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