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