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