blob: af0c411aa7250b5f9c360b2aeb89b44f5666d6f0 [file] [log] [blame]
Eric Laurent135ad072010-05-21 06:05:13 -07001/*
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//#define LOG_NDEBUG 0
20#include <cutils/log.h>
21#include <assert.h>
22#include <stdlib.h>
Eric Laurent17217ab2010-05-25 12:38:34 -070023#include <string.h>
Eric Laurent135ad072010-05-21 06:05:13 -070024#include <new>
25#include "AudioEqualizer.h"
26#include "AudioBiquadFilter.h"
27#include "AudioFormatAdapter.h"
28#include <media/EffectEqualizerApi.h>
29
30// effect_interface_t interface implementation for equalizer effect
31extern "C" const struct effect_interface_s gEqualizerInterface;
32
Eric Laurente44b1ef2010-07-09 13:34:17 -070033enum equalizer_state_e {
34 EQUALIZER_STATE_UNINITIALIZED,
35 EQUALIZER_STATE_INITIALIZED,
36 EQUALIZER_STATE_ACTIVE,
37};
38
Eric Laurent135ad072010-05-21 06:05:13 -070039namespace android {
40namespace {
41
42// Google Graphic Equalizer UUID: e25aa840-543b-11df-98a5-0002a5d5c51b
43const effect_descriptor_t gEqualizerDescriptor = {
44 {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
45 {0xe25aa840, 0x543b, 0x11df, 0x98a5, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
46 EFFECT_API_VERSION,
47 (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
Eric Laurentffe9c252010-06-23 17:38:20 -070048 0, // TODO
49 1,
Eric Laurent135ad072010-05-21 06:05:13 -070050 "Graphic Equalizer",
51 "Google Inc.",
52};
Eric Laurent135ad072010-05-21 06:05:13 -070053
54/////////////////// BEGIN EQ PRESETS ///////////////////////////////////////////
55const int kNumBands = 5;
56const uint32_t gFreqs[kNumBands] = { 50000, 125000, 900000, 3200000, 6300000 };
57const uint32_t gBandwidths[kNumBands] = { 0, 3600, 3600, 2400, 0 };
58
59const AudioEqualizer::BandConfig gBandsClassic[kNumBands] = {
60 { 300, gFreqs[0], gBandwidths[0] },
61 { 400, gFreqs[1], gBandwidths[1] },
62 { 0, gFreqs[2], gBandwidths[2] },
63 { 200, gFreqs[3], gBandwidths[3] },
64 { -300, gFreqs[4], gBandwidths[4] }
65};
66
67const AudioEqualizer::BandConfig gBandsJazz[kNumBands] = {
68 { -600, gFreqs[0], gBandwidths[0] },
69 { 200, gFreqs[1], gBandwidths[1] },
70 { 400, gFreqs[2], gBandwidths[2] },
71 { -400, gFreqs[3], gBandwidths[3] },
72 { -600, gFreqs[4], gBandwidths[4] }
73};
74
75const AudioEqualizer::BandConfig gBandsPop[kNumBands] = {
76 { 400, gFreqs[0], gBandwidths[0] },
77 { -400, gFreqs[1], gBandwidths[1] },
78 { 300, gFreqs[2], gBandwidths[2] },
79 { -400, gFreqs[3], gBandwidths[3] },
80 { 600, gFreqs[4], gBandwidths[4] }
81};
82
83const AudioEqualizer::BandConfig gBandsRock[kNumBands] = {
84 { 700, gFreqs[0], gBandwidths[0] },
85 { 400, gFreqs[1], gBandwidths[1] },
86 { -400, gFreqs[2], gBandwidths[2] },
87 { 400, gFreqs[3], gBandwidths[3] },
88 { 200, gFreqs[4], gBandwidths[4] }
89};
90
91const AudioEqualizer::PresetConfig gEqualizerPresets[] = {
92 { "Classic", gBandsClassic },
93 { "Jazz", gBandsJazz },
94 { "Pop", gBandsPop },
95 { "Rock", gBandsRock }
96};
97
98/////////////////// END EQ PRESETS /////////////////////////////////////////////
99
100static const size_t kBufferSize = 32;
101
102typedef AudioFormatAdapter<AudioEqualizer, kBufferSize> FormatAdapter;
103
104struct EqualizerContext {
105 const struct effect_interface_s *itfe;
106 effect_config_t config;
107 FormatAdapter adapter;
108 AudioEqualizer * pEqualizer;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700109 uint32_t state;
Eric Laurent135ad072010-05-21 06:05:13 -0700110};
111
Eric Laurent135ad072010-05-21 06:05:13 -0700112//--- local function prototypes
113
114int Equalizer_init(EqualizerContext *pContext);
115int Equalizer_configure(EqualizerContext *pContext, effect_config_t *pConfig);
116int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue);
117int Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue);
118
119
120//
121//--- Effect Library Interface Implementation
122//
123
Eric Laurentbe916aa2010-06-01 23:49:17 -0700124extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects) {
Eric Laurent135ad072010-05-21 06:05:13 -0700125 *pNumEffects = 1;
Eric Laurent135ad072010-05-21 06:05:13 -0700126 return 0;
127} /* end EffectQueryNumberEffects */
128
Eric Laurentffe9c252010-06-23 17:38:20 -0700129extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) {
Eric Laurent135ad072010-05-21 06:05:13 -0700130 if (pDescriptor == NULL) {
131 return -EINVAL;
132 }
Eric Laurentffe9c252010-06-23 17:38:20 -0700133 if (index > 0) {
134 return -EINVAL;
Eric Laurent135ad072010-05-21 06:05:13 -0700135 }
136 memcpy(pDescriptor, &gEqualizerDescriptor, sizeof(effect_descriptor_t));
137 return 0;
138} /* end EffectQueryNext */
139
140extern "C" int EffectCreate(effect_uuid_t *uuid,
Eric Laurentffe9c252010-06-23 17:38:20 -0700141 int32_t sessionId,
142 int32_t ioId,
Eric Laurent135ad072010-05-21 06:05:13 -0700143 effect_interface_t *pInterface) {
144 int ret;
145 int i;
146
147 LOGV("EffectLibCreateEffect start");
148
149 if (pInterface == NULL || uuid == NULL) {
150 return -EINVAL;
151 }
152
153 if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) != 0) {
154 return -EINVAL;
155 }
156
157 EqualizerContext *pContext = new EqualizerContext;
158
159 pContext->itfe = &gEqualizerInterface;
160 pContext->pEqualizer = NULL;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700161 pContext->state = EQUALIZER_STATE_UNINITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700162
163 ret = Equalizer_init(pContext);
164 if (ret < 0) {
165 LOGW("EffectLibCreateEffect() init failed");
166 delete pContext;
167 return ret;
168 }
169
170 *pInterface = (effect_interface_t)pContext;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700171 pContext->state = EQUALIZER_STATE_INITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700172
Eric Laurentffe9c252010-06-23 17:38:20 -0700173 LOGV("EffectLibCreateEffect %p, size %d", pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext));
Eric Laurent135ad072010-05-21 06:05:13 -0700174
175 return 0;
176
177} /* end EffectCreate */
178
179extern "C" int EffectRelease(effect_interface_t interface) {
180 EqualizerContext * pContext = (EqualizerContext *)interface;
181
182 LOGV("EffectLibReleaseEffect %p", interface);
183 if (pContext == NULL) {
184 return -EINVAL;
185 }
186
Eric Laurente44b1ef2010-07-09 13:34:17 -0700187 pContext->state = EQUALIZER_STATE_UNINITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700188 pContext->pEqualizer->free();
189 delete pContext;
190
191 return 0;
192} /* end EffectRelease */
193
194
195//
196//--- local functions
197//
198
199#define CHECK_ARG(cond) { \
200 if (!(cond)) { \
201 LOGV("Invalid argument: "#cond); \
202 return -EINVAL; \
203 } \
204}
205
206//----------------------------------------------------------------------------
207// Equalizer_configure()
208//----------------------------------------------------------------------------
209// Purpose: Set input and output audio configuration.
210//
211// Inputs:
212// pContext: effect engine context
213// pConfig: pointer to effect_config_t structure holding input and output
214// configuration parameters
215//
216// Outputs:
217//
218//----------------------------------------------------------------------------
219
220int Equalizer_configure(EqualizerContext *pContext, effect_config_t *pConfig)
221{
222 LOGV("Equalizer_configure start");
223
224 CHECK_ARG(pContext != NULL);
225 CHECK_ARG(pConfig != NULL);
226
227 CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
228 CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
229 CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
230 CHECK_ARG((pConfig->inputCfg.channels == CHANNEL_MONO) || (pConfig->inputCfg.channels == CHANNEL_STEREO));
231 CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
232 || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
Eric Laurentffe9c252010-06-23 17:38:20 -0700233 CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S7_24
234 || pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15);
Eric Laurent135ad072010-05-21 06:05:13 -0700235
236 int channelCount;
237 if (pConfig->inputCfg.channels == CHANNEL_MONO) {
238 channelCount = 1;
239 } else {
240 channelCount = 2;
241 }
242 CHECK_ARG(channelCount <= AudioBiquadFilter::MAX_CHANNELS);
243
Eric Laurentffe9c252010-06-23 17:38:20 -0700244 memcpy(&pContext->config, pConfig, sizeof(effect_config_t));
245
Eric Laurent135ad072010-05-21 06:05:13 -0700246 pContext->pEqualizer->configure(channelCount,
247 pConfig->inputCfg.samplingRate);
248
249 pContext->adapter.configure(*pContext->pEqualizer, channelCount,
250 pConfig->inputCfg.format,
251 pConfig->outputCfg.accessMode);
252
253 return 0;
254} // end Equalizer_configure
255
256
257//----------------------------------------------------------------------------
258// Equalizer_init()
259//----------------------------------------------------------------------------
260// Purpose: Initialize engine with default configuration and creates
261// AudioEqualizer instance.
262//
263// Inputs:
264// pContext: effect engine context
265//
266// Outputs:
267//
268//----------------------------------------------------------------------------
269
270int Equalizer_init(EqualizerContext *pContext)
271{
272 int status;
273
274 LOGV("Equalizer_init start");
275
276 CHECK_ARG(pContext != NULL);
277
278 if (pContext->pEqualizer != NULL) {
279 pContext->pEqualizer->free();
280 }
281
282 pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
283 pContext->config.inputCfg.channels = CHANNEL_STEREO;
Eric Laurentffe9c252010-06-23 17:38:20 -0700284 pContext->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
Eric Laurent135ad072010-05-21 06:05:13 -0700285 pContext->config.inputCfg.samplingRate = 44100;
286 pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
287 pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
288 pContext->config.inputCfg.bufferProvider.cookie = NULL;
289 pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
290 pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
291 pContext->config.outputCfg.channels = CHANNEL_STEREO;
Eric Laurentffe9c252010-06-23 17:38:20 -0700292 pContext->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
Eric Laurent135ad072010-05-21 06:05:13 -0700293 pContext->config.outputCfg.samplingRate = 44100;
294 pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
295 pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
296 pContext->config.outputCfg.bufferProvider.cookie = NULL;
297 pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL;
298
299 pContext->pEqualizer = AudioEqualizer::CreateInstance(
300 NULL,
301 kNumBands,
302 AudioBiquadFilter::MAX_CHANNELS,
303 44100,
304 gEqualizerPresets,
305 ARRAY_SIZE(gEqualizerPresets));
306
307 for (int i = 0; i < kNumBands; ++i) {
308 pContext->pEqualizer->setFrequency(i, gFreqs[i]);
309 pContext->pEqualizer->setBandwidth(i, gBandwidths[i]);
310 }
311
312 pContext->pEqualizer->enable(true);
313
314 Equalizer_configure(pContext, &pContext->config);
315
316 return 0;
317} // end Equalizer_init
318
319
320//----------------------------------------------------------------------------
321// Equalizer_getParameter()
322//----------------------------------------------------------------------------
323// Purpose:
324// Get a Equalizer parameter
325//
326// Inputs:
327// pEqualizer - handle to instance data
328// pParam - pointer to parameter
329// pValue - pointer to variable to hold retrieved value
330// pValueSize - pointer to value size: maximum size as input
331//
332// Outputs:
333// *pValue updated with parameter value
334// *pValueSize updated with actual value size
335//
336//
337// Side Effects:
338//
339//----------------------------------------------------------------------------
340
341int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue)
342{
343 int status = 0;
344 int32_t param = *pParam++;
345 int32_t param2;
346 char *name;
347
348 switch (param) {
349 case EQ_PARAM_NUM_BANDS:
350 case EQ_PARAM_CUR_PRESET:
351 case EQ_PARAM_GET_NUM_OF_PRESETS:
352 if (*pValueSize < sizeof(int16_t)) {
353 return -EINVAL;
354 }
355 *pValueSize = sizeof(int16_t);
356 break;
357
358 case EQ_PARAM_LEVEL_RANGE:
359 case EQ_PARAM_BAND_FREQ_RANGE:
360 if (*pValueSize < 2 * sizeof(int32_t)) {
361 return -EINVAL;
362 }
363 *pValueSize = 2 * sizeof(int32_t);
364 break;
365 case EQ_PARAM_BAND_LEVEL:
366 case EQ_PARAM_GET_BAND:
367 case EQ_PARAM_CENTER_FREQ:
368 if (*pValueSize < sizeof(int32_t)) {
369 return -EINVAL;
370 }
371 *pValueSize = sizeof(int32_t);
372 break;
373
374 case EQ_PARAM_GET_PRESET_NAME:
375 break;
376
377 default:
378 return -EINVAL;
379 }
380
381 switch (param) {
382 case EQ_PARAM_NUM_BANDS:
383 *(int16_t *)pValue = kNumBands;
384 LOGV("Equalizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue);
385 break;
386
387 case EQ_PARAM_LEVEL_RANGE:
388 *(int32_t *)pValue = -9600;
389 *((int32_t *)pValue + 1) = 4800;
390 LOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d", *(int32_t *)pValue, *((int32_t *)pValue + 1));
391 break;
392
393 case EQ_PARAM_BAND_LEVEL:
394 param2 = *pParam;
395 if (param2 >= kNumBands) {
396 status = -EINVAL;
397 break;
398 }
399 *(int32_t *)pValue = pEqualizer->getGain(param2);
400 LOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", param2, *(int32_t *)pValue);
401 break;
402
403 case EQ_PARAM_CENTER_FREQ:
404 param2 = *pParam;
405 if (param2 >= kNumBands) {
406 status = -EINVAL;
407 break;
408 }
409 *(int32_t *)pValue = pEqualizer->getFrequency(param2);
410 LOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d", param2, *(int32_t *)pValue);
411 break;
412
413 case EQ_PARAM_BAND_FREQ_RANGE:
414 param2 = *pParam;
415 if (param2 >= kNumBands) {
416 status = -EINVAL;
417 break;
418 }
419 pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1));
420 LOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
421 break;
422
423 case EQ_PARAM_GET_BAND:
424 param2 = *pParam;
425 *(int32_t *)pValue = pEqualizer->getMostRelevantBand(param2);
426 LOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d", param2, *(int32_t *)pValue);
427 break;
428
429 case EQ_PARAM_CUR_PRESET:
430 *(int16_t *)pValue = pEqualizer->getPreset();
431 LOGV("Equalizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue);
432 break;
433
434 case EQ_PARAM_GET_NUM_OF_PRESETS:
435 *(int16_t *)pValue = pEqualizer->getNumPresets();
436 LOGV("Equalizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue);
437 break;
438
439 case EQ_PARAM_GET_PRESET_NAME:
440 param2 = *pParam;
441 if (param2 >= pEqualizer->getNumPresets()) {
442 status = -EINVAL;
443 break;
444 }
445 name = (char *)pValue;
446 strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1);
447 name[*pValueSize - 1] = 0;
448 *pValueSize = strlen(name) + 1;
449 LOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", param2, gEqualizerPresets[param2].name, *pValueSize);
450 break;
451
452 default:
453 LOGV("Equalizer_getParameter() invalid param %d", param);
454 status = -EINVAL;
455 break;
456 }
457
458 return status;
459} // end Equalizer_getParameter
460
461
462//----------------------------------------------------------------------------
463// Equalizer_setParameter()
464//----------------------------------------------------------------------------
465// Purpose:
466// Set a Equalizer parameter
467//
468// Inputs:
469// pEqualizer - handle to instance data
470// pParam - pointer to parameter
471// pValue - pointer to value
472//
473// Outputs:
474//
475//
476// Side Effects:
477//
478//----------------------------------------------------------------------------
479
480int Equalizer_setParameter (AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue)
481{
482 int status = 0;
483 int32_t preset;
484 int32_t band;
485 int32_t level;
486 int32_t param = *pParam++;
487
488
489 switch (param) {
490 case EQ_PARAM_CUR_PRESET:
491 preset = *(int16_t *)pValue;
492
493 LOGV("setParameter() EQ_PARAM_CUR_PRESET %d", preset);
494 if (preset >= pEqualizer->getNumPresets()) {
495 status = -EINVAL;
496 break;
497 }
498 pEqualizer->setPreset(preset);
499 pEqualizer->commit(true);
500 break;
501 case EQ_PARAM_BAND_LEVEL:
502 band = *pParam;
503 level = *(int32_t *)pValue;
504 LOGV("setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level);
505 if (band >= kNumBands) {
506 status = -EINVAL;
507 break;
508 }
509 pEqualizer->setGain(band, level);
510 pEqualizer->commit(true);
511 break;
512 default:
513 LOGV("setParameter() invalid param %d", param);
514 break;
515 }
516
517 return status;
518} // end Equalizer_setParameter
519
520} // namespace
521} // namespace
522
523
524//
525//--- Effect Control Interface Implementation
526//
527
528extern "C" int Equalizer_process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
529{
530 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
531
532 if (pContext == NULL) {
533 return -EINVAL;
534 }
535 if (inBuffer == NULL || inBuffer->raw == NULL ||
536 outBuffer == NULL || outBuffer->raw == NULL ||
537 inBuffer->frameCount != outBuffer->frameCount) {
538 return -EINVAL;
539 }
540
Eric Laurente44b1ef2010-07-09 13:34:17 -0700541 if (pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
542 return -EINVAL;
543 }
544 if (pContext->state == EQUALIZER_STATE_INITIALIZED) {
545 return -ENODATA;
546 }
547
Eric Laurent135ad072010-05-21 06:05:13 -0700548 pContext->adapter.process(inBuffer->raw, outBuffer->raw, outBuffer->frameCount);
Eric Laurentffe9c252010-06-23 17:38:20 -0700549
Eric Laurent135ad072010-05-21 06:05:13 -0700550 return 0;
551} // end Equalizer_process
552
553extern "C" int Equalizer_command(effect_interface_t self, int cmdCode, int cmdSize,
554 void *pCmdData, int *replySize, void *pReplyData) {
555
556 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
557 int retsize;
558
Eric Laurente44b1ef2010-07-09 13:34:17 -0700559 if (pContext == NULL || pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
Eric Laurent135ad072010-05-21 06:05:13 -0700560 return -EINVAL;
561 }
562
563 android::AudioEqualizer * pEqualizer = pContext->pEqualizer;
564
565 LOGV("Equalizer_command command %d cmdSize %d",cmdCode, cmdSize);
566
567 switch (cmdCode) {
568 case EFFECT_CMD_INIT:
569 if (pReplyData == NULL || *replySize != sizeof(int)) {
570 return -EINVAL;
571 }
572 *(int *) pReplyData = Equalizer_init(pContext);
573 break;
574 case EFFECT_CMD_CONFIGURE:
575 if (pCmdData == NULL || cmdSize != sizeof(effect_config_t)
576 || pReplyData == NULL || *replySize != sizeof(int)) {
577 return -EINVAL;
578 }
579 *(int *) pReplyData = Equalizer_configure(pContext,
580 (effect_config_t *) pCmdData);
581 break;
582 case EFFECT_CMD_RESET:
583 Equalizer_configure(pContext, &pContext->config);
584 break;
585 case EFFECT_CMD_GET_PARAM: {
586 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
587 pReplyData == NULL || *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))) {
588 return -EINVAL;
589 }
590 effect_param_t *p = (effect_param_t *)pCmdData;
591 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
592 p = (effect_param_t *)pReplyData;
593 int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
594 p->status = android::Equalizer_getParameter(pEqualizer, (int32_t *)p->data, &p->vsize,
595 p->data + voffset);
596 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
597 LOGV("Equalizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x",
598 *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize,
599 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset),
600 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset + sizeof(int32_t)));
601
602 } break;
603 case EFFECT_CMD_SET_PARAM: {
604 LOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData);
605 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
606 pReplyData == NULL || *replySize != sizeof(int32_t)) {
607 return -EINVAL;
608 }
609 effect_param_t *p = (effect_param_t *) pCmdData;
610 *(int *)pReplyData = android::Equalizer_setParameter(pEqualizer, (int32_t *)p->data,
611 p->data + p->psize);
612 } break;
Eric Laurentffe9c252010-06-23 17:38:20 -0700613 case EFFECT_CMD_ENABLE:
Eric Laurente44b1ef2010-07-09 13:34:17 -0700614 if (pReplyData == NULL || *replySize != sizeof(int)) {
615 return -EINVAL;
616 }
617 if (pContext->state != EQUALIZER_STATE_INITIALIZED) {
618 return -ENOSYS;
619 }
620 pContext->state = EQUALIZER_STATE_ACTIVE;
621 LOGV("EFFECT_CMD_ENABLE() OK");
622 *(int *)pReplyData = 0;
623 break;
Eric Laurentffe9c252010-06-23 17:38:20 -0700624 case EFFECT_CMD_DISABLE:
625 if (pReplyData == NULL || *replySize != sizeof(int)) {
626 return -EINVAL;
627 }
Eric Laurente44b1ef2010-07-09 13:34:17 -0700628 if (pContext->state != EQUALIZER_STATE_ACTIVE) {
629 return -ENOSYS;
630 }
631 pContext->state = EQUALIZER_STATE_INITIALIZED;
632 LOGV("EFFECT_CMD_DISABLE() OK");
Eric Laurentffe9c252010-06-23 17:38:20 -0700633 *(int *)pReplyData = 0;
634 break;
635 case EFFECT_CMD_SET_DEVICE:
636 case EFFECT_CMD_SET_VOLUME:
637 case EFFECT_CMD_SET_AUDIO_MODE:
638 break;
Eric Laurent135ad072010-05-21 06:05:13 -0700639 default:
640 LOGW("Equalizer_command invalid command %d",cmdCode);
641 return -EINVAL;
642 }
643
644 return 0;
645}
646
647// effect_interface_t interface implementation for equalizer effect
648const struct effect_interface_s gEqualizerInterface = {
649 Equalizer_process,
650 Equalizer_command
651};
652
653