1135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/*
2135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Copyright (C) 2009 The Android Open Source Project
3135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
4135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * you may not use this file except in compliance with the License.
6135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * You may obtain a copy of the License at
7135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
8135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
10135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Unless required by applicable law or agreed to in writing, software
11135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * See the License for the specific language governing permissions and
14135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * limitations under the License.
15135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent */
16135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
17135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#define LOG_TAG "Equalizer"
18135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent//
202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define LOG_NDEBUG 0
21135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <cutils/log.h>
22135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <assert.h>
23135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <stdlib.h>
2417217ab46e12fbdaad9e1d7460c48937f76fa0e2Eric Laurent#include <string.h>
25135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <new>
26135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "AudioEqualizer.h"
27135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "AudioBiquadFilter.h"
28135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "AudioFormatAdapter.h"
296d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent#include <audio_effects/effect_equalizer.h>
306d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent
31135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
32e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent// effect_handle_t interface implementation for equalizer effect
33135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentextern "C" const struct effect_interface_s gEqualizerInterface;
34135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
35e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurentenum equalizer_state_e {
36e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent    EQUALIZER_STATE_UNINITIALIZED,
37e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent    EQUALIZER_STATE_INITIALIZED,
38e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent    EQUALIZER_STATE_ACTIVE,
39e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent};
40e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent
41135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentnamespace android {
42135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentnamespace {
43135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
44135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Google Graphic Equalizer UUID: e25aa840-543b-11df-98a5-0002a5d5c51b
45135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst effect_descriptor_t gEqualizerDescriptor = {
46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
47135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        {0xe25aa840, 0x543b, 0x11df, 0x98a5, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
48e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        EFFECT_CONTROL_API_VERSION,
49135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
50ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        0, // TODO
51ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        1,
52135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        "Graphic Equalizer",
53e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        "The Android Open Source Project",
54135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
55135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
56135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////// BEGIN EQ PRESETS ///////////////////////////////////////////
57135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst int kNumBands = 5;
58135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst uint32_t gFreqs[kNumBands] =      { 50000, 125000, 900000, 3200000, 6300000 };
59135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst uint32_t gBandwidths[kNumBands] = { 0,     3600,   3600,   2400,    0       };
60135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
61135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst AudioEqualizer::BandConfig gBandsClassic[kNumBands] = {
62135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 300,  gFreqs[0], gBandwidths[0] },
63135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 400,  gFreqs[1], gBandwidths[1] },
64135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 0,    gFreqs[2], gBandwidths[2] },
65135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 200,  gFreqs[3], gBandwidths[3] },
66135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { -300, gFreqs[4], gBandwidths[4] }
67135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
68135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
69135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst AudioEqualizer::BandConfig gBandsJazz[kNumBands] = {
70135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { -600, gFreqs[0], gBandwidths[0] },
71135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 200,  gFreqs[1], gBandwidths[1] },
72135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 400,  gFreqs[2], gBandwidths[2] },
73135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { -400, gFreqs[3], gBandwidths[3] },
74135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { -600, gFreqs[4], gBandwidths[4] }
75135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
76135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
77135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst AudioEqualizer::BandConfig gBandsPop[kNumBands] = {
78135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 400,  gFreqs[0], gBandwidths[0] },
79135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { -400, gFreqs[1], gBandwidths[1] },
80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 300,  gFreqs[2], gBandwidths[2] },
81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { -400, gFreqs[3], gBandwidths[3] },
82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 600,  gFreqs[4], gBandwidths[4] }
83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
84135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
85135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst AudioEqualizer::BandConfig gBandsRock[kNumBands] = {
86135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 700,  gFreqs[0], gBandwidths[0] },
87135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 400,  gFreqs[1], gBandwidths[1] },
88135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { -400, gFreqs[2], gBandwidths[2] },
89135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 400,  gFreqs[3], gBandwidths[3] },
90135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { 200,  gFreqs[4], gBandwidths[4] }
91135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
92135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst AudioEqualizer::PresetConfig gEqualizerPresets[] = {
94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { "Classic", gBandsClassic },
95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { "Jazz",    gBandsJazz    },
96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { "Pop",     gBandsPop     },
97135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    { "Rock",    gBandsRock    }
98135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
99135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
100135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////// END EQ PRESETS /////////////////////////////////////////////
101135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
102135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic const size_t kBufferSize = 32;
103135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
104135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurenttypedef AudioFormatAdapter<AudioEqualizer, kBufferSize> FormatAdapter;
105135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
106135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstruct EqualizerContext {
107135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    const struct effect_interface_s *itfe;
108135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_config_t config;
109135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    FormatAdapter adapter;
110135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    AudioEqualizer * pEqualizer;
111e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent    uint32_t state;
112135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
113135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
114135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//--- local function prototypes
115135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
116135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint Equalizer_init(EqualizerContext *pContext);
1173d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurentint Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig);
118135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue);
119135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue);
120135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
121135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
122135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
123135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//--- Effect Library Interface Implementation
124135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
125135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
126be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentextern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects) {
127135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    *pNumEffects = 1;
128135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
129135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} /* end EffectQueryNumberEffects */
130135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
131e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentextern "C" int EffectQueryEffect(uint32_t index,
132e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                                 effect_descriptor_t *pDescriptor) {
133135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pDescriptor == NULL) {
134135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
135135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
136ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (index > 0) {
137ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        return -EINVAL;
138135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
139a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten    *pDescriptor = gEqualizerDescriptor;
140135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
141135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} /* end EffectQueryNext */
142135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
1435e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenextern "C" int EffectCreate(const effect_uuid_t *uuid,
144e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                            int32_t sessionId,
145e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                            int32_t ioId,
146e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                            effect_handle_t *pHandle) {
147135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret;
148135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int i;
149135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
1503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectLibCreateEffect start");
151135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
152e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (pHandle == NULL || uuid == NULL) {
153135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
154135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
155135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
156135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) != 0) {
157135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
158135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
159135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
160135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    EqualizerContext *pContext = new EqualizerContext;
161135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
162135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->itfe = &gEqualizerInterface;
163135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->pEqualizer = NULL;
164e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent    pContext->state = EQUALIZER_STATE_UNINITIALIZED;
165135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
166135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = Equalizer_init(pContext);
167135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
1685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectLibCreateEffect() init failed");
169135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        delete pContext;
170135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
171135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
172135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
173e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    *pHandle = (effect_handle_t)pContext;
174e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent    pContext->state = EQUALIZER_STATE_INITIALIZED;
175135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
1763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectLibCreateEffect %p, size %d",
177e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent         pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext));
178135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
179135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
180135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
181135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} /* end EffectCreate */
182135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
183e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentextern "C" int EffectRelease(effect_handle_t handle) {
184e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    EqualizerContext * pContext = (EqualizerContext *)handle;
185135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
1863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectLibReleaseEffect %p", handle);
187135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pContext == NULL) {
188135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
189135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
190135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
191e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent    pContext->state = EQUALIZER_STATE_UNINITIALIZED;
192135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->pEqualizer->free();
193135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    delete pContext;
194135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
195135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
196135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} /* end EffectRelease */
197135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
1985e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenextern "C" int EffectGetDescriptor(const effect_uuid_t *uuid,
199e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                                   effect_descriptor_t *pDescriptor) {
200e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
201e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (pDescriptor == NULL || uuid == NULL){
2023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("EffectGetDescriptor() called with NULL pointer");
203e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
204e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
205e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
206e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
207a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten        *pDescriptor = gEqualizerDescriptor;
208e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return 0;
209e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
210e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
211e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return  -EINVAL;
212e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} /* end EffectGetDescriptor */
213e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
214135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
215135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
216135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//--- local functions
217135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
218135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
219135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#define CHECK_ARG(cond) {                     \
220135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (!(cond)) {                            \
2213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Invalid argument: "#cond);      \
222135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;                       \
223135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }                                         \
224135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
225135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
226135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//----------------------------------------------------------------------------
2273d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent// Equalizer_setConfig()
228135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//----------------------------------------------------------------------------
229135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Purpose: Set input and output audio configuration.
230135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
231135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Inputs:
232135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//  pContext:   effect engine context
233135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//  pConfig:    pointer to effect_config_t structure holding input and output
234135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      configuration parameters
235135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
236135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Outputs:
237135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
238135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//----------------------------------------------------------------------------
239135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2403d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurentint Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig)
241135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
2423d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent    ALOGV("Equalizer_setConfig start");
243135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
244135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    CHECK_ARG(pContext != NULL);
245135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    CHECK_ARG(pConfig != NULL);
246135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
247135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
248135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
249135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
250e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    CHECK_ARG((pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) ||
251e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent              (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO));
252135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
253135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent              || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
254e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_8_24_BIT
255e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent              || pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT);
256135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
257135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int channelCount;
258e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) {
259135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        channelCount = 1;
260135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
261135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        channelCount = 2;
262135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
263135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    CHECK_ARG(channelCount <= AudioBiquadFilter::MAX_CHANNELS);
264135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
265a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten    pContext->config = *pConfig;
266ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
267135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->pEqualizer->configure(channelCount,
268135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                          pConfig->inputCfg.samplingRate);
269135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
270135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->adapter.configure(*pContext->pEqualizer, channelCount,
271135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                        pConfig->inputCfg.format,
272135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                        pConfig->outputCfg.accessMode);
273135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
274135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
2753d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent}   // end Equalizer_setConfig
2763d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent
2773d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent//----------------------------------------------------------------------------
2783d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent// Equalizer_getConfig()
2793d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent//----------------------------------------------------------------------------
2803d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent// Purpose: Get input and output audio configuration.
2813d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent//
2823d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent// Inputs:
2833d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent//  pContext:   effect engine context
2843d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent//  pConfig:    pointer to effect_config_t structure holding input and output
2853d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent//      configuration parameters
2863d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent//
2873d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent// Outputs:
2883d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent//
2893d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent//----------------------------------------------------------------------------
2903d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent
2913d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurentvoid Equalizer_getConfig(EqualizerContext *pContext, effect_config_t *pConfig)
2923d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent{
293a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten    *pConfig = pContext->config;
2943d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent}   // end Equalizer_getConfig
295135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
296135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
297135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//----------------------------------------------------------------------------
298135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Equalizer_init()
299135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//----------------------------------------------------------------------------
300135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Purpose: Initialize engine with default configuration and creates
301135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//     AudioEqualizer instance.
302135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
303135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Inputs:
304135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//  pContext:   effect engine context
305135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
306135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Outputs:
307135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
308135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//----------------------------------------------------------------------------
309135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
310135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint Equalizer_init(EqualizerContext *pContext)
311135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
312135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int status;
313135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Equalizer_init start");
315135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
316135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    CHECK_ARG(pContext != NULL);
317135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
318135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pContext->pEqualizer != NULL) {
319135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pContext->pEqualizer->free();
320135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
321135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
322135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
323e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
324e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
325135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->config.inputCfg.samplingRate = 44100;
326135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
327135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
328135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->config.inputCfg.bufferProvider.cookie = NULL;
329135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
330135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
331e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
332e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
333135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->config.outputCfg.samplingRate = 44100;
334135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
335135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
336135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->config.outputCfg.bufferProvider.cookie = NULL;
337135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL;
338135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
339135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->pEqualizer = AudioEqualizer::CreateInstance(
340135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        NULL,
341135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        kNumBands,
342135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        AudioBiquadFilter::MAX_CHANNELS,
343135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        44100,
344135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        gEqualizerPresets,
345135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        ARRAY_SIZE(gEqualizerPresets));
346135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
347135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    for (int i = 0; i < kNumBands; ++i) {
348135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pContext->pEqualizer->setFrequency(i, gFreqs[i]);
349135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pContext->pEqualizer->setBandwidth(i, gBandwidths[i]);
350135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
351135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
352135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->pEqualizer->enable(true);
353135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3543d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent    Equalizer_setConfig(pContext, &pContext->config);
355135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
356135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
357135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}   // end Equalizer_init
358135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
359135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
360135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//----------------------------------------------------------------------------
361135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Equalizer_getParameter()
362135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//----------------------------------------------------------------------------
363135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Purpose:
364135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Get a Equalizer parameter
365135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
366135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Inputs:
367135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//  pEqualizer       - handle to instance data
368135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//  pParam           - pointer to parameter
369135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//  pValue           - pointer to variable to hold retrieved value
370135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//  pValueSize       - pointer to value size: maximum size as input
371135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
372135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Outputs:
373135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//  *pValue updated with parameter value
374135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//  *pValueSize updated with actual value size
375135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
376135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
377135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Side Effects:
378135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
379135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//----------------------------------------------------------------------------
380135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
381135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue)
382135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
383135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int status = 0;
384135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t param = *pParam++;
385135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t param2;
386135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    char *name;
387135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
388135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    switch (param) {
389135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_NUM_BANDS:
390135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_CUR_PRESET:
391135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_GET_NUM_OF_PRESETS:
3923be9523784cc4038f601e510faee595117cdacb3Eric Laurent    case EQ_PARAM_BAND_LEVEL:
3933be9523784cc4038f601e510faee595117cdacb3Eric Laurent    case EQ_PARAM_GET_BAND:
394135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (*pValueSize < sizeof(int16_t)) {
395135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            return -EINVAL;
396135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
397135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        *pValueSize = sizeof(int16_t);
398135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
399135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
400135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_LEVEL_RANGE:
4013be9523784cc4038f601e510faee595117cdacb3Eric Laurent        if (*pValueSize < 2 * sizeof(int16_t)) {
4023be9523784cc4038f601e510faee595117cdacb3Eric Laurent            return -EINVAL;
4033be9523784cc4038f601e510faee595117cdacb3Eric Laurent        }
4043be9523784cc4038f601e510faee595117cdacb3Eric Laurent        *pValueSize = 2 * sizeof(int16_t);
4053be9523784cc4038f601e510faee595117cdacb3Eric Laurent        break;
4063be9523784cc4038f601e510faee595117cdacb3Eric Laurent
407135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_BAND_FREQ_RANGE:
408135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (*pValueSize < 2 * sizeof(int32_t)) {
409135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            return -EINVAL;
410135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
411135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        *pValueSize = 2 * sizeof(int32_t);
412135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
4133be9523784cc4038f601e510faee595117cdacb3Eric Laurent
414135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_CENTER_FREQ:
415135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (*pValueSize < sizeof(int32_t)) {
416135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            return -EINVAL;
417135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
418135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        *pValueSize = sizeof(int32_t);
419135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
420135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
421135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_GET_PRESET_NAME:
422135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
423135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
4243be9523784cc4038f601e510faee595117cdacb3Eric Laurent    case EQ_PARAM_PROPERTIES:
4253be9523784cc4038f601e510faee595117cdacb3Eric Laurent        if (*pValueSize < (2 + kNumBands) * sizeof(uint16_t)) {
4263be9523784cc4038f601e510faee595117cdacb3Eric Laurent            return -EINVAL;
4273be9523784cc4038f601e510faee595117cdacb3Eric Laurent        }
4283be9523784cc4038f601e510faee595117cdacb3Eric Laurent        *pValueSize = (2 + kNumBands) * sizeof(uint16_t);
4293be9523784cc4038f601e510faee595117cdacb3Eric Laurent        break;
4303be9523784cc4038f601e510faee595117cdacb3Eric Laurent
431135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    default:
432135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
433135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
434135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
435135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    switch (param) {
436135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_NUM_BANDS:
4373be9523784cc4038f601e510faee595117cdacb3Eric Laurent        *(uint16_t *)pValue = (uint16_t)kNumBands;
4383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue);
439135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
440135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
441135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_LEVEL_RANGE:
4423be9523784cc4038f601e510faee595117cdacb3Eric Laurent        *(int16_t *)pValue = -9600;
4433be9523784cc4038f601e510faee595117cdacb3Eric Laurent        *((int16_t *)pValue + 1) = 4800;
4443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d",
445e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent             *(int32_t *)pValue, *((int32_t *)pValue + 1));
446135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
447135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
448135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_BAND_LEVEL:
449135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        param2 = *pParam;
450135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (param2 >= kNumBands) {
451135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            status = -EINVAL;
452135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            break;
453135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
4543be9523784cc4038f601e510faee595117cdacb3Eric Laurent        *(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2);
4553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d",
456e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent             param2, *(int32_t *)pValue);
457135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
458135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
459135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_CENTER_FREQ:
460135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        param2 = *pParam;
461135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (param2 >= kNumBands) {
462135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            status = -EINVAL;
463135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            break;
464135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
465135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        *(int32_t *)pValue = pEqualizer->getFrequency(param2);
4663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d",
467e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent             param2, *(int32_t *)pValue);
468135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
469135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
470135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_BAND_FREQ_RANGE:
471135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        param2 = *pParam;
472135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (param2 >= kNumBands) {
473135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            status = -EINVAL;
474135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            break;
475135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
476135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1));
4773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d",
478e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent             param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
479135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
480135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
481135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_GET_BAND:
482135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        param2 = *pParam;
4833be9523784cc4038f601e510faee595117cdacb3Eric Laurent        *(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2);
4843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d",
485e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent             param2, *(int32_t *)pValue);
486135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
487135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
488135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_CUR_PRESET:
4893be9523784cc4038f601e510faee595117cdacb3Eric Laurent        *(uint16_t *)pValue = (uint16_t)pEqualizer->getPreset();
4903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue);
491135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
492135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
493135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_GET_NUM_OF_PRESETS:
4943be9523784cc4038f601e510faee595117cdacb3Eric Laurent        *(uint16_t *)pValue = (uint16_t)pEqualizer->getNumPresets();
4953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue);
496135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
497135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
498135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_GET_PRESET_NAME:
499135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        param2 = *pParam;
500135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (param2 >= pEqualizer->getNumPresets()) {
501135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            status = -EINVAL;
502135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            break;
503135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
504135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        name = (char *)pValue;
505135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1);
506135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        name[*pValueSize - 1] = 0;
507135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        *pValueSize = strlen(name) + 1;
5083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d",
509e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent             param2, gEqualizerPresets[param2].name, *pValueSize);
510135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
511135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
5123be9523784cc4038f601e510faee595117cdacb3Eric Laurent    case EQ_PARAM_PROPERTIES: {
5133be9523784cc4038f601e510faee595117cdacb3Eric Laurent        int16_t *p = (int16_t *)pValue;
5143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_getParameter() EQ_PARAM_PROPERTIES");
5153be9523784cc4038f601e510faee595117cdacb3Eric Laurent        p[0] = (int16_t)pEqualizer->getPreset();
5163be9523784cc4038f601e510faee595117cdacb3Eric Laurent        p[1] = (int16_t)kNumBands;
5173be9523784cc4038f601e510faee595117cdacb3Eric Laurent        for (int i = 0; i < kNumBands; i++) {
5183be9523784cc4038f601e510faee595117cdacb3Eric Laurent            p[2 + i] = (int16_t)pEqualizer->getGain(i);
5193be9523784cc4038f601e510faee595117cdacb3Eric Laurent        }
5203be9523784cc4038f601e510faee595117cdacb3Eric Laurent    } break;
5213be9523784cc4038f601e510faee595117cdacb3Eric Laurent
522135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    default:
5233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_getParameter() invalid param %d", param);
524135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        status = -EINVAL;
525135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
526135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
527135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
528135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return status;
529135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} // end Equalizer_getParameter
530135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
531135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
532135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//----------------------------------------------------------------------------
533135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Equalizer_setParameter()
534135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//----------------------------------------------------------------------------
535135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Purpose:
536135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Set a Equalizer parameter
537135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
538135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Inputs:
539135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//  pEqualizer       - handle to instance data
540135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//  pParam           - pointer to parameter
541135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//  pValue           - pointer to value
542135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
543135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Outputs:
544135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
545135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
546135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Side Effects:
547135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
548135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//----------------------------------------------------------------------------
549135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
550135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint Equalizer_setParameter (AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue)
551135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
552135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int status = 0;
553135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t preset;
554135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t band;
555135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t level;
556135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t param = *pParam++;
557135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
558135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
559135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    switch (param) {
560135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_CUR_PRESET:
5613be9523784cc4038f601e510faee595117cdacb3Eric Laurent        preset = (int32_t)(*(uint16_t *)pValue);
562135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
5633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("setParameter() EQ_PARAM_CUR_PRESET %d", preset);
5643be9523784cc4038f601e510faee595117cdacb3Eric Laurent        if (preset < 0 || preset >= pEqualizer->getNumPresets()) {
565135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            status = -EINVAL;
566135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            break;
567135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
568135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pEqualizer->setPreset(preset);
569135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pEqualizer->commit(true);
570135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
571135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EQ_PARAM_BAND_LEVEL:
572135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        band =  *pParam;
5733be9523784cc4038f601e510faee595117cdacb3Eric Laurent        level = (int32_t)(*(int16_t *)pValue);
5743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level);
575135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (band >= kNumBands) {
576135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            status = -EINVAL;
577135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            break;
578135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
579135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pEqualizer->setGain(band, level);
580135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pEqualizer->commit(true);
581135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent       break;
5823be9523784cc4038f601e510faee595117cdacb3Eric Laurent    case EQ_PARAM_PROPERTIES: {
5833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("setParameter() EQ_PARAM_PROPERTIES");
5843be9523784cc4038f601e510faee595117cdacb3Eric Laurent        int16_t *p = (int16_t *)pValue;
5853be9523784cc4038f601e510faee595117cdacb3Eric Laurent        if ((int)p[0] >= pEqualizer->getNumPresets()) {
5863be9523784cc4038f601e510faee595117cdacb3Eric Laurent            status = -EINVAL;
5873be9523784cc4038f601e510faee595117cdacb3Eric Laurent            break;
5883be9523784cc4038f601e510faee595117cdacb3Eric Laurent        }
5893be9523784cc4038f601e510faee595117cdacb3Eric Laurent        if (p[0] >= 0) {
5903be9523784cc4038f601e510faee595117cdacb3Eric Laurent            pEqualizer->setPreset((int)p[0]);
5913be9523784cc4038f601e510faee595117cdacb3Eric Laurent        } else {
5923be9523784cc4038f601e510faee595117cdacb3Eric Laurent            if ((int)p[1] != kNumBands) {
5933be9523784cc4038f601e510faee595117cdacb3Eric Laurent                status = -EINVAL;
5943be9523784cc4038f601e510faee595117cdacb3Eric Laurent                break;
5953be9523784cc4038f601e510faee595117cdacb3Eric Laurent            }
5963be9523784cc4038f601e510faee595117cdacb3Eric Laurent            for (int i = 0; i < kNumBands; i++) {
5973be9523784cc4038f601e510faee595117cdacb3Eric Laurent                pEqualizer->setGain(i, (int32_t)p[2 + i]);
5983be9523784cc4038f601e510faee595117cdacb3Eric Laurent            }
5993be9523784cc4038f601e510faee595117cdacb3Eric Laurent        }
6003be9523784cc4038f601e510faee595117cdacb3Eric Laurent        pEqualizer->commit(true);
6013be9523784cc4038f601e510faee595117cdacb3Eric Laurent    } break;
602135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    default:
6033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("setParameter() invalid param %d", param);
6043be9523784cc4038f601e510faee595117cdacb3Eric Laurent        status = -EINVAL;
605135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
606135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
607135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
608135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return status;
609135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} // end Equalizer_setParameter
610135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
611135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} // namespace
612135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} // namespace
613135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
614135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
615135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
616135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//--- Effect Control Interface Implementation
617135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
618135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
619e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentextern "C" int Equalizer_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
620135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
621135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    android::EqualizerContext * pContext = (android::EqualizerContext *) self;
622135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
623135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pContext == NULL) {
624135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
625135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
626135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (inBuffer == NULL || inBuffer->raw == NULL ||
627135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        outBuffer == NULL || outBuffer->raw == NULL ||
628135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        inBuffer->frameCount != outBuffer->frameCount) {
629135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
630135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
631135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
632e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent    if (pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
633e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent        return -EINVAL;
634e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent    }
635e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent    if (pContext->state == EQUALIZER_STATE_INITIALIZED) {
636e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent        return -ENODATA;
637e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent    }
638e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent
639135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pContext->adapter.process(inBuffer->raw, outBuffer->raw, outBuffer->frameCount);
640ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
641135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
642135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}   // end Equalizer_process
643135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
644e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentextern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
64525f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent        void *pCmdData, uint32_t *replySize, void *pReplyData) {
646135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
647135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    android::EqualizerContext * pContext = (android::EqualizerContext *) self;
648135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int retsize;
649135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
650e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent    if (pContext == NULL || pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
651135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
652135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
653135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
654135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    android::AudioEqualizer * pEqualizer = pContext->pEqualizer;
655135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
6563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Equalizer_command command %d cmdSize %d",cmdCode, cmdSize);
657135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
658135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    switch (cmdCode) {
659135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EFFECT_CMD_INIT:
660135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (pReplyData == NULL || *replySize != sizeof(int)) {
661135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            return -EINVAL;
662135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
663135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        *(int *) pReplyData = Equalizer_init(pContext);
664135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
6653d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent    case EFFECT_CMD_SET_CONFIG:
666135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (pCmdData == NULL || cmdSize != sizeof(effect_config_t)
667135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                || pReplyData == NULL || *replySize != sizeof(int)) {
668135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            return -EINVAL;
669135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
6703d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent        *(int *) pReplyData = Equalizer_setConfig(pContext,
671135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                (effect_config_t *) pCmdData);
672135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
6733d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent    case EFFECT_CMD_GET_CONFIG:
6743d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent        if (pReplyData == NULL || *replySize != sizeof(effect_config_t)) {
6753d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent            return -EINVAL;
6763d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent        }
6773d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent        Equalizer_getConfig(pContext, (effect_config_t *) pCmdData);
6783d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent        break;
679135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EFFECT_CMD_RESET:
6803d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent        Equalizer_setConfig(pContext, &pContext->config);
681135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        break;
682135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EFFECT_CMD_GET_PARAM: {
683135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
684135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            pReplyData == NULL || *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))) {
685135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            return -EINVAL;
686135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
687135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        effect_param_t *p = (effect_param_t *)pCmdData;
688135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
689135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        p = (effect_param_t *)pReplyData;
690135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
691135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        p->status = android::Equalizer_getParameter(pEqualizer, (int32_t *)p->data, &p->vsize,
692135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                p->data + voffset);
693135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        *replySize = sizeof(effect_param_t) + voffset + p->vsize;
6943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x",
695135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize,
696135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset),
697135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset + sizeof(int32_t)));
698135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
699135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        } break;
700135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    case EFFECT_CMD_SET_PARAM: {
7013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p",
702e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent             cmdSize, pCmdData, *replySize, pReplyData);
703135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
704135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            pReplyData == NULL || *replySize != sizeof(int32_t)) {
705135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            return -EINVAL;
706135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
707135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        effect_param_t *p = (effect_param_t *) pCmdData;
708135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        *(int *)pReplyData = android::Equalizer_setParameter(pEqualizer, (int32_t *)p->data,
709135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                p->data + p->psize);
710135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        } break;
711ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    case EFFECT_CMD_ENABLE:
712e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent        if (pReplyData == NULL || *replySize != sizeof(int)) {
713e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent            return -EINVAL;
714e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent        }
715e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent        if (pContext->state != EQUALIZER_STATE_INITIALIZED) {
716e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent            return -ENOSYS;
717e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent        }
718e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent        pContext->state = EQUALIZER_STATE_ACTIVE;
7193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("EFFECT_CMD_ENABLE() OK");
720e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent        *(int *)pReplyData = 0;
721e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent        break;
722ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    case EFFECT_CMD_DISABLE:
723ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        if (pReplyData == NULL || *replySize != sizeof(int)) {
724ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            return -EINVAL;
725ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        }
726e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent        if (pContext->state != EQUALIZER_STATE_ACTIVE) {
727e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent            return -ENOSYS;
728e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent        }
729e44b1efb293f878d4af8e824a6b3d070167bf2d6Eric Laurent        pContext->state = EQUALIZER_STATE_INITIALIZED;
7303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("EFFECT_CMD_DISABLE() OK");
731ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        *(int *)pReplyData = 0;
732ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        break;
733ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    case EFFECT_CMD_SET_DEVICE:
734ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    case EFFECT_CMD_SET_VOLUME:
735ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    case EFFECT_CMD_SET_AUDIO_MODE:
736ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        break;
737135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    default:
7385ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Equalizer_command invalid command %d",cmdCode);
739135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
740135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
741135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
742135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
743135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
744135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
745e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentextern "C" int Equalizer_getDescriptor(effect_handle_t   self,
746e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                                    effect_descriptor_t *pDescriptor)
747e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
748e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    android::EqualizerContext * pContext = (android::EqualizerContext *) self;
749e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
750e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (pContext == NULL || pDescriptor == NULL) {
7513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Equalizer_getDescriptor() invalid param");
752e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
753e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
754e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
755a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten    *pDescriptor = android::gEqualizerDescriptor;
756e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
757e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
758e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
759e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
760e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent// effect_handle_t interface implementation for equalizer effect
761135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst struct effect_interface_s gEqualizerInterface = {
762135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        Equalizer_process,
763e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        Equalizer_command,
764ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Equalizer_getDescriptor,
765ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        NULL
766135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
767135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
768135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
769e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentaudio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
770e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    tag : AUDIO_EFFECT_LIBRARY_TAG,
771e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    version : EFFECT_LIBRARY_API_VERSION,
772e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    name : "Test Equalizer Library",
773e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    implementor : "The Android Open Source Project",
774e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    query_num_effects : android::EffectQueryNumberEffects,
775e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    query_effect : android::EffectQueryEffect,
776e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    create_effect : android::EffectCreate,
777e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    release_effect : android::EffectRelease,
778e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    get_descriptor : android::EffectGetDescriptor,
779e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent};
780