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