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