blob: f8e4357847464468ea0237b33b85195b894e73f7 [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])
Eric Laurent2c8e5ca2010-07-09 12:28:50 -070019//
20#define LOG_NDEBUG 0
Eric Laurent135ad072010-05-21 06:05:13 -070021#include <cutils/log.h>
22#include <assert.h>
23#include <stdlib.h>
Eric Laurent17217ab2010-05-25 12:38:34 -070024#include <string.h>
Eric Laurent135ad072010-05-21 06:05:13 -070025#include <new>
26#include "AudioEqualizer.h"
27#include "AudioBiquadFilter.h"
28#include "AudioFormatAdapter.h"
29#include <media/EffectEqualizerApi.h>
30
31// effect_interface_t interface implementation for equalizer effect
32extern "C" const struct effect_interface_s gEqualizerInterface;
33
Eric Laurente44b1ef2010-07-09 13:34:17 -070034enum equalizer_state_e {
35 EQUALIZER_STATE_UNINITIALIZED,
36 EQUALIZER_STATE_INITIALIZED,
37 EQUALIZER_STATE_ACTIVE,
38};
39
Eric Laurent135ad072010-05-21 06:05:13 -070040namespace android {
41namespace {
42
43// Google Graphic Equalizer UUID: e25aa840-543b-11df-98a5-0002a5d5c51b
44const effect_descriptor_t gEqualizerDescriptor = {
45 {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
46 {0xe25aa840, 0x543b, 0x11df, 0x98a5, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
47 EFFECT_API_VERSION,
48 (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
Eric Laurentffe9c252010-06-23 17:38:20 -070049 0, // TODO
50 1,
Eric Laurent135ad072010-05-21 06:05:13 -070051 "Graphic Equalizer",
52 "Google Inc.",
53};
Eric Laurent135ad072010-05-21 06:05:13 -070054
55/////////////////// BEGIN EQ PRESETS ///////////////////////////////////////////
56const int kNumBands = 5;
57const uint32_t gFreqs[kNumBands] = { 50000, 125000, 900000, 3200000, 6300000 };
58const uint32_t gBandwidths[kNumBands] = { 0, 3600, 3600, 2400, 0 };
59
60const AudioEqualizer::BandConfig gBandsClassic[kNumBands] = {
61 { 300, gFreqs[0], gBandwidths[0] },
62 { 400, gFreqs[1], gBandwidths[1] },
63 { 0, gFreqs[2], gBandwidths[2] },
64 { 200, gFreqs[3], gBandwidths[3] },
65 { -300, gFreqs[4], gBandwidths[4] }
66};
67
68const AudioEqualizer::BandConfig gBandsJazz[kNumBands] = {
69 { -600, gFreqs[0], gBandwidths[0] },
70 { 200, gFreqs[1], gBandwidths[1] },
71 { 400, gFreqs[2], gBandwidths[2] },
72 { -400, gFreqs[3], gBandwidths[3] },
73 { -600, gFreqs[4], gBandwidths[4] }
74};
75
76const AudioEqualizer::BandConfig gBandsPop[kNumBands] = {
77 { 400, gFreqs[0], gBandwidths[0] },
78 { -400, gFreqs[1], gBandwidths[1] },
79 { 300, gFreqs[2], gBandwidths[2] },
80 { -400, gFreqs[3], gBandwidths[3] },
81 { 600, gFreqs[4], gBandwidths[4] }
82};
83
84const AudioEqualizer::BandConfig gBandsRock[kNumBands] = {
85 { 700, gFreqs[0], gBandwidths[0] },
86 { 400, gFreqs[1], gBandwidths[1] },
87 { -400, gFreqs[2], gBandwidths[2] },
88 { 400, gFreqs[3], gBandwidths[3] },
89 { 200, gFreqs[4], gBandwidths[4] }
90};
91
92const AudioEqualizer::PresetConfig gEqualizerPresets[] = {
93 { "Classic", gBandsClassic },
94 { "Jazz", gBandsJazz },
95 { "Pop", gBandsPop },
96 { "Rock", gBandsRock }
97};
98
99/////////////////// END EQ PRESETS /////////////////////////////////////////////
100
101static const size_t kBufferSize = 32;
102
103typedef AudioFormatAdapter<AudioEqualizer, kBufferSize> FormatAdapter;
104
105struct EqualizerContext {
106 const struct effect_interface_s *itfe;
107 effect_config_t config;
108 FormatAdapter adapter;
109 AudioEqualizer * pEqualizer;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700110 uint32_t state;
Eric Laurent135ad072010-05-21 06:05:13 -0700111};
112
Eric Laurent135ad072010-05-21 06:05:13 -0700113//--- local function prototypes
114
115int Equalizer_init(EqualizerContext *pContext);
116int Equalizer_configure(EqualizerContext *pContext, effect_config_t *pConfig);
117int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue);
118int Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue);
119
120
121//
122//--- Effect Library Interface Implementation
123//
124
Eric Laurentbe916aa2010-06-01 23:49:17 -0700125extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects) {
Eric Laurent135ad072010-05-21 06:05:13 -0700126 *pNumEffects = 1;
Eric Laurent135ad072010-05-21 06:05:13 -0700127 return 0;
128} /* end EffectQueryNumberEffects */
129
Eric Laurentffe9c252010-06-23 17:38:20 -0700130extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) {
Eric Laurent135ad072010-05-21 06:05:13 -0700131 if (pDescriptor == NULL) {
132 return -EINVAL;
133 }
Eric Laurentffe9c252010-06-23 17:38:20 -0700134 if (index > 0) {
135 return -EINVAL;
Eric Laurent135ad072010-05-21 06:05:13 -0700136 }
137 memcpy(pDescriptor, &gEqualizerDescriptor, sizeof(effect_descriptor_t));
138 return 0;
139} /* end EffectQueryNext */
140
141extern "C" int EffectCreate(effect_uuid_t *uuid,
Eric Laurentffe9c252010-06-23 17:38:20 -0700142 int32_t sessionId,
143 int32_t ioId,
Eric Laurent135ad072010-05-21 06:05:13 -0700144 effect_interface_t *pInterface) {
145 int ret;
146 int i;
147
148 LOGV("EffectLibCreateEffect start");
149
150 if (pInterface == NULL || uuid == NULL) {
151 return -EINVAL;
152 }
153
154 if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) != 0) {
155 return -EINVAL;
156 }
157
158 EqualizerContext *pContext = new EqualizerContext;
159
160 pContext->itfe = &gEqualizerInterface;
161 pContext->pEqualizer = NULL;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700162 pContext->state = EQUALIZER_STATE_UNINITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700163
164 ret = Equalizer_init(pContext);
165 if (ret < 0) {
166 LOGW("EffectLibCreateEffect() init failed");
167 delete pContext;
168 return ret;
169 }
170
171 *pInterface = (effect_interface_t)pContext;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700172 pContext->state = EQUALIZER_STATE_INITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700173
Eric Laurentffe9c252010-06-23 17:38:20 -0700174 LOGV("EffectLibCreateEffect %p, size %d", pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext));
Eric Laurent135ad072010-05-21 06:05:13 -0700175
176 return 0;
177
178} /* end EffectCreate */
179
180extern "C" int EffectRelease(effect_interface_t interface) {
181 EqualizerContext * pContext = (EqualizerContext *)interface;
182
183 LOGV("EffectLibReleaseEffect %p", interface);
184 if (pContext == NULL) {
185 return -EINVAL;
186 }
187
Eric Laurente44b1ef2010-07-09 13:34:17 -0700188 pContext->state = EQUALIZER_STATE_UNINITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700189 pContext->pEqualizer->free();
190 delete pContext;
191
192 return 0;
193} /* end EffectRelease */
194
195
196//
197//--- local functions
198//
199
200#define CHECK_ARG(cond) { \
201 if (!(cond)) { \
202 LOGV("Invalid argument: "#cond); \
203 return -EINVAL; \
204 } \
205}
206
207//----------------------------------------------------------------------------
208// Equalizer_configure()
209//----------------------------------------------------------------------------
210// Purpose: Set input and output audio configuration.
211//
212// Inputs:
213// pContext: effect engine context
214// pConfig: pointer to effect_config_t structure holding input and output
215// configuration parameters
216//
217// Outputs:
218//
219//----------------------------------------------------------------------------
220
221int Equalizer_configure(EqualizerContext *pContext, effect_config_t *pConfig)
222{
223 LOGV("Equalizer_configure start");
224
225 CHECK_ARG(pContext != NULL);
226 CHECK_ARG(pConfig != NULL);
227
228 CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
229 CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
230 CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
231 CHECK_ARG((pConfig->inputCfg.channels == CHANNEL_MONO) || (pConfig->inputCfg.channels == CHANNEL_STEREO));
232 CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
233 || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
Eric Laurentffe9c252010-06-23 17:38:20 -0700234 CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S7_24
235 || pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15);
Eric Laurent135ad072010-05-21 06:05:13 -0700236
237 int channelCount;
238 if (pConfig->inputCfg.channels == CHANNEL_MONO) {
239 channelCount = 1;
240 } else {
241 channelCount = 2;
242 }
243 CHECK_ARG(channelCount <= AudioBiquadFilter::MAX_CHANNELS);
244
Eric Laurentffe9c252010-06-23 17:38:20 -0700245 memcpy(&pContext->config, pConfig, sizeof(effect_config_t));
246
Eric Laurent135ad072010-05-21 06:05:13 -0700247 pContext->pEqualizer->configure(channelCount,
248 pConfig->inputCfg.samplingRate);
249
250 pContext->adapter.configure(*pContext->pEqualizer, channelCount,
251 pConfig->inputCfg.format,
252 pConfig->outputCfg.accessMode);
253
254 return 0;
255} // end Equalizer_configure
256
257
258//----------------------------------------------------------------------------
259// Equalizer_init()
260//----------------------------------------------------------------------------
261// Purpose: Initialize engine with default configuration and creates
262// AudioEqualizer instance.
263//
264// Inputs:
265// pContext: effect engine context
266//
267// Outputs:
268//
269//----------------------------------------------------------------------------
270
271int Equalizer_init(EqualizerContext *pContext)
272{
273 int status;
274
275 LOGV("Equalizer_init start");
276
277 CHECK_ARG(pContext != NULL);
278
279 if (pContext->pEqualizer != NULL) {
280 pContext->pEqualizer->free();
281 }
282
283 pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
284 pContext->config.inputCfg.channels = CHANNEL_STEREO;
Eric Laurentffe9c252010-06-23 17:38:20 -0700285 pContext->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
Eric Laurent135ad072010-05-21 06:05:13 -0700286 pContext->config.inputCfg.samplingRate = 44100;
287 pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
288 pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
289 pContext->config.inputCfg.bufferProvider.cookie = NULL;
290 pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
291 pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
292 pContext->config.outputCfg.channels = CHANNEL_STEREO;
Eric Laurentffe9c252010-06-23 17:38:20 -0700293 pContext->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15;
Eric Laurent135ad072010-05-21 06:05:13 -0700294 pContext->config.outputCfg.samplingRate = 44100;
295 pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
296 pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
297 pContext->config.outputCfg.bufferProvider.cookie = NULL;
298 pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL;
299
300 pContext->pEqualizer = AudioEqualizer::CreateInstance(
301 NULL,
302 kNumBands,
303 AudioBiquadFilter::MAX_CHANNELS,
304 44100,
305 gEqualizerPresets,
306 ARRAY_SIZE(gEqualizerPresets));
307
308 for (int i = 0; i < kNumBands; ++i) {
309 pContext->pEqualizer->setFrequency(i, gFreqs[i]);
310 pContext->pEqualizer->setBandwidth(i, gBandwidths[i]);
311 }
312
313 pContext->pEqualizer->enable(true);
314
315 Equalizer_configure(pContext, &pContext->config);
316
317 return 0;
318} // end Equalizer_init
319
320
321//----------------------------------------------------------------------------
322// Equalizer_getParameter()
323//----------------------------------------------------------------------------
324// Purpose:
325// Get a Equalizer parameter
326//
327// Inputs:
328// pEqualizer - handle to instance data
329// pParam - pointer to parameter
330// pValue - pointer to variable to hold retrieved value
331// pValueSize - pointer to value size: maximum size as input
332//
333// Outputs:
334// *pValue updated with parameter value
335// *pValueSize updated with actual value size
336//
337//
338// Side Effects:
339//
340//----------------------------------------------------------------------------
341
342int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue)
343{
344 int status = 0;
345 int32_t param = *pParam++;
346 int32_t param2;
347 char *name;
348
349 switch (param) {
350 case EQ_PARAM_NUM_BANDS:
351 case EQ_PARAM_CUR_PRESET:
352 case EQ_PARAM_GET_NUM_OF_PRESETS:
Eric Laurent3be95232010-07-30 09:12:51 -0700353 case EQ_PARAM_BAND_LEVEL:
354 case EQ_PARAM_GET_BAND:
Eric Laurent135ad072010-05-21 06:05:13 -0700355 if (*pValueSize < sizeof(int16_t)) {
356 return -EINVAL;
357 }
358 *pValueSize = sizeof(int16_t);
359 break;
360
361 case EQ_PARAM_LEVEL_RANGE:
Eric Laurent3be95232010-07-30 09:12:51 -0700362 if (*pValueSize < 2 * sizeof(int16_t)) {
363 return -EINVAL;
364 }
365 *pValueSize = 2 * sizeof(int16_t);
366 break;
367
Eric Laurent135ad072010-05-21 06:05:13 -0700368 case EQ_PARAM_BAND_FREQ_RANGE:
369 if (*pValueSize < 2 * sizeof(int32_t)) {
370 return -EINVAL;
371 }
372 *pValueSize = 2 * sizeof(int32_t);
373 break;
Eric Laurent3be95232010-07-30 09:12:51 -0700374
Eric Laurent135ad072010-05-21 06:05:13 -0700375 case EQ_PARAM_CENTER_FREQ:
376 if (*pValueSize < sizeof(int32_t)) {
377 return -EINVAL;
378 }
379 *pValueSize = sizeof(int32_t);
380 break;
381
382 case EQ_PARAM_GET_PRESET_NAME:
383 break;
384
Eric Laurent3be95232010-07-30 09:12:51 -0700385 case EQ_PARAM_PROPERTIES:
386 if (*pValueSize < (2 + kNumBands) * sizeof(uint16_t)) {
387 return -EINVAL;
388 }
389 *pValueSize = (2 + kNumBands) * sizeof(uint16_t);
390 break;
391
Eric Laurent135ad072010-05-21 06:05:13 -0700392 default:
393 return -EINVAL;
394 }
395
396 switch (param) {
397 case EQ_PARAM_NUM_BANDS:
Eric Laurent3be95232010-07-30 09:12:51 -0700398 *(uint16_t *)pValue = (uint16_t)kNumBands;
Eric Laurent135ad072010-05-21 06:05:13 -0700399 LOGV("Equalizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue);
400 break;
401
402 case EQ_PARAM_LEVEL_RANGE:
Eric Laurent3be95232010-07-30 09:12:51 -0700403 *(int16_t *)pValue = -9600;
404 *((int16_t *)pValue + 1) = 4800;
Eric Laurent135ad072010-05-21 06:05:13 -0700405 LOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d", *(int32_t *)pValue, *((int32_t *)pValue + 1));
406 break;
407
408 case EQ_PARAM_BAND_LEVEL:
409 param2 = *pParam;
410 if (param2 >= kNumBands) {
411 status = -EINVAL;
412 break;
413 }
Eric Laurent3be95232010-07-30 09:12:51 -0700414 *(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2);
Eric Laurent135ad072010-05-21 06:05:13 -0700415 LOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", param2, *(int32_t *)pValue);
416 break;
417
418 case EQ_PARAM_CENTER_FREQ:
419 param2 = *pParam;
420 if (param2 >= kNumBands) {
421 status = -EINVAL;
422 break;
423 }
424 *(int32_t *)pValue = pEqualizer->getFrequency(param2);
425 LOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d", param2, *(int32_t *)pValue);
426 break;
427
428 case EQ_PARAM_BAND_FREQ_RANGE:
429 param2 = *pParam;
430 if (param2 >= kNumBands) {
431 status = -EINVAL;
432 break;
433 }
434 pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1));
435 LOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
436 break;
437
438 case EQ_PARAM_GET_BAND:
439 param2 = *pParam;
Eric Laurent3be95232010-07-30 09:12:51 -0700440 *(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2);
Eric Laurent135ad072010-05-21 06:05:13 -0700441 LOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d", param2, *(int32_t *)pValue);
442 break;
443
444 case EQ_PARAM_CUR_PRESET:
Eric Laurent3be95232010-07-30 09:12:51 -0700445 *(uint16_t *)pValue = (uint16_t)pEqualizer->getPreset();
Eric Laurent135ad072010-05-21 06:05:13 -0700446 LOGV("Equalizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue);
447 break;
448
449 case EQ_PARAM_GET_NUM_OF_PRESETS:
Eric Laurent3be95232010-07-30 09:12:51 -0700450 *(uint16_t *)pValue = (uint16_t)pEqualizer->getNumPresets();
Eric Laurent135ad072010-05-21 06:05:13 -0700451 LOGV("Equalizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue);
452 break;
453
454 case EQ_PARAM_GET_PRESET_NAME:
455 param2 = *pParam;
456 if (param2 >= pEqualizer->getNumPresets()) {
457 status = -EINVAL;
458 break;
459 }
460 name = (char *)pValue;
461 strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1);
462 name[*pValueSize - 1] = 0;
463 *pValueSize = strlen(name) + 1;
464 LOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", param2, gEqualizerPresets[param2].name, *pValueSize);
465 break;
466
Eric Laurent3be95232010-07-30 09:12:51 -0700467 case EQ_PARAM_PROPERTIES: {
468 int16_t *p = (int16_t *)pValue;
469 LOGV("Equalizer_getParameter() EQ_PARAM_PROPERTIES");
470 p[0] = (int16_t)pEqualizer->getPreset();
471 p[1] = (int16_t)kNumBands;
472 for (int i = 0; i < kNumBands; i++) {
473 p[2 + i] = (int16_t)pEqualizer->getGain(i);
474 }
475 } break;
476
Eric Laurent135ad072010-05-21 06:05:13 -0700477 default:
478 LOGV("Equalizer_getParameter() invalid param %d", param);
479 status = -EINVAL;
480 break;
481 }
482
483 return status;
484} // end Equalizer_getParameter
485
486
487//----------------------------------------------------------------------------
488// Equalizer_setParameter()
489//----------------------------------------------------------------------------
490// Purpose:
491// Set a Equalizer parameter
492//
493// Inputs:
494// pEqualizer - handle to instance data
495// pParam - pointer to parameter
496// pValue - pointer to value
497//
498// Outputs:
499//
500//
501// Side Effects:
502//
503//----------------------------------------------------------------------------
504
505int Equalizer_setParameter (AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue)
506{
507 int status = 0;
508 int32_t preset;
509 int32_t band;
510 int32_t level;
511 int32_t param = *pParam++;
512
513
514 switch (param) {
515 case EQ_PARAM_CUR_PRESET:
Eric Laurent3be95232010-07-30 09:12:51 -0700516 preset = (int32_t)(*(uint16_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700517
518 LOGV("setParameter() EQ_PARAM_CUR_PRESET %d", preset);
Eric Laurent3be95232010-07-30 09:12:51 -0700519 if (preset < 0 || preset >= pEqualizer->getNumPresets()) {
Eric Laurent135ad072010-05-21 06:05:13 -0700520 status = -EINVAL;
521 break;
522 }
523 pEqualizer->setPreset(preset);
524 pEqualizer->commit(true);
525 break;
526 case EQ_PARAM_BAND_LEVEL:
527 band = *pParam;
Eric Laurent3be95232010-07-30 09:12:51 -0700528 level = (int32_t)(*(int16_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700529 LOGV("setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level);
530 if (band >= kNumBands) {
531 status = -EINVAL;
532 break;
533 }
534 pEqualizer->setGain(band, level);
535 pEqualizer->commit(true);
536 break;
Eric Laurent3be95232010-07-30 09:12:51 -0700537 case EQ_PARAM_PROPERTIES: {
538 LOGV("setParameter() EQ_PARAM_PROPERTIES");
539 int16_t *p = (int16_t *)pValue;
540 if ((int)p[0] >= pEqualizer->getNumPresets()) {
541 status = -EINVAL;
542 break;
543 }
544 if (p[0] >= 0) {
545 pEqualizer->setPreset((int)p[0]);
546 } else {
547 if ((int)p[1] != kNumBands) {
548 status = -EINVAL;
549 break;
550 }
551 for (int i = 0; i < kNumBands; i++) {
552 pEqualizer->setGain(i, (int32_t)p[2 + i]);
553 }
554 }
555 pEqualizer->commit(true);
556 } break;
Eric Laurent135ad072010-05-21 06:05:13 -0700557 default:
558 LOGV("setParameter() invalid param %d", param);
Eric Laurent3be95232010-07-30 09:12:51 -0700559 status = -EINVAL;
Eric Laurent135ad072010-05-21 06:05:13 -0700560 break;
561 }
562
563 return status;
564} // end Equalizer_setParameter
565
566} // namespace
567} // namespace
568
569
570//
571//--- Effect Control Interface Implementation
572//
573
574extern "C" int Equalizer_process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
575{
576 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
577
578 if (pContext == NULL) {
579 return -EINVAL;
580 }
581 if (inBuffer == NULL || inBuffer->raw == NULL ||
582 outBuffer == NULL || outBuffer->raw == NULL ||
583 inBuffer->frameCount != outBuffer->frameCount) {
584 return -EINVAL;
585 }
586
Eric Laurente44b1ef2010-07-09 13:34:17 -0700587 if (pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
588 return -EINVAL;
589 }
590 if (pContext->state == EQUALIZER_STATE_INITIALIZED) {
591 return -ENODATA;
592 }
593
Eric Laurent135ad072010-05-21 06:05:13 -0700594 pContext->adapter.process(inBuffer->raw, outBuffer->raw, outBuffer->frameCount);
Eric Laurentffe9c252010-06-23 17:38:20 -0700595
Eric Laurent135ad072010-05-21 06:05:13 -0700596 return 0;
597} // end Equalizer_process
598
Eric Laurent25f43952010-07-28 05:40:18 -0700599extern "C" int Equalizer_command(effect_interface_t self, uint32_t cmdCode, uint32_t cmdSize,
600 void *pCmdData, uint32_t *replySize, void *pReplyData) {
Eric Laurent135ad072010-05-21 06:05:13 -0700601
602 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
603 int retsize;
604
Eric Laurente44b1ef2010-07-09 13:34:17 -0700605 if (pContext == NULL || pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
Eric Laurent135ad072010-05-21 06:05:13 -0700606 return -EINVAL;
607 }
608
609 android::AudioEqualizer * pEqualizer = pContext->pEqualizer;
610
611 LOGV("Equalizer_command command %d cmdSize %d",cmdCode, cmdSize);
612
613 switch (cmdCode) {
614 case EFFECT_CMD_INIT:
615 if (pReplyData == NULL || *replySize != sizeof(int)) {
616 return -EINVAL;
617 }
618 *(int *) pReplyData = Equalizer_init(pContext);
619 break;
620 case EFFECT_CMD_CONFIGURE:
621 if (pCmdData == NULL || cmdSize != sizeof(effect_config_t)
622 || pReplyData == NULL || *replySize != sizeof(int)) {
623 return -EINVAL;
624 }
625 *(int *) pReplyData = Equalizer_configure(pContext,
626 (effect_config_t *) pCmdData);
627 break;
628 case EFFECT_CMD_RESET:
629 Equalizer_configure(pContext, &pContext->config);
630 break;
631 case EFFECT_CMD_GET_PARAM: {
632 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
633 pReplyData == NULL || *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))) {
634 return -EINVAL;
635 }
636 effect_param_t *p = (effect_param_t *)pCmdData;
637 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
638 p = (effect_param_t *)pReplyData;
639 int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
640 p->status = android::Equalizer_getParameter(pEqualizer, (int32_t *)p->data, &p->vsize,
641 p->data + voffset);
642 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
643 LOGV("Equalizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x",
644 *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize,
645 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset),
646 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset + sizeof(int32_t)));
647
648 } break;
649 case EFFECT_CMD_SET_PARAM: {
650 LOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData);
651 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
652 pReplyData == NULL || *replySize != sizeof(int32_t)) {
653 return -EINVAL;
654 }
655 effect_param_t *p = (effect_param_t *) pCmdData;
656 *(int *)pReplyData = android::Equalizer_setParameter(pEqualizer, (int32_t *)p->data,
657 p->data + p->psize);
658 } break;
Eric Laurentffe9c252010-06-23 17:38:20 -0700659 case EFFECT_CMD_ENABLE:
Eric Laurente44b1ef2010-07-09 13:34:17 -0700660 if (pReplyData == NULL || *replySize != sizeof(int)) {
661 return -EINVAL;
662 }
663 if (pContext->state != EQUALIZER_STATE_INITIALIZED) {
664 return -ENOSYS;
665 }
666 pContext->state = EQUALIZER_STATE_ACTIVE;
667 LOGV("EFFECT_CMD_ENABLE() OK");
668 *(int *)pReplyData = 0;
669 break;
Eric Laurentffe9c252010-06-23 17:38:20 -0700670 case EFFECT_CMD_DISABLE:
671 if (pReplyData == NULL || *replySize != sizeof(int)) {
672 return -EINVAL;
673 }
Eric Laurente44b1ef2010-07-09 13:34:17 -0700674 if (pContext->state != EQUALIZER_STATE_ACTIVE) {
675 return -ENOSYS;
676 }
677 pContext->state = EQUALIZER_STATE_INITIALIZED;
678 LOGV("EFFECT_CMD_DISABLE() OK");
Eric Laurentffe9c252010-06-23 17:38:20 -0700679 *(int *)pReplyData = 0;
680 break;
681 case EFFECT_CMD_SET_DEVICE:
682 case EFFECT_CMD_SET_VOLUME:
683 case EFFECT_CMD_SET_AUDIO_MODE:
684 break;
Eric Laurent135ad072010-05-21 06:05:13 -0700685 default:
686 LOGW("Equalizer_command invalid command %d",cmdCode);
687 return -EINVAL;
688 }
689
690 return 0;
691}
692
693// effect_interface_t interface implementation for equalizer effect
694const struct effect_interface_s gEqualizerInterface = {
695 Equalizer_process,
696 Equalizer_command
697};
698
699