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