1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2009 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "Equalizer"
18*ec779b8eSAndroid Build Coastguard Worker #define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
19*ec779b8eSAndroid Build Coastguard Worker //
20*ec779b8eSAndroid Build Coastguard Worker #define LOG_NDEBUG 0
21*ec779b8eSAndroid Build Coastguard Worker
22*ec779b8eSAndroid Build Coastguard Worker #include <assert.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <stdlib.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <string.h>
25*ec779b8eSAndroid Build Coastguard Worker
26*ec779b8eSAndroid Build Coastguard Worker #include <new>
27*ec779b8eSAndroid Build Coastguard Worker
28*ec779b8eSAndroid Build Coastguard Worker #include <log/log.h>
29*ec779b8eSAndroid Build Coastguard Worker
30*ec779b8eSAndroid Build Coastguard Worker #include "AudioEqualizer.h"
31*ec779b8eSAndroid Build Coastguard Worker #include "AudioBiquadFilter.h"
32*ec779b8eSAndroid Build Coastguard Worker #include "AudioFormatAdapter.h"
33*ec779b8eSAndroid Build Coastguard Worker #include <audio_effects/effect_equalizer.h>
34*ec779b8eSAndroid Build Coastguard Worker
35*ec779b8eSAndroid Build Coastguard Worker // effect_handle_t interface implementation for equalizer effect
36*ec779b8eSAndroid Build Coastguard Worker extern "C" const struct effect_interface_s gEqualizerInterface;
37*ec779b8eSAndroid Build Coastguard Worker
38*ec779b8eSAndroid Build Coastguard Worker enum equalizer_state_e {
39*ec779b8eSAndroid Build Coastguard Worker EQUALIZER_STATE_UNINITIALIZED,
40*ec779b8eSAndroid Build Coastguard Worker EQUALIZER_STATE_INITIALIZED,
41*ec779b8eSAndroid Build Coastguard Worker EQUALIZER_STATE_ACTIVE,
42*ec779b8eSAndroid Build Coastguard Worker };
43*ec779b8eSAndroid Build Coastguard Worker
44*ec779b8eSAndroid Build Coastguard Worker namespace android {
45*ec779b8eSAndroid Build Coastguard Worker namespace {
46*ec779b8eSAndroid Build Coastguard Worker
47*ec779b8eSAndroid Build Coastguard Worker // Google Graphic Equalizer UUID: e25aa840-543b-11df-98a5-0002a5d5c51b
48*ec779b8eSAndroid Build Coastguard Worker const effect_descriptor_t gEqualizerDescriptor = {
49*ec779b8eSAndroid Build Coastguard Worker {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
50*ec779b8eSAndroid Build Coastguard Worker {0xe25aa840, 0x543b, 0x11df, 0x98a5, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
51*ec779b8eSAndroid Build Coastguard Worker EFFECT_CONTROL_API_VERSION,
52*ec779b8eSAndroid Build Coastguard Worker (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
53*ec779b8eSAndroid Build Coastguard Worker 0, // TODO
54*ec779b8eSAndroid Build Coastguard Worker 1,
55*ec779b8eSAndroid Build Coastguard Worker "Graphic Equalizer",
56*ec779b8eSAndroid Build Coastguard Worker "The Android Open Source Project",
57*ec779b8eSAndroid Build Coastguard Worker };
58*ec779b8eSAndroid Build Coastguard Worker
59*ec779b8eSAndroid Build Coastguard Worker /////////////////// BEGIN EQ PRESETS ///////////////////////////////////////////
60*ec779b8eSAndroid Build Coastguard Worker const int kNumBands = 5;
61*ec779b8eSAndroid Build Coastguard Worker const uint32_t gFreqs[kNumBands] = { 50000, 125000, 900000, 3200000, 6300000 };
62*ec779b8eSAndroid Build Coastguard Worker const uint32_t gBandwidths[kNumBands] = { 0, 3600, 3600, 2400, 0 };
63*ec779b8eSAndroid Build Coastguard Worker
64*ec779b8eSAndroid Build Coastguard Worker const AudioEqualizer::BandConfig gBandsClassic[kNumBands] = {
65*ec779b8eSAndroid Build Coastguard Worker { 300, gFreqs[0], gBandwidths[0] },
66*ec779b8eSAndroid Build Coastguard Worker { 400, gFreqs[1], gBandwidths[1] },
67*ec779b8eSAndroid Build Coastguard Worker { 0, gFreqs[2], gBandwidths[2] },
68*ec779b8eSAndroid Build Coastguard Worker { 200, gFreqs[3], gBandwidths[3] },
69*ec779b8eSAndroid Build Coastguard Worker { -300, gFreqs[4], gBandwidths[4] }
70*ec779b8eSAndroid Build Coastguard Worker };
71*ec779b8eSAndroid Build Coastguard Worker
72*ec779b8eSAndroid Build Coastguard Worker const AudioEqualizer::BandConfig gBandsJazz[kNumBands] = {
73*ec779b8eSAndroid Build Coastguard Worker { -600, gFreqs[0], gBandwidths[0] },
74*ec779b8eSAndroid Build Coastguard Worker { 200, gFreqs[1], gBandwidths[1] },
75*ec779b8eSAndroid Build Coastguard Worker { 400, gFreqs[2], gBandwidths[2] },
76*ec779b8eSAndroid Build Coastguard Worker { -400, gFreqs[3], gBandwidths[3] },
77*ec779b8eSAndroid Build Coastguard Worker { -600, gFreqs[4], gBandwidths[4] }
78*ec779b8eSAndroid Build Coastguard Worker };
79*ec779b8eSAndroid Build Coastguard Worker
80*ec779b8eSAndroid Build Coastguard Worker const AudioEqualizer::BandConfig gBandsPop[kNumBands] = {
81*ec779b8eSAndroid Build Coastguard Worker { 400, gFreqs[0], gBandwidths[0] },
82*ec779b8eSAndroid Build Coastguard Worker { -400, gFreqs[1], gBandwidths[1] },
83*ec779b8eSAndroid Build Coastguard Worker { 300, gFreqs[2], gBandwidths[2] },
84*ec779b8eSAndroid Build Coastguard Worker { -400, gFreqs[3], gBandwidths[3] },
85*ec779b8eSAndroid Build Coastguard Worker { 600, gFreqs[4], gBandwidths[4] }
86*ec779b8eSAndroid Build Coastguard Worker };
87*ec779b8eSAndroid Build Coastguard Worker
88*ec779b8eSAndroid Build Coastguard Worker const AudioEqualizer::BandConfig gBandsRock[kNumBands] = {
89*ec779b8eSAndroid Build Coastguard Worker { 700, gFreqs[0], gBandwidths[0] },
90*ec779b8eSAndroid Build Coastguard Worker { 400, gFreqs[1], gBandwidths[1] },
91*ec779b8eSAndroid Build Coastguard Worker { -400, gFreqs[2], gBandwidths[2] },
92*ec779b8eSAndroid Build Coastguard Worker { 400, gFreqs[3], gBandwidths[3] },
93*ec779b8eSAndroid Build Coastguard Worker { 200, gFreqs[4], gBandwidths[4] }
94*ec779b8eSAndroid Build Coastguard Worker };
95*ec779b8eSAndroid Build Coastguard Worker
96*ec779b8eSAndroid Build Coastguard Worker const AudioEqualizer::PresetConfig gEqualizerPresets[] = {
97*ec779b8eSAndroid Build Coastguard Worker { "Classic", gBandsClassic },
98*ec779b8eSAndroid Build Coastguard Worker { "Jazz", gBandsJazz },
99*ec779b8eSAndroid Build Coastguard Worker { "Pop", gBandsPop },
100*ec779b8eSAndroid Build Coastguard Worker { "Rock", gBandsRock }
101*ec779b8eSAndroid Build Coastguard Worker };
102*ec779b8eSAndroid Build Coastguard Worker
103*ec779b8eSAndroid Build Coastguard Worker /////////////////// END EQ PRESETS /////////////////////////////////////////////
104*ec779b8eSAndroid Build Coastguard Worker
105*ec779b8eSAndroid Build Coastguard Worker static const size_t kBufferSize = 32;
106*ec779b8eSAndroid Build Coastguard Worker
107*ec779b8eSAndroid Build Coastguard Worker typedef AudioFormatAdapter<AudioEqualizer, kBufferSize> FormatAdapter;
108*ec779b8eSAndroid Build Coastguard Worker
109*ec779b8eSAndroid Build Coastguard Worker struct EqualizerContext {
110*ec779b8eSAndroid Build Coastguard Worker const struct effect_interface_s *itfe;
111*ec779b8eSAndroid Build Coastguard Worker effect_config_t config;
112*ec779b8eSAndroid Build Coastguard Worker FormatAdapter adapter;
113*ec779b8eSAndroid Build Coastguard Worker AudioEqualizer * pEqualizer;
114*ec779b8eSAndroid Build Coastguard Worker uint32_t state;
115*ec779b8eSAndroid Build Coastguard Worker };
116*ec779b8eSAndroid Build Coastguard Worker
117*ec779b8eSAndroid Build Coastguard Worker //--- local function prototypes
118*ec779b8eSAndroid Build Coastguard Worker
119*ec779b8eSAndroid Build Coastguard Worker int Equalizer_init(EqualizerContext *pContext);
120*ec779b8eSAndroid Build Coastguard Worker int Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig);
121*ec779b8eSAndroid Build Coastguard Worker int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, uint32_t *pValueSize, void *pValue);
122*ec779b8eSAndroid Build Coastguard Worker int Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue);
123*ec779b8eSAndroid Build Coastguard Worker
124*ec779b8eSAndroid Build Coastguard Worker
125*ec779b8eSAndroid Build Coastguard Worker //
126*ec779b8eSAndroid Build Coastguard Worker //--- Effect Library Interface Implementation
127*ec779b8eSAndroid Build Coastguard Worker //
128*ec779b8eSAndroid Build Coastguard Worker
EffectCreate(const effect_uuid_t * uuid,int32_t sessionId,int32_t ioId,effect_handle_t * pHandle)129*ec779b8eSAndroid Build Coastguard Worker extern "C" int EffectCreate(const effect_uuid_t *uuid,
130*ec779b8eSAndroid Build Coastguard Worker int32_t sessionId,
131*ec779b8eSAndroid Build Coastguard Worker int32_t ioId,
132*ec779b8eSAndroid Build Coastguard Worker effect_handle_t *pHandle) {
133*ec779b8eSAndroid Build Coastguard Worker int ret;
134*ec779b8eSAndroid Build Coastguard Worker (void)sessionId;
135*ec779b8eSAndroid Build Coastguard Worker (void)ioId;
136*ec779b8eSAndroid Build Coastguard Worker
137*ec779b8eSAndroid Build Coastguard Worker ALOGV("EffectLibCreateEffect start");
138*ec779b8eSAndroid Build Coastguard Worker
139*ec779b8eSAndroid Build Coastguard Worker if (pHandle == NULL || uuid == NULL) {
140*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
141*ec779b8eSAndroid Build Coastguard Worker }
142*ec779b8eSAndroid Build Coastguard Worker
143*ec779b8eSAndroid Build Coastguard Worker if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) != 0) {
144*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
145*ec779b8eSAndroid Build Coastguard Worker }
146*ec779b8eSAndroid Build Coastguard Worker
147*ec779b8eSAndroid Build Coastguard Worker EqualizerContext *pContext = new EqualizerContext;
148*ec779b8eSAndroid Build Coastguard Worker
149*ec779b8eSAndroid Build Coastguard Worker pContext->itfe = &gEqualizerInterface;
150*ec779b8eSAndroid Build Coastguard Worker pContext->pEqualizer = NULL;
151*ec779b8eSAndroid Build Coastguard Worker pContext->state = EQUALIZER_STATE_UNINITIALIZED;
152*ec779b8eSAndroid Build Coastguard Worker
153*ec779b8eSAndroid Build Coastguard Worker ret = Equalizer_init(pContext);
154*ec779b8eSAndroid Build Coastguard Worker if (ret < 0) {
155*ec779b8eSAndroid Build Coastguard Worker ALOGW("EffectLibCreateEffect() init failed");
156*ec779b8eSAndroid Build Coastguard Worker delete pContext;
157*ec779b8eSAndroid Build Coastguard Worker return ret;
158*ec779b8eSAndroid Build Coastguard Worker }
159*ec779b8eSAndroid Build Coastguard Worker
160*ec779b8eSAndroid Build Coastguard Worker *pHandle = (effect_handle_t)pContext;
161*ec779b8eSAndroid Build Coastguard Worker pContext->state = EQUALIZER_STATE_INITIALIZED;
162*ec779b8eSAndroid Build Coastguard Worker
163*ec779b8eSAndroid Build Coastguard Worker ALOGV("EffectLibCreateEffect %p, size %d",
164*ec779b8eSAndroid Build Coastguard Worker pContext, (int)(AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext)));
165*ec779b8eSAndroid Build Coastguard Worker
166*ec779b8eSAndroid Build Coastguard Worker return 0;
167*ec779b8eSAndroid Build Coastguard Worker
168*ec779b8eSAndroid Build Coastguard Worker } /* end EffectCreate */
169*ec779b8eSAndroid Build Coastguard Worker
EffectRelease(effect_handle_t handle)170*ec779b8eSAndroid Build Coastguard Worker extern "C" int EffectRelease(effect_handle_t handle) {
171*ec779b8eSAndroid Build Coastguard Worker EqualizerContext * pContext = (EqualizerContext *)handle;
172*ec779b8eSAndroid Build Coastguard Worker
173*ec779b8eSAndroid Build Coastguard Worker ALOGV("EffectLibReleaseEffect %p", handle);
174*ec779b8eSAndroid Build Coastguard Worker if (pContext == NULL) {
175*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
176*ec779b8eSAndroid Build Coastguard Worker }
177*ec779b8eSAndroid Build Coastguard Worker
178*ec779b8eSAndroid Build Coastguard Worker pContext->state = EQUALIZER_STATE_UNINITIALIZED;
179*ec779b8eSAndroid Build Coastguard Worker pContext->pEqualizer->free();
180*ec779b8eSAndroid Build Coastguard Worker delete pContext;
181*ec779b8eSAndroid Build Coastguard Worker
182*ec779b8eSAndroid Build Coastguard Worker return 0;
183*ec779b8eSAndroid Build Coastguard Worker } /* end EffectRelease */
184*ec779b8eSAndroid Build Coastguard Worker
EffectGetDescriptor(const effect_uuid_t * uuid,effect_descriptor_t * pDescriptor)185*ec779b8eSAndroid Build Coastguard Worker extern "C" int EffectGetDescriptor(const effect_uuid_t *uuid,
186*ec779b8eSAndroid Build Coastguard Worker effect_descriptor_t *pDescriptor) {
187*ec779b8eSAndroid Build Coastguard Worker
188*ec779b8eSAndroid Build Coastguard Worker if (pDescriptor == NULL || uuid == NULL){
189*ec779b8eSAndroid Build Coastguard Worker ALOGV("EffectGetDescriptor() called with NULL pointer");
190*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
191*ec779b8eSAndroid Build Coastguard Worker }
192*ec779b8eSAndroid Build Coastguard Worker
193*ec779b8eSAndroid Build Coastguard Worker if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
194*ec779b8eSAndroid Build Coastguard Worker *pDescriptor = gEqualizerDescriptor;
195*ec779b8eSAndroid Build Coastguard Worker return 0;
196*ec779b8eSAndroid Build Coastguard Worker }
197*ec779b8eSAndroid Build Coastguard Worker
198*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
199*ec779b8eSAndroid Build Coastguard Worker } /* end EffectGetDescriptor */
200*ec779b8eSAndroid Build Coastguard Worker
201*ec779b8eSAndroid Build Coastguard Worker
202*ec779b8eSAndroid Build Coastguard Worker //
203*ec779b8eSAndroid Build Coastguard Worker //--- local functions
204*ec779b8eSAndroid Build Coastguard Worker //
205*ec779b8eSAndroid Build Coastguard Worker
206*ec779b8eSAndroid Build Coastguard Worker #define CHECK_ARG(cond) { \
207*ec779b8eSAndroid Build Coastguard Worker if (!(cond)) { \
208*ec779b8eSAndroid Build Coastguard Worker ALOGV("Invalid argument: "#cond); \
209*ec779b8eSAndroid Build Coastguard Worker return -EINVAL; \
210*ec779b8eSAndroid Build Coastguard Worker } \
211*ec779b8eSAndroid Build Coastguard Worker }
212*ec779b8eSAndroid Build Coastguard Worker
213*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
214*ec779b8eSAndroid Build Coastguard Worker // Equalizer_setConfig()
215*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
216*ec779b8eSAndroid Build Coastguard Worker // Purpose: Set input and output audio configuration.
217*ec779b8eSAndroid Build Coastguard Worker //
218*ec779b8eSAndroid Build Coastguard Worker // Inputs:
219*ec779b8eSAndroid Build Coastguard Worker // pContext: effect engine context
220*ec779b8eSAndroid Build Coastguard Worker // pConfig: pointer to effect_config_t structure holding input and output
221*ec779b8eSAndroid Build Coastguard Worker // configuration parameters
222*ec779b8eSAndroid Build Coastguard Worker //
223*ec779b8eSAndroid Build Coastguard Worker // Outputs:
224*ec779b8eSAndroid Build Coastguard Worker //
225*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
226*ec779b8eSAndroid Build Coastguard Worker
Equalizer_setConfig(EqualizerContext * pContext,effect_config_t * pConfig)227*ec779b8eSAndroid Build Coastguard Worker int Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig)
228*ec779b8eSAndroid Build Coastguard Worker {
229*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_setConfig start");
230*ec779b8eSAndroid Build Coastguard Worker
231*ec779b8eSAndroid Build Coastguard Worker CHECK_ARG(pContext != NULL);
232*ec779b8eSAndroid Build Coastguard Worker CHECK_ARG(pConfig != NULL);
233*ec779b8eSAndroid Build Coastguard Worker
234*ec779b8eSAndroid Build Coastguard Worker CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
235*ec779b8eSAndroid Build Coastguard Worker CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
236*ec779b8eSAndroid Build Coastguard Worker CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
237*ec779b8eSAndroid Build Coastguard Worker CHECK_ARG((pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) ||
238*ec779b8eSAndroid Build Coastguard Worker (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO));
239*ec779b8eSAndroid Build Coastguard Worker CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
240*ec779b8eSAndroid Build Coastguard Worker || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
241*ec779b8eSAndroid Build Coastguard Worker CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT);
242*ec779b8eSAndroid Build Coastguard Worker
243*ec779b8eSAndroid Build Coastguard Worker int channelCount;
244*ec779b8eSAndroid Build Coastguard Worker if (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) {
245*ec779b8eSAndroid Build Coastguard Worker channelCount = 1;
246*ec779b8eSAndroid Build Coastguard Worker } else {
247*ec779b8eSAndroid Build Coastguard Worker channelCount = 2;
248*ec779b8eSAndroid Build Coastguard Worker }
249*ec779b8eSAndroid Build Coastguard Worker CHECK_ARG(channelCount <= AudioBiquadFilter::MAX_CHANNELS);
250*ec779b8eSAndroid Build Coastguard Worker
251*ec779b8eSAndroid Build Coastguard Worker pContext->config = *pConfig;
252*ec779b8eSAndroid Build Coastguard Worker
253*ec779b8eSAndroid Build Coastguard Worker pContext->pEqualizer->configure(channelCount,
254*ec779b8eSAndroid Build Coastguard Worker pConfig->inputCfg.samplingRate);
255*ec779b8eSAndroid Build Coastguard Worker
256*ec779b8eSAndroid Build Coastguard Worker pContext->adapter.configure(*pContext->pEqualizer, channelCount,
257*ec779b8eSAndroid Build Coastguard Worker pConfig->inputCfg.format,
258*ec779b8eSAndroid Build Coastguard Worker pConfig->outputCfg.accessMode);
259*ec779b8eSAndroid Build Coastguard Worker
260*ec779b8eSAndroid Build Coastguard Worker return 0;
261*ec779b8eSAndroid Build Coastguard Worker } // end Equalizer_setConfig
262*ec779b8eSAndroid Build Coastguard Worker
263*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
264*ec779b8eSAndroid Build Coastguard Worker // Equalizer_getConfig()
265*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
266*ec779b8eSAndroid Build Coastguard Worker // Purpose: Get input and output audio configuration.
267*ec779b8eSAndroid Build Coastguard Worker //
268*ec779b8eSAndroid Build Coastguard Worker // Inputs:
269*ec779b8eSAndroid Build Coastguard Worker // pContext: effect engine context
270*ec779b8eSAndroid Build Coastguard Worker // pConfig: pointer to effect_config_t structure holding input and output
271*ec779b8eSAndroid Build Coastguard Worker // configuration parameters
272*ec779b8eSAndroid Build Coastguard Worker //
273*ec779b8eSAndroid Build Coastguard Worker // Outputs:
274*ec779b8eSAndroid Build Coastguard Worker //
275*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
276*ec779b8eSAndroid Build Coastguard Worker
Equalizer_getConfig(EqualizerContext * pContext,effect_config_t * pConfig)277*ec779b8eSAndroid Build Coastguard Worker void Equalizer_getConfig(EqualizerContext *pContext, effect_config_t *pConfig)
278*ec779b8eSAndroid Build Coastguard Worker {
279*ec779b8eSAndroid Build Coastguard Worker *pConfig = pContext->config;
280*ec779b8eSAndroid Build Coastguard Worker } // end Equalizer_getConfig
281*ec779b8eSAndroid Build Coastguard Worker
282*ec779b8eSAndroid Build Coastguard Worker
283*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
284*ec779b8eSAndroid Build Coastguard Worker // Equalizer_init()
285*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
286*ec779b8eSAndroid Build Coastguard Worker // Purpose: Initialize engine with default configuration and creates
287*ec779b8eSAndroid Build Coastguard Worker // AudioEqualizer instance.
288*ec779b8eSAndroid Build Coastguard Worker //
289*ec779b8eSAndroid Build Coastguard Worker // Inputs:
290*ec779b8eSAndroid Build Coastguard Worker // pContext: effect engine context
291*ec779b8eSAndroid Build Coastguard Worker //
292*ec779b8eSAndroid Build Coastguard Worker // Outputs:
293*ec779b8eSAndroid Build Coastguard Worker //
294*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
295*ec779b8eSAndroid Build Coastguard Worker
Equalizer_init(EqualizerContext * pContext)296*ec779b8eSAndroid Build Coastguard Worker int Equalizer_init(EqualizerContext *pContext)
297*ec779b8eSAndroid Build Coastguard Worker {
298*ec779b8eSAndroid Build Coastguard Worker
299*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_init start");
300*ec779b8eSAndroid Build Coastguard Worker
301*ec779b8eSAndroid Build Coastguard Worker CHECK_ARG(pContext != NULL);
302*ec779b8eSAndroid Build Coastguard Worker
303*ec779b8eSAndroid Build Coastguard Worker if (pContext->pEqualizer != NULL) {
304*ec779b8eSAndroid Build Coastguard Worker pContext->pEqualizer->free();
305*ec779b8eSAndroid Build Coastguard Worker }
306*ec779b8eSAndroid Build Coastguard Worker
307*ec779b8eSAndroid Build Coastguard Worker pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
308*ec779b8eSAndroid Build Coastguard Worker pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
309*ec779b8eSAndroid Build Coastguard Worker pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
310*ec779b8eSAndroid Build Coastguard Worker pContext->config.inputCfg.samplingRate = 44100;
311*ec779b8eSAndroid Build Coastguard Worker pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
312*ec779b8eSAndroid Build Coastguard Worker pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
313*ec779b8eSAndroid Build Coastguard Worker pContext->config.inputCfg.bufferProvider.cookie = NULL;
314*ec779b8eSAndroid Build Coastguard Worker pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
315*ec779b8eSAndroid Build Coastguard Worker pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
316*ec779b8eSAndroid Build Coastguard Worker pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
317*ec779b8eSAndroid Build Coastguard Worker pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
318*ec779b8eSAndroid Build Coastguard Worker pContext->config.outputCfg.samplingRate = 44100;
319*ec779b8eSAndroid Build Coastguard Worker pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
320*ec779b8eSAndroid Build Coastguard Worker pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
321*ec779b8eSAndroid Build Coastguard Worker pContext->config.outputCfg.bufferProvider.cookie = NULL;
322*ec779b8eSAndroid Build Coastguard Worker pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL;
323*ec779b8eSAndroid Build Coastguard Worker
324*ec779b8eSAndroid Build Coastguard Worker pContext->pEqualizer = AudioEqualizer::CreateInstance(
325*ec779b8eSAndroid Build Coastguard Worker NULL,
326*ec779b8eSAndroid Build Coastguard Worker kNumBands,
327*ec779b8eSAndroid Build Coastguard Worker AudioBiquadFilter::MAX_CHANNELS,
328*ec779b8eSAndroid Build Coastguard Worker 44100,
329*ec779b8eSAndroid Build Coastguard Worker gEqualizerPresets,
330*ec779b8eSAndroid Build Coastguard Worker ARRAY_SIZE(gEqualizerPresets));
331*ec779b8eSAndroid Build Coastguard Worker
332*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < kNumBands; ++i) {
333*ec779b8eSAndroid Build Coastguard Worker pContext->pEqualizer->setFrequency(i, gFreqs[i]);
334*ec779b8eSAndroid Build Coastguard Worker pContext->pEqualizer->setBandwidth(i, gBandwidths[i]);
335*ec779b8eSAndroid Build Coastguard Worker }
336*ec779b8eSAndroid Build Coastguard Worker
337*ec779b8eSAndroid Build Coastguard Worker pContext->pEqualizer->enable(true);
338*ec779b8eSAndroid Build Coastguard Worker
339*ec779b8eSAndroid Build Coastguard Worker Equalizer_setConfig(pContext, &pContext->config);
340*ec779b8eSAndroid Build Coastguard Worker
341*ec779b8eSAndroid Build Coastguard Worker return 0;
342*ec779b8eSAndroid Build Coastguard Worker } // end Equalizer_init
343*ec779b8eSAndroid Build Coastguard Worker
344*ec779b8eSAndroid Build Coastguard Worker
345*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
346*ec779b8eSAndroid Build Coastguard Worker // Equalizer_getParameter()
347*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
348*ec779b8eSAndroid Build Coastguard Worker // Purpose:
349*ec779b8eSAndroid Build Coastguard Worker // Get a Equalizer parameter
350*ec779b8eSAndroid Build Coastguard Worker //
351*ec779b8eSAndroid Build Coastguard Worker // Inputs:
352*ec779b8eSAndroid Build Coastguard Worker // pEqualizer - handle to instance data
353*ec779b8eSAndroid Build Coastguard Worker // pParam - pointer to parameter
354*ec779b8eSAndroid Build Coastguard Worker // pValue - pointer to variable to hold retrieved value
355*ec779b8eSAndroid Build Coastguard Worker // pValueSize - pointer to value size: maximum size as input
356*ec779b8eSAndroid Build Coastguard Worker //
357*ec779b8eSAndroid Build Coastguard Worker // Outputs:
358*ec779b8eSAndroid Build Coastguard Worker // *pValue updated with parameter value
359*ec779b8eSAndroid Build Coastguard Worker // *pValueSize updated with actual value size
360*ec779b8eSAndroid Build Coastguard Worker //
361*ec779b8eSAndroid Build Coastguard Worker //
362*ec779b8eSAndroid Build Coastguard Worker // Side Effects:
363*ec779b8eSAndroid Build Coastguard Worker //
364*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
365*ec779b8eSAndroid Build Coastguard Worker
Equalizer_getParameter(AudioEqualizer * pEqualizer,int32_t * pParam,uint32_t * pValueSize,void * pValue)366*ec779b8eSAndroid Build Coastguard Worker int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, uint32_t *pValueSize, void *pValue)
367*ec779b8eSAndroid Build Coastguard Worker {
368*ec779b8eSAndroid Build Coastguard Worker int status = 0;
369*ec779b8eSAndroid Build Coastguard Worker int32_t param = *pParam++;
370*ec779b8eSAndroid Build Coastguard Worker int32_t param2;
371*ec779b8eSAndroid Build Coastguard Worker char *name;
372*ec779b8eSAndroid Build Coastguard Worker
373*ec779b8eSAndroid Build Coastguard Worker switch (param) {
374*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_NUM_BANDS:
375*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_CUR_PRESET:
376*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_GET_NUM_OF_PRESETS:
377*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_BAND_LEVEL:
378*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_GET_BAND:
379*ec779b8eSAndroid Build Coastguard Worker if (*pValueSize < sizeof(int16_t)) {
380*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
381*ec779b8eSAndroid Build Coastguard Worker }
382*ec779b8eSAndroid Build Coastguard Worker *pValueSize = sizeof(int16_t);
383*ec779b8eSAndroid Build Coastguard Worker break;
384*ec779b8eSAndroid Build Coastguard Worker
385*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_LEVEL_RANGE:
386*ec779b8eSAndroid Build Coastguard Worker if (*pValueSize < 2 * sizeof(int16_t)) {
387*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
388*ec779b8eSAndroid Build Coastguard Worker }
389*ec779b8eSAndroid Build Coastguard Worker *pValueSize = 2 * sizeof(int16_t);
390*ec779b8eSAndroid Build Coastguard Worker break;
391*ec779b8eSAndroid Build Coastguard Worker
392*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_BAND_FREQ_RANGE:
393*ec779b8eSAndroid Build Coastguard Worker if (*pValueSize < 2 * sizeof(int32_t)) {
394*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
395*ec779b8eSAndroid Build Coastguard Worker }
396*ec779b8eSAndroid Build Coastguard Worker *pValueSize = 2 * sizeof(int32_t);
397*ec779b8eSAndroid Build Coastguard Worker break;
398*ec779b8eSAndroid Build Coastguard Worker
399*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_CENTER_FREQ:
400*ec779b8eSAndroid Build Coastguard Worker if (*pValueSize < sizeof(int32_t)) {
401*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
402*ec779b8eSAndroid Build Coastguard Worker }
403*ec779b8eSAndroid Build Coastguard Worker *pValueSize = sizeof(int32_t);
404*ec779b8eSAndroid Build Coastguard Worker break;
405*ec779b8eSAndroid Build Coastguard Worker
406*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_GET_PRESET_NAME:
407*ec779b8eSAndroid Build Coastguard Worker break;
408*ec779b8eSAndroid Build Coastguard Worker
409*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_PROPERTIES:
410*ec779b8eSAndroid Build Coastguard Worker if (*pValueSize < (2 + kNumBands) * sizeof(uint16_t)) {
411*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
412*ec779b8eSAndroid Build Coastguard Worker }
413*ec779b8eSAndroid Build Coastguard Worker *pValueSize = (2 + kNumBands) * sizeof(uint16_t);
414*ec779b8eSAndroid Build Coastguard Worker break;
415*ec779b8eSAndroid Build Coastguard Worker
416*ec779b8eSAndroid Build Coastguard Worker default:
417*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
418*ec779b8eSAndroid Build Coastguard Worker }
419*ec779b8eSAndroid Build Coastguard Worker
420*ec779b8eSAndroid Build Coastguard Worker switch (param) {
421*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_NUM_BANDS:
422*ec779b8eSAndroid Build Coastguard Worker *(uint16_t *)pValue = (uint16_t)kNumBands;
423*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue);
424*ec779b8eSAndroid Build Coastguard Worker break;
425*ec779b8eSAndroid Build Coastguard Worker
426*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_LEVEL_RANGE:
427*ec779b8eSAndroid Build Coastguard Worker *(int16_t *)pValue = -9600;
428*ec779b8eSAndroid Build Coastguard Worker *((int16_t *)pValue + 1) = 4800;
429*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d",
430*ec779b8eSAndroid Build Coastguard Worker *(int32_t *)pValue, *((int32_t *)pValue + 1));
431*ec779b8eSAndroid Build Coastguard Worker break;
432*ec779b8eSAndroid Build Coastguard Worker
433*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_BAND_LEVEL:
434*ec779b8eSAndroid Build Coastguard Worker param2 = *pParam;
435*ec779b8eSAndroid Build Coastguard Worker if (param2 >= kNumBands) {
436*ec779b8eSAndroid Build Coastguard Worker status = -EINVAL;
437*ec779b8eSAndroid Build Coastguard Worker break;
438*ec779b8eSAndroid Build Coastguard Worker }
439*ec779b8eSAndroid Build Coastguard Worker *(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2);
440*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d",
441*ec779b8eSAndroid Build Coastguard Worker param2, *(int32_t *)pValue);
442*ec779b8eSAndroid Build Coastguard Worker break;
443*ec779b8eSAndroid Build Coastguard Worker
444*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_CENTER_FREQ:
445*ec779b8eSAndroid Build Coastguard Worker param2 = *pParam;
446*ec779b8eSAndroid Build Coastguard Worker if (param2 >= kNumBands) {
447*ec779b8eSAndroid Build Coastguard Worker status = -EINVAL;
448*ec779b8eSAndroid Build Coastguard Worker break;
449*ec779b8eSAndroid Build Coastguard Worker }
450*ec779b8eSAndroid Build Coastguard Worker *(int32_t *)pValue = pEqualizer->getFrequency(param2);
451*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d",
452*ec779b8eSAndroid Build Coastguard Worker param2, *(int32_t *)pValue);
453*ec779b8eSAndroid Build Coastguard Worker break;
454*ec779b8eSAndroid Build Coastguard Worker
455*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_BAND_FREQ_RANGE:
456*ec779b8eSAndroid Build Coastguard Worker param2 = *pParam;
457*ec779b8eSAndroid Build Coastguard Worker if (param2 >= kNumBands) {
458*ec779b8eSAndroid Build Coastguard Worker status = -EINVAL;
459*ec779b8eSAndroid Build Coastguard Worker break;
460*ec779b8eSAndroid Build Coastguard Worker }
461*ec779b8eSAndroid Build Coastguard Worker pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1));
462*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d",
463*ec779b8eSAndroid Build Coastguard Worker param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
464*ec779b8eSAndroid Build Coastguard Worker break;
465*ec779b8eSAndroid Build Coastguard Worker
466*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_GET_BAND:
467*ec779b8eSAndroid Build Coastguard Worker param2 = *pParam;
468*ec779b8eSAndroid Build Coastguard Worker *(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2);
469*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d",
470*ec779b8eSAndroid Build Coastguard Worker param2, *(int32_t *)pValue);
471*ec779b8eSAndroid Build Coastguard Worker break;
472*ec779b8eSAndroid Build Coastguard Worker
473*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_CUR_PRESET:
474*ec779b8eSAndroid Build Coastguard Worker *(uint16_t *)pValue = (uint16_t)pEqualizer->getPreset();
475*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue);
476*ec779b8eSAndroid Build Coastguard Worker break;
477*ec779b8eSAndroid Build Coastguard Worker
478*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_GET_NUM_OF_PRESETS:
479*ec779b8eSAndroid Build Coastguard Worker *(uint16_t *)pValue = (uint16_t)pEqualizer->getNumPresets();
480*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue);
481*ec779b8eSAndroid Build Coastguard Worker break;
482*ec779b8eSAndroid Build Coastguard Worker
483*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_GET_PRESET_NAME:
484*ec779b8eSAndroid Build Coastguard Worker param2 = *pParam;
485*ec779b8eSAndroid Build Coastguard Worker if (param2 >= pEqualizer->getNumPresets()) {
486*ec779b8eSAndroid Build Coastguard Worker status = -EINVAL;
487*ec779b8eSAndroid Build Coastguard Worker break;
488*ec779b8eSAndroid Build Coastguard Worker }
489*ec779b8eSAndroid Build Coastguard Worker name = (char *)pValue;
490*ec779b8eSAndroid Build Coastguard Worker strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1);
491*ec779b8eSAndroid Build Coastguard Worker name[*pValueSize - 1] = 0;
492*ec779b8eSAndroid Build Coastguard Worker *pValueSize = strlen(name) + 1;
493*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d",
494*ec779b8eSAndroid Build Coastguard Worker param2, gEqualizerPresets[param2].name, *pValueSize);
495*ec779b8eSAndroid Build Coastguard Worker break;
496*ec779b8eSAndroid Build Coastguard Worker
497*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_PROPERTIES: {
498*ec779b8eSAndroid Build Coastguard Worker int16_t *p = (int16_t *)pValue;
499*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_getParameter() EQ_PARAM_PROPERTIES");
500*ec779b8eSAndroid Build Coastguard Worker p[0] = (int16_t)pEqualizer->getPreset();
501*ec779b8eSAndroid Build Coastguard Worker p[1] = (int16_t)kNumBands;
502*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < kNumBands; i++) {
503*ec779b8eSAndroid Build Coastguard Worker p[2 + i] = (int16_t)pEqualizer->getGain(i);
504*ec779b8eSAndroid Build Coastguard Worker }
505*ec779b8eSAndroid Build Coastguard Worker } break;
506*ec779b8eSAndroid Build Coastguard Worker
507*ec779b8eSAndroid Build Coastguard Worker default:
508*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_getParameter() invalid param %d", param);
509*ec779b8eSAndroid Build Coastguard Worker status = -EINVAL;
510*ec779b8eSAndroid Build Coastguard Worker break;
511*ec779b8eSAndroid Build Coastguard Worker }
512*ec779b8eSAndroid Build Coastguard Worker
513*ec779b8eSAndroid Build Coastguard Worker return status;
514*ec779b8eSAndroid Build Coastguard Worker } // end Equalizer_getParameter
515*ec779b8eSAndroid Build Coastguard Worker
516*ec779b8eSAndroid Build Coastguard Worker
517*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
518*ec779b8eSAndroid Build Coastguard Worker // Equalizer_setParameter()
519*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
520*ec779b8eSAndroid Build Coastguard Worker // Purpose:
521*ec779b8eSAndroid Build Coastguard Worker // Set a Equalizer parameter
522*ec779b8eSAndroid Build Coastguard Worker //
523*ec779b8eSAndroid Build Coastguard Worker // Inputs:
524*ec779b8eSAndroid Build Coastguard Worker // pEqualizer - handle to instance data
525*ec779b8eSAndroid Build Coastguard Worker // pParam - pointer to parameter
526*ec779b8eSAndroid Build Coastguard Worker // pValue - pointer to value
527*ec779b8eSAndroid Build Coastguard Worker //
528*ec779b8eSAndroid Build Coastguard Worker // Outputs:
529*ec779b8eSAndroid Build Coastguard Worker //
530*ec779b8eSAndroid Build Coastguard Worker //
531*ec779b8eSAndroid Build Coastguard Worker // Side Effects:
532*ec779b8eSAndroid Build Coastguard Worker //
533*ec779b8eSAndroid Build Coastguard Worker //----------------------------------------------------------------------------
534*ec779b8eSAndroid Build Coastguard Worker
Equalizer_setParameter(AudioEqualizer * pEqualizer,int32_t * pParam,void * pValue)535*ec779b8eSAndroid Build Coastguard Worker int Equalizer_setParameter (AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue)
536*ec779b8eSAndroid Build Coastguard Worker {
537*ec779b8eSAndroid Build Coastguard Worker int status = 0;
538*ec779b8eSAndroid Build Coastguard Worker int32_t preset;
539*ec779b8eSAndroid Build Coastguard Worker int32_t band;
540*ec779b8eSAndroid Build Coastguard Worker int32_t level;
541*ec779b8eSAndroid Build Coastguard Worker int32_t param = *pParam++;
542*ec779b8eSAndroid Build Coastguard Worker
543*ec779b8eSAndroid Build Coastguard Worker
544*ec779b8eSAndroid Build Coastguard Worker switch (param) {
545*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_CUR_PRESET:
546*ec779b8eSAndroid Build Coastguard Worker preset = (int32_t)(*(uint16_t *)pValue);
547*ec779b8eSAndroid Build Coastguard Worker
548*ec779b8eSAndroid Build Coastguard Worker ALOGV("setParameter() EQ_PARAM_CUR_PRESET %d", preset);
549*ec779b8eSAndroid Build Coastguard Worker if (preset < 0 || preset >= pEqualizer->getNumPresets()) {
550*ec779b8eSAndroid Build Coastguard Worker status = -EINVAL;
551*ec779b8eSAndroid Build Coastguard Worker break;
552*ec779b8eSAndroid Build Coastguard Worker }
553*ec779b8eSAndroid Build Coastguard Worker pEqualizer->setPreset(preset);
554*ec779b8eSAndroid Build Coastguard Worker pEqualizer->commit(true);
555*ec779b8eSAndroid Build Coastguard Worker break;
556*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_BAND_LEVEL:
557*ec779b8eSAndroid Build Coastguard Worker band = *pParam;
558*ec779b8eSAndroid Build Coastguard Worker level = (int32_t)(*(int16_t *)pValue);
559*ec779b8eSAndroid Build Coastguard Worker ALOGV("setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level);
560*ec779b8eSAndroid Build Coastguard Worker if (band >= kNumBands) {
561*ec779b8eSAndroid Build Coastguard Worker status = -EINVAL;
562*ec779b8eSAndroid Build Coastguard Worker break;
563*ec779b8eSAndroid Build Coastguard Worker }
564*ec779b8eSAndroid Build Coastguard Worker pEqualizer->setGain(band, level);
565*ec779b8eSAndroid Build Coastguard Worker pEqualizer->commit(true);
566*ec779b8eSAndroid Build Coastguard Worker break;
567*ec779b8eSAndroid Build Coastguard Worker case EQ_PARAM_PROPERTIES: {
568*ec779b8eSAndroid Build Coastguard Worker ALOGV("setParameter() EQ_PARAM_PROPERTIES");
569*ec779b8eSAndroid Build Coastguard Worker int16_t *p = (int16_t *)pValue;
570*ec779b8eSAndroid Build Coastguard Worker if ((int)p[0] >= pEqualizer->getNumPresets()) {
571*ec779b8eSAndroid Build Coastguard Worker status = -EINVAL;
572*ec779b8eSAndroid Build Coastguard Worker break;
573*ec779b8eSAndroid Build Coastguard Worker }
574*ec779b8eSAndroid Build Coastguard Worker if (p[0] >= 0) {
575*ec779b8eSAndroid Build Coastguard Worker pEqualizer->setPreset((int)p[0]);
576*ec779b8eSAndroid Build Coastguard Worker } else {
577*ec779b8eSAndroid Build Coastguard Worker if ((int)p[1] != kNumBands) {
578*ec779b8eSAndroid Build Coastguard Worker status = -EINVAL;
579*ec779b8eSAndroid Build Coastguard Worker break;
580*ec779b8eSAndroid Build Coastguard Worker }
581*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < kNumBands; i++) {
582*ec779b8eSAndroid Build Coastguard Worker pEqualizer->setGain(i, (int32_t)p[2 + i]);
583*ec779b8eSAndroid Build Coastguard Worker }
584*ec779b8eSAndroid Build Coastguard Worker }
585*ec779b8eSAndroid Build Coastguard Worker pEqualizer->commit(true);
586*ec779b8eSAndroid Build Coastguard Worker } break;
587*ec779b8eSAndroid Build Coastguard Worker default:
588*ec779b8eSAndroid Build Coastguard Worker ALOGV("setParameter() invalid param %d", param);
589*ec779b8eSAndroid Build Coastguard Worker status = -EINVAL;
590*ec779b8eSAndroid Build Coastguard Worker break;
591*ec779b8eSAndroid Build Coastguard Worker }
592*ec779b8eSAndroid Build Coastguard Worker
593*ec779b8eSAndroid Build Coastguard Worker return status;
594*ec779b8eSAndroid Build Coastguard Worker } // end Equalizer_setParameter
595*ec779b8eSAndroid Build Coastguard Worker
596*ec779b8eSAndroid Build Coastguard Worker } // namespace
597*ec779b8eSAndroid Build Coastguard Worker } // namespace
598*ec779b8eSAndroid Build Coastguard Worker
599*ec779b8eSAndroid Build Coastguard Worker
600*ec779b8eSAndroid Build Coastguard Worker //
601*ec779b8eSAndroid Build Coastguard Worker //--- Effect Control Interface Implementation
602*ec779b8eSAndroid Build Coastguard Worker //
603*ec779b8eSAndroid Build Coastguard Worker
Equalizer_process(effect_handle_t self,audio_buffer_t * inBuffer,audio_buffer_t * outBuffer)604*ec779b8eSAndroid Build Coastguard Worker extern "C" int Equalizer_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
605*ec779b8eSAndroid Build Coastguard Worker {
606*ec779b8eSAndroid Build Coastguard Worker android::EqualizerContext * pContext = (android::EqualizerContext *) self;
607*ec779b8eSAndroid Build Coastguard Worker
608*ec779b8eSAndroid Build Coastguard Worker if (pContext == NULL) {
609*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
610*ec779b8eSAndroid Build Coastguard Worker }
611*ec779b8eSAndroid Build Coastguard Worker if (inBuffer == NULL || inBuffer->raw == NULL ||
612*ec779b8eSAndroid Build Coastguard Worker outBuffer == NULL || outBuffer->raw == NULL ||
613*ec779b8eSAndroid Build Coastguard Worker inBuffer->frameCount != outBuffer->frameCount) {
614*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
615*ec779b8eSAndroid Build Coastguard Worker }
616*ec779b8eSAndroid Build Coastguard Worker
617*ec779b8eSAndroid Build Coastguard Worker if (pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
618*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
619*ec779b8eSAndroid Build Coastguard Worker }
620*ec779b8eSAndroid Build Coastguard Worker if (pContext->state == EQUALIZER_STATE_INITIALIZED) {
621*ec779b8eSAndroid Build Coastguard Worker return -ENODATA;
622*ec779b8eSAndroid Build Coastguard Worker }
623*ec779b8eSAndroid Build Coastguard Worker
624*ec779b8eSAndroid Build Coastguard Worker pContext->adapter.process(inBuffer->raw, outBuffer->raw, outBuffer->frameCount);
625*ec779b8eSAndroid Build Coastguard Worker
626*ec779b8eSAndroid Build Coastguard Worker return 0;
627*ec779b8eSAndroid Build Coastguard Worker } // end Equalizer_process
628*ec779b8eSAndroid Build Coastguard Worker
Equalizer_command(effect_handle_t self,uint32_t cmdCode,uint32_t cmdSize,void * pCmdData,uint32_t * replySize,void * pReplyData)629*ec779b8eSAndroid Build Coastguard Worker extern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
630*ec779b8eSAndroid Build Coastguard Worker void *pCmdData, uint32_t *replySize, void *pReplyData) {
631*ec779b8eSAndroid Build Coastguard Worker
632*ec779b8eSAndroid Build Coastguard Worker android::EqualizerContext * pContext = (android::EqualizerContext *) self;
633*ec779b8eSAndroid Build Coastguard Worker
634*ec779b8eSAndroid Build Coastguard Worker if (pContext == NULL || pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
635*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
636*ec779b8eSAndroid Build Coastguard Worker }
637*ec779b8eSAndroid Build Coastguard Worker
638*ec779b8eSAndroid Build Coastguard Worker android::AudioEqualizer * pEqualizer = pContext->pEqualizer;
639*ec779b8eSAndroid Build Coastguard Worker
640*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_command command %d cmdSize %d",cmdCode, cmdSize);
641*ec779b8eSAndroid Build Coastguard Worker
642*ec779b8eSAndroid Build Coastguard Worker switch (cmdCode) {
643*ec779b8eSAndroid Build Coastguard Worker case EFFECT_CMD_INIT:
644*ec779b8eSAndroid Build Coastguard Worker if (pReplyData == NULL || *replySize != sizeof(int)) {
645*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
646*ec779b8eSAndroid Build Coastguard Worker }
647*ec779b8eSAndroid Build Coastguard Worker *(int *) pReplyData = Equalizer_init(pContext);
648*ec779b8eSAndroid Build Coastguard Worker break;
649*ec779b8eSAndroid Build Coastguard Worker case EFFECT_CMD_SET_CONFIG:
650*ec779b8eSAndroid Build Coastguard Worker if (pCmdData == NULL || cmdSize != sizeof(effect_config_t)
651*ec779b8eSAndroid Build Coastguard Worker || pReplyData == NULL || *replySize != sizeof(int)) {
652*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
653*ec779b8eSAndroid Build Coastguard Worker }
654*ec779b8eSAndroid Build Coastguard Worker *(int *) pReplyData = Equalizer_setConfig(pContext,
655*ec779b8eSAndroid Build Coastguard Worker (effect_config_t *) pCmdData);
656*ec779b8eSAndroid Build Coastguard Worker break;
657*ec779b8eSAndroid Build Coastguard Worker case EFFECT_CMD_GET_CONFIG:
658*ec779b8eSAndroid Build Coastguard Worker if (pReplyData == NULL || *replySize != sizeof(effect_config_t)) {
659*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
660*ec779b8eSAndroid Build Coastguard Worker }
661*ec779b8eSAndroid Build Coastguard Worker Equalizer_getConfig(pContext, (effect_config_t *) pCmdData);
662*ec779b8eSAndroid Build Coastguard Worker break;
663*ec779b8eSAndroid Build Coastguard Worker case EFFECT_CMD_RESET:
664*ec779b8eSAndroid Build Coastguard Worker Equalizer_setConfig(pContext, &pContext->config);
665*ec779b8eSAndroid Build Coastguard Worker break;
666*ec779b8eSAndroid Build Coastguard Worker case EFFECT_CMD_GET_PARAM: {
667*ec779b8eSAndroid Build Coastguard Worker if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
668*ec779b8eSAndroid Build Coastguard Worker pReplyData == NULL || *replySize < (sizeof(effect_param_t) + sizeof(int32_t))) {
669*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
670*ec779b8eSAndroid Build Coastguard Worker }
671*ec779b8eSAndroid Build Coastguard Worker effect_param_t *p = (effect_param_t *)pCmdData;
672*ec779b8eSAndroid Build Coastguard Worker memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
673*ec779b8eSAndroid Build Coastguard Worker p = (effect_param_t *)pReplyData;
674*ec779b8eSAndroid Build Coastguard Worker int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
675*ec779b8eSAndroid Build Coastguard Worker p->status = android::Equalizer_getParameter(pEqualizer, (int32_t *)p->data, &p->vsize,
676*ec779b8eSAndroid Build Coastguard Worker p->data + voffset);
677*ec779b8eSAndroid Build Coastguard Worker *replySize = sizeof(effect_param_t) + voffset + p->vsize;
678*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x",
679*ec779b8eSAndroid Build Coastguard Worker *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize,
680*ec779b8eSAndroid Build Coastguard Worker *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset),
681*ec779b8eSAndroid Build Coastguard Worker *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset + sizeof(int32_t)));
682*ec779b8eSAndroid Build Coastguard Worker
683*ec779b8eSAndroid Build Coastguard Worker } break;
684*ec779b8eSAndroid Build Coastguard Worker case EFFECT_CMD_SET_PARAM: {
685*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p",
686*ec779b8eSAndroid Build Coastguard Worker cmdSize, pCmdData, *replySize, pReplyData);
687*ec779b8eSAndroid Build Coastguard Worker if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
688*ec779b8eSAndroid Build Coastguard Worker pReplyData == NULL || *replySize != sizeof(int32_t)) {
689*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
690*ec779b8eSAndroid Build Coastguard Worker }
691*ec779b8eSAndroid Build Coastguard Worker effect_param_t *p = (effect_param_t *) pCmdData;
692*ec779b8eSAndroid Build Coastguard Worker *(int *)pReplyData = android::Equalizer_setParameter(pEqualizer, (int32_t *)p->data,
693*ec779b8eSAndroid Build Coastguard Worker p->data + p->psize);
694*ec779b8eSAndroid Build Coastguard Worker } break;
695*ec779b8eSAndroid Build Coastguard Worker case EFFECT_CMD_ENABLE:
696*ec779b8eSAndroid Build Coastguard Worker if (pReplyData == NULL || *replySize != sizeof(int)) {
697*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
698*ec779b8eSAndroid Build Coastguard Worker }
699*ec779b8eSAndroid Build Coastguard Worker if (pContext->state != EQUALIZER_STATE_INITIALIZED) {
700*ec779b8eSAndroid Build Coastguard Worker return -ENOSYS;
701*ec779b8eSAndroid Build Coastguard Worker }
702*ec779b8eSAndroid Build Coastguard Worker pContext->state = EQUALIZER_STATE_ACTIVE;
703*ec779b8eSAndroid Build Coastguard Worker ALOGV("EFFECT_CMD_ENABLE() OK");
704*ec779b8eSAndroid Build Coastguard Worker *(int *)pReplyData = 0;
705*ec779b8eSAndroid Build Coastguard Worker break;
706*ec779b8eSAndroid Build Coastguard Worker case EFFECT_CMD_DISABLE:
707*ec779b8eSAndroid Build Coastguard Worker if (pReplyData == NULL || *replySize != sizeof(int)) {
708*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
709*ec779b8eSAndroid Build Coastguard Worker }
710*ec779b8eSAndroid Build Coastguard Worker if (pContext->state != EQUALIZER_STATE_ACTIVE) {
711*ec779b8eSAndroid Build Coastguard Worker return -ENOSYS;
712*ec779b8eSAndroid Build Coastguard Worker }
713*ec779b8eSAndroid Build Coastguard Worker pContext->state = EQUALIZER_STATE_INITIALIZED;
714*ec779b8eSAndroid Build Coastguard Worker ALOGV("EFFECT_CMD_DISABLE() OK");
715*ec779b8eSAndroid Build Coastguard Worker *(int *)pReplyData = 0;
716*ec779b8eSAndroid Build Coastguard Worker break;
717*ec779b8eSAndroid Build Coastguard Worker case EFFECT_CMD_SET_DEVICE:
718*ec779b8eSAndroid Build Coastguard Worker case EFFECT_CMD_SET_VOLUME:
719*ec779b8eSAndroid Build Coastguard Worker case EFFECT_CMD_SET_AUDIO_MODE:
720*ec779b8eSAndroid Build Coastguard Worker break;
721*ec779b8eSAndroid Build Coastguard Worker default:
722*ec779b8eSAndroid Build Coastguard Worker ALOGW("Equalizer_command invalid command %d",cmdCode);
723*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
724*ec779b8eSAndroid Build Coastguard Worker }
725*ec779b8eSAndroid Build Coastguard Worker
726*ec779b8eSAndroid Build Coastguard Worker return 0;
727*ec779b8eSAndroid Build Coastguard Worker }
728*ec779b8eSAndroid Build Coastguard Worker
Equalizer_getDescriptor(effect_handle_t self,effect_descriptor_t * pDescriptor)729*ec779b8eSAndroid Build Coastguard Worker extern "C" int Equalizer_getDescriptor(effect_handle_t self,
730*ec779b8eSAndroid Build Coastguard Worker effect_descriptor_t *pDescriptor)
731*ec779b8eSAndroid Build Coastguard Worker {
732*ec779b8eSAndroid Build Coastguard Worker android::EqualizerContext * pContext = (android::EqualizerContext *) self;
733*ec779b8eSAndroid Build Coastguard Worker
734*ec779b8eSAndroid Build Coastguard Worker if (pContext == NULL || pDescriptor == NULL) {
735*ec779b8eSAndroid Build Coastguard Worker ALOGV("Equalizer_getDescriptor() invalid param");
736*ec779b8eSAndroid Build Coastguard Worker return -EINVAL;
737*ec779b8eSAndroid Build Coastguard Worker }
738*ec779b8eSAndroid Build Coastguard Worker
739*ec779b8eSAndroid Build Coastguard Worker *pDescriptor = android::gEqualizerDescriptor;
740*ec779b8eSAndroid Build Coastguard Worker
741*ec779b8eSAndroid Build Coastguard Worker return 0;
742*ec779b8eSAndroid Build Coastguard Worker }
743*ec779b8eSAndroid Build Coastguard Worker
744*ec779b8eSAndroid Build Coastguard Worker // effect_handle_t interface implementation for equalizer effect
745*ec779b8eSAndroid Build Coastguard Worker const struct effect_interface_s gEqualizerInterface = {
746*ec779b8eSAndroid Build Coastguard Worker Equalizer_process,
747*ec779b8eSAndroid Build Coastguard Worker Equalizer_command,
748*ec779b8eSAndroid Build Coastguard Worker Equalizer_getDescriptor,
749*ec779b8eSAndroid Build Coastguard Worker NULL
750*ec779b8eSAndroid Build Coastguard Worker };
751*ec779b8eSAndroid Build Coastguard Worker
752*ec779b8eSAndroid Build Coastguard Worker __attribute__ ((visibility ("default")))
753*ec779b8eSAndroid Build Coastguard Worker audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
754*ec779b8eSAndroid Build Coastguard Worker .tag = AUDIO_EFFECT_LIBRARY_TAG,
755*ec779b8eSAndroid Build Coastguard Worker .version = EFFECT_LIBRARY_API_VERSION,
756*ec779b8eSAndroid Build Coastguard Worker .name = "Test Equalizer Library",
757*ec779b8eSAndroid Build Coastguard Worker .implementor = "The Android Open Source Project",
758*ec779b8eSAndroid Build Coastguard Worker .create_effect = android::EffectCreate,
759*ec779b8eSAndroid Build Coastguard Worker .release_effect = android::EffectRelease,
760*ec779b8eSAndroid Build Coastguard Worker .get_descriptor = android::EffectGetDescriptor,
761*ec779b8eSAndroid Build Coastguard Worker };
762