blob: 43dfa82ef4c5ad447e41df114d992cdfe77673bc [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
Eric Laurente1315cf2011-05-17 19:16:02 -070031// effect_handle_t interface implementation for equalizer effect
Eric Laurent135ad072010-05-21 06:05:13 -070032extern "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
Eric Laurente1315cf2011-05-17 19:16:02 -070047 EFFECT_CONTROL_API_VERSION,
Eric Laurent135ad072010-05-21 06:05:13 -070048 (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",
Eric Laurente1315cf2011-05-17 19:16:02 -070052 "The Android Open Source Project",
Eric Laurent135ad072010-05-21 06:05:13 -070053};
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 Laurente1315cf2011-05-17 19:16:02 -0700130extern "C" int EffectQueryEffect(uint32_t index,
131 effect_descriptor_t *pDescriptor) {
Eric Laurent135ad072010-05-21 06:05:13 -0700132 if (pDescriptor == NULL) {
133 return -EINVAL;
134 }
Eric Laurentffe9c252010-06-23 17:38:20 -0700135 if (index > 0) {
136 return -EINVAL;
Eric Laurent135ad072010-05-21 06:05:13 -0700137 }
138 memcpy(pDescriptor, &gEqualizerDescriptor, sizeof(effect_descriptor_t));
139 return 0;
140} /* end EffectQueryNext */
141
142extern "C" int EffectCreate(effect_uuid_t *uuid,
Eric Laurente1315cf2011-05-17 19:16:02 -0700143 int32_t sessionId,
144 int32_t ioId,
145 effect_handle_t *pHandle) {
Eric Laurent135ad072010-05-21 06:05:13 -0700146 int ret;
147 int i;
148
149 LOGV("EffectLibCreateEffect start");
150
Eric Laurente1315cf2011-05-17 19:16:02 -0700151 if (pHandle == NULL || uuid == NULL) {
Eric Laurent135ad072010-05-21 06:05:13 -0700152 return -EINVAL;
153 }
154
155 if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) != 0) {
156 return -EINVAL;
157 }
158
159 EqualizerContext *pContext = new EqualizerContext;
160
161 pContext->itfe = &gEqualizerInterface;
162 pContext->pEqualizer = NULL;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700163 pContext->state = EQUALIZER_STATE_UNINITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700164
165 ret = Equalizer_init(pContext);
166 if (ret < 0) {
167 LOGW("EffectLibCreateEffect() init failed");
168 delete pContext;
169 return ret;
170 }
171
Eric Laurente1315cf2011-05-17 19:16:02 -0700172 *pHandle = (effect_handle_t)pContext;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700173 pContext->state = EQUALIZER_STATE_INITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700174
Eric Laurente1315cf2011-05-17 19:16:02 -0700175 LOGV("EffectLibCreateEffect %p, size %d",
176 pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext));
Eric Laurent135ad072010-05-21 06:05:13 -0700177
178 return 0;
179
180} /* end EffectCreate */
181
Eric Laurente1315cf2011-05-17 19:16:02 -0700182extern "C" int EffectRelease(effect_handle_t handle) {
183 EqualizerContext * pContext = (EqualizerContext *)handle;
Eric Laurent135ad072010-05-21 06:05:13 -0700184
Eric Laurente1315cf2011-05-17 19:16:02 -0700185 LOGV("EffectLibReleaseEffect %p", handle);
Eric Laurent135ad072010-05-21 06:05:13 -0700186 if (pContext == NULL) {
187 return -EINVAL;
188 }
189
Eric Laurente44b1ef2010-07-09 13:34:17 -0700190 pContext->state = EQUALIZER_STATE_UNINITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700191 pContext->pEqualizer->free();
192 delete pContext;
193
194 return 0;
195} /* end EffectRelease */
196
Eric Laurente1315cf2011-05-17 19:16:02 -0700197extern "C" int EffectGetDescriptor(effect_uuid_t *uuid,
198 effect_descriptor_t *pDescriptor) {
199
200 if (pDescriptor == NULL || uuid == NULL){
201 LOGV("EffectGetDescriptor() called with NULL pointer");
202 return -EINVAL;
203 }
204
205 if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
206 memcpy(pDescriptor, &gEqualizerDescriptor, sizeof(effect_descriptor_t));
207 return 0;
208 }
209
210 return -EINVAL;
211} /* end EffectGetDescriptor */
212
Eric Laurent135ad072010-05-21 06:05:13 -0700213
214//
215//--- local functions
216//
217
218#define CHECK_ARG(cond) { \
219 if (!(cond)) { \
220 LOGV("Invalid argument: "#cond); \
221 return -EINVAL; \
222 } \
223}
224
225//----------------------------------------------------------------------------
226// Equalizer_configure()
227//----------------------------------------------------------------------------
228// Purpose: Set input and output audio configuration.
229//
230// Inputs:
231// pContext: effect engine context
232// pConfig: pointer to effect_config_t structure holding input and output
233// configuration parameters
234//
235// Outputs:
236//
237//----------------------------------------------------------------------------
238
239int Equalizer_configure(EqualizerContext *pContext, effect_config_t *pConfig)
240{
241 LOGV("Equalizer_configure start");
242
243 CHECK_ARG(pContext != NULL);
244 CHECK_ARG(pConfig != NULL);
245
246 CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
247 CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
248 CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
Eric Laurente1315cf2011-05-17 19:16:02 -0700249 CHECK_ARG((pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) ||
250 (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO));
Eric Laurent135ad072010-05-21 06:05:13 -0700251 CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
252 || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
Eric Laurente1315cf2011-05-17 19:16:02 -0700253 CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_8_24_BIT
254 || pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT);
Eric Laurent135ad072010-05-21 06:05:13 -0700255
256 int channelCount;
Eric Laurente1315cf2011-05-17 19:16:02 -0700257 if (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) {
Eric Laurent135ad072010-05-21 06:05:13 -0700258 channelCount = 1;
259 } else {
260 channelCount = 2;
261 }
262 CHECK_ARG(channelCount <= AudioBiquadFilter::MAX_CHANNELS);
263
Eric Laurentffe9c252010-06-23 17:38:20 -0700264 memcpy(&pContext->config, pConfig, sizeof(effect_config_t));
265
Eric Laurent135ad072010-05-21 06:05:13 -0700266 pContext->pEqualizer->configure(channelCount,
267 pConfig->inputCfg.samplingRate);
268
269 pContext->adapter.configure(*pContext->pEqualizer, channelCount,
270 pConfig->inputCfg.format,
271 pConfig->outputCfg.accessMode);
272
273 return 0;
274} // end Equalizer_configure
275
276
277//----------------------------------------------------------------------------
278// Equalizer_init()
279//----------------------------------------------------------------------------
280// Purpose: Initialize engine with default configuration and creates
281// AudioEqualizer instance.
282//
283// Inputs:
284// pContext: effect engine context
285//
286// Outputs:
287//
288//----------------------------------------------------------------------------
289
290int Equalizer_init(EqualizerContext *pContext)
291{
292 int status;
293
294 LOGV("Equalizer_init start");
295
296 CHECK_ARG(pContext != NULL);
297
298 if (pContext->pEqualizer != NULL) {
299 pContext->pEqualizer->free();
300 }
301
302 pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
Eric Laurente1315cf2011-05-17 19:16:02 -0700303 pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
304 pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
Eric Laurent135ad072010-05-21 06:05:13 -0700305 pContext->config.inputCfg.samplingRate = 44100;
306 pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
307 pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
308 pContext->config.inputCfg.bufferProvider.cookie = NULL;
309 pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
310 pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
Eric Laurente1315cf2011-05-17 19:16:02 -0700311 pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
312 pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
Eric Laurent135ad072010-05-21 06:05:13 -0700313 pContext->config.outputCfg.samplingRate = 44100;
314 pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
315 pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
316 pContext->config.outputCfg.bufferProvider.cookie = NULL;
317 pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL;
318
319 pContext->pEqualizer = AudioEqualizer::CreateInstance(
320 NULL,
321 kNumBands,
322 AudioBiquadFilter::MAX_CHANNELS,
323 44100,
324 gEqualizerPresets,
325 ARRAY_SIZE(gEqualizerPresets));
326
327 for (int i = 0; i < kNumBands; ++i) {
328 pContext->pEqualizer->setFrequency(i, gFreqs[i]);
329 pContext->pEqualizer->setBandwidth(i, gBandwidths[i]);
330 }
331
332 pContext->pEqualizer->enable(true);
333
334 Equalizer_configure(pContext, &pContext->config);
335
336 return 0;
337} // end Equalizer_init
338
339
340//----------------------------------------------------------------------------
341// Equalizer_getParameter()
342//----------------------------------------------------------------------------
343// Purpose:
344// Get a Equalizer parameter
345//
346// Inputs:
347// pEqualizer - handle to instance data
348// pParam - pointer to parameter
349// pValue - pointer to variable to hold retrieved value
350// pValueSize - pointer to value size: maximum size as input
351//
352// Outputs:
353// *pValue updated with parameter value
354// *pValueSize updated with actual value size
355//
356//
357// Side Effects:
358//
359//----------------------------------------------------------------------------
360
361int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue)
362{
363 int status = 0;
364 int32_t param = *pParam++;
365 int32_t param2;
366 char *name;
367
368 switch (param) {
369 case EQ_PARAM_NUM_BANDS:
370 case EQ_PARAM_CUR_PRESET:
371 case EQ_PARAM_GET_NUM_OF_PRESETS:
Eric Laurent3be95232010-07-30 09:12:51 -0700372 case EQ_PARAM_BAND_LEVEL:
373 case EQ_PARAM_GET_BAND:
Eric Laurent135ad072010-05-21 06:05:13 -0700374 if (*pValueSize < sizeof(int16_t)) {
375 return -EINVAL;
376 }
377 *pValueSize = sizeof(int16_t);
378 break;
379
380 case EQ_PARAM_LEVEL_RANGE:
Eric Laurent3be95232010-07-30 09:12:51 -0700381 if (*pValueSize < 2 * sizeof(int16_t)) {
382 return -EINVAL;
383 }
384 *pValueSize = 2 * sizeof(int16_t);
385 break;
386
Eric Laurent135ad072010-05-21 06:05:13 -0700387 case EQ_PARAM_BAND_FREQ_RANGE:
388 if (*pValueSize < 2 * sizeof(int32_t)) {
389 return -EINVAL;
390 }
391 *pValueSize = 2 * sizeof(int32_t);
392 break;
Eric Laurent3be95232010-07-30 09:12:51 -0700393
Eric Laurent135ad072010-05-21 06:05:13 -0700394 case EQ_PARAM_CENTER_FREQ:
395 if (*pValueSize < sizeof(int32_t)) {
396 return -EINVAL;
397 }
398 *pValueSize = sizeof(int32_t);
399 break;
400
401 case EQ_PARAM_GET_PRESET_NAME:
402 break;
403
Eric Laurent3be95232010-07-30 09:12:51 -0700404 case EQ_PARAM_PROPERTIES:
405 if (*pValueSize < (2 + kNumBands) * sizeof(uint16_t)) {
406 return -EINVAL;
407 }
408 *pValueSize = (2 + kNumBands) * sizeof(uint16_t);
409 break;
410
Eric Laurent135ad072010-05-21 06:05:13 -0700411 default:
412 return -EINVAL;
413 }
414
415 switch (param) {
416 case EQ_PARAM_NUM_BANDS:
Eric Laurent3be95232010-07-30 09:12:51 -0700417 *(uint16_t *)pValue = (uint16_t)kNumBands;
Eric Laurent135ad072010-05-21 06:05:13 -0700418 LOGV("Equalizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue);
419 break;
420
421 case EQ_PARAM_LEVEL_RANGE:
Eric Laurent3be95232010-07-30 09:12:51 -0700422 *(int16_t *)pValue = -9600;
423 *((int16_t *)pValue + 1) = 4800;
Eric Laurente1315cf2011-05-17 19:16:02 -0700424 LOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d",
425 *(int32_t *)pValue, *((int32_t *)pValue + 1));
Eric Laurent135ad072010-05-21 06:05:13 -0700426 break;
427
428 case EQ_PARAM_BAND_LEVEL:
429 param2 = *pParam;
430 if (param2 >= kNumBands) {
431 status = -EINVAL;
432 break;
433 }
Eric Laurent3be95232010-07-30 09:12:51 -0700434 *(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2);
Eric Laurente1315cf2011-05-17 19:16:02 -0700435 LOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d",
436 param2, *(int32_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700437 break;
438
439 case EQ_PARAM_CENTER_FREQ:
440 param2 = *pParam;
441 if (param2 >= kNumBands) {
442 status = -EINVAL;
443 break;
444 }
445 *(int32_t *)pValue = pEqualizer->getFrequency(param2);
Eric Laurente1315cf2011-05-17 19:16:02 -0700446 LOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d",
447 param2, *(int32_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700448 break;
449
450 case EQ_PARAM_BAND_FREQ_RANGE:
451 param2 = *pParam;
452 if (param2 >= kNumBands) {
453 status = -EINVAL;
454 break;
455 }
456 pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1));
Eric Laurente1315cf2011-05-17 19:16:02 -0700457 LOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d",
458 param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
Eric Laurent135ad072010-05-21 06:05:13 -0700459 break;
460
461 case EQ_PARAM_GET_BAND:
462 param2 = *pParam;
Eric Laurent3be95232010-07-30 09:12:51 -0700463 *(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2);
Eric Laurente1315cf2011-05-17 19:16:02 -0700464 LOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d",
465 param2, *(int32_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700466 break;
467
468 case EQ_PARAM_CUR_PRESET:
Eric Laurent3be95232010-07-30 09:12:51 -0700469 *(uint16_t *)pValue = (uint16_t)pEqualizer->getPreset();
Eric Laurent135ad072010-05-21 06:05:13 -0700470 LOGV("Equalizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue);
471 break;
472
473 case EQ_PARAM_GET_NUM_OF_PRESETS:
Eric Laurent3be95232010-07-30 09:12:51 -0700474 *(uint16_t *)pValue = (uint16_t)pEqualizer->getNumPresets();
Eric Laurent135ad072010-05-21 06:05:13 -0700475 LOGV("Equalizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue);
476 break;
477
478 case EQ_PARAM_GET_PRESET_NAME:
479 param2 = *pParam;
480 if (param2 >= pEqualizer->getNumPresets()) {
481 status = -EINVAL;
482 break;
483 }
484 name = (char *)pValue;
485 strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1);
486 name[*pValueSize - 1] = 0;
487 *pValueSize = strlen(name) + 1;
Eric Laurente1315cf2011-05-17 19:16:02 -0700488 LOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d",
489 param2, gEqualizerPresets[param2].name, *pValueSize);
Eric Laurent135ad072010-05-21 06:05:13 -0700490 break;
491
Eric Laurent3be95232010-07-30 09:12:51 -0700492 case EQ_PARAM_PROPERTIES: {
493 int16_t *p = (int16_t *)pValue;
494 LOGV("Equalizer_getParameter() EQ_PARAM_PROPERTIES");
495 p[0] = (int16_t)pEqualizer->getPreset();
496 p[1] = (int16_t)kNumBands;
497 for (int i = 0; i < kNumBands; i++) {
498 p[2 + i] = (int16_t)pEqualizer->getGain(i);
499 }
500 } break;
501
Eric Laurent135ad072010-05-21 06:05:13 -0700502 default:
503 LOGV("Equalizer_getParameter() invalid param %d", param);
504 status = -EINVAL;
505 break;
506 }
507
508 return status;
509} // end Equalizer_getParameter
510
511
512//----------------------------------------------------------------------------
513// Equalizer_setParameter()
514//----------------------------------------------------------------------------
515// Purpose:
516// Set a Equalizer parameter
517//
518// Inputs:
519// pEqualizer - handle to instance data
520// pParam - pointer to parameter
521// pValue - pointer to value
522//
523// Outputs:
524//
525//
526// Side Effects:
527//
528//----------------------------------------------------------------------------
529
530int Equalizer_setParameter (AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue)
531{
532 int status = 0;
533 int32_t preset;
534 int32_t band;
535 int32_t level;
536 int32_t param = *pParam++;
537
538
539 switch (param) {
540 case EQ_PARAM_CUR_PRESET:
Eric Laurent3be95232010-07-30 09:12:51 -0700541 preset = (int32_t)(*(uint16_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700542
543 LOGV("setParameter() EQ_PARAM_CUR_PRESET %d", preset);
Eric Laurent3be95232010-07-30 09:12:51 -0700544 if (preset < 0 || preset >= pEqualizer->getNumPresets()) {
Eric Laurent135ad072010-05-21 06:05:13 -0700545 status = -EINVAL;
546 break;
547 }
548 pEqualizer->setPreset(preset);
549 pEqualizer->commit(true);
550 break;
551 case EQ_PARAM_BAND_LEVEL:
552 band = *pParam;
Eric Laurent3be95232010-07-30 09:12:51 -0700553 level = (int32_t)(*(int16_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700554 LOGV("setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level);
555 if (band >= kNumBands) {
556 status = -EINVAL;
557 break;
558 }
559 pEqualizer->setGain(band, level);
560 pEqualizer->commit(true);
561 break;
Eric Laurent3be95232010-07-30 09:12:51 -0700562 case EQ_PARAM_PROPERTIES: {
563 LOGV("setParameter() EQ_PARAM_PROPERTIES");
564 int16_t *p = (int16_t *)pValue;
565 if ((int)p[0] >= pEqualizer->getNumPresets()) {
566 status = -EINVAL;
567 break;
568 }
569 if (p[0] >= 0) {
570 pEqualizer->setPreset((int)p[0]);
571 } else {
572 if ((int)p[1] != kNumBands) {
573 status = -EINVAL;
574 break;
575 }
576 for (int i = 0; i < kNumBands; i++) {
577 pEqualizer->setGain(i, (int32_t)p[2 + i]);
578 }
579 }
580 pEqualizer->commit(true);
581 } break;
Eric Laurent135ad072010-05-21 06:05:13 -0700582 default:
583 LOGV("setParameter() invalid param %d", param);
Eric Laurent3be95232010-07-30 09:12:51 -0700584 status = -EINVAL;
Eric Laurent135ad072010-05-21 06:05:13 -0700585 break;
586 }
587
588 return status;
589} // end Equalizer_setParameter
590
591} // namespace
592} // namespace
593
594
595//
596//--- Effect Control Interface Implementation
597//
598
Eric Laurente1315cf2011-05-17 19:16:02 -0700599extern "C" int Equalizer_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
Eric Laurent135ad072010-05-21 06:05:13 -0700600{
601 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
602
603 if (pContext == NULL) {
604 return -EINVAL;
605 }
606 if (inBuffer == NULL || inBuffer->raw == NULL ||
607 outBuffer == NULL || outBuffer->raw == NULL ||
608 inBuffer->frameCount != outBuffer->frameCount) {
609 return -EINVAL;
610 }
611
Eric Laurente44b1ef2010-07-09 13:34:17 -0700612 if (pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
613 return -EINVAL;
614 }
615 if (pContext->state == EQUALIZER_STATE_INITIALIZED) {
616 return -ENODATA;
617 }
618
Eric Laurent135ad072010-05-21 06:05:13 -0700619 pContext->adapter.process(inBuffer->raw, outBuffer->raw, outBuffer->frameCount);
Eric Laurentffe9c252010-06-23 17:38:20 -0700620
Eric Laurent135ad072010-05-21 06:05:13 -0700621 return 0;
622} // end Equalizer_process
623
Eric Laurente1315cf2011-05-17 19:16:02 -0700624extern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
Eric Laurent25f43952010-07-28 05:40:18 -0700625 void *pCmdData, uint32_t *replySize, void *pReplyData) {
Eric Laurent135ad072010-05-21 06:05:13 -0700626
627 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
628 int retsize;
629
Eric Laurente44b1ef2010-07-09 13:34:17 -0700630 if (pContext == NULL || pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
Eric Laurent135ad072010-05-21 06:05:13 -0700631 return -EINVAL;
632 }
633
634 android::AudioEqualizer * pEqualizer = pContext->pEqualizer;
635
636 LOGV("Equalizer_command command %d cmdSize %d",cmdCode, cmdSize);
637
638 switch (cmdCode) {
639 case EFFECT_CMD_INIT:
640 if (pReplyData == NULL || *replySize != sizeof(int)) {
641 return -EINVAL;
642 }
643 *(int *) pReplyData = Equalizer_init(pContext);
644 break;
645 case EFFECT_CMD_CONFIGURE:
646 if (pCmdData == NULL || cmdSize != sizeof(effect_config_t)
647 || pReplyData == NULL || *replySize != sizeof(int)) {
648 return -EINVAL;
649 }
650 *(int *) pReplyData = Equalizer_configure(pContext,
651 (effect_config_t *) pCmdData);
652 break;
653 case EFFECT_CMD_RESET:
654 Equalizer_configure(pContext, &pContext->config);
655 break;
656 case EFFECT_CMD_GET_PARAM: {
657 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
658 pReplyData == NULL || *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))) {
659 return -EINVAL;
660 }
661 effect_param_t *p = (effect_param_t *)pCmdData;
662 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
663 p = (effect_param_t *)pReplyData;
664 int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
665 p->status = android::Equalizer_getParameter(pEqualizer, (int32_t *)p->data, &p->vsize,
666 p->data + voffset);
667 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
668 LOGV("Equalizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x",
669 *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize,
670 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset),
671 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset + sizeof(int32_t)));
672
673 } break;
674 case EFFECT_CMD_SET_PARAM: {
Eric Laurente1315cf2011-05-17 19:16:02 -0700675 LOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p",
676 cmdSize, pCmdData, *replySize, pReplyData);
Eric Laurent135ad072010-05-21 06:05:13 -0700677 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
678 pReplyData == NULL || *replySize != sizeof(int32_t)) {
679 return -EINVAL;
680 }
681 effect_param_t *p = (effect_param_t *) pCmdData;
682 *(int *)pReplyData = android::Equalizer_setParameter(pEqualizer, (int32_t *)p->data,
683 p->data + p->psize);
684 } break;
Eric Laurentffe9c252010-06-23 17:38:20 -0700685 case EFFECT_CMD_ENABLE:
Eric Laurente44b1ef2010-07-09 13:34:17 -0700686 if (pReplyData == NULL || *replySize != sizeof(int)) {
687 return -EINVAL;
688 }
689 if (pContext->state != EQUALIZER_STATE_INITIALIZED) {
690 return -ENOSYS;
691 }
692 pContext->state = EQUALIZER_STATE_ACTIVE;
693 LOGV("EFFECT_CMD_ENABLE() OK");
694 *(int *)pReplyData = 0;
695 break;
Eric Laurentffe9c252010-06-23 17:38:20 -0700696 case EFFECT_CMD_DISABLE:
697 if (pReplyData == NULL || *replySize != sizeof(int)) {
698 return -EINVAL;
699 }
Eric Laurente44b1ef2010-07-09 13:34:17 -0700700 if (pContext->state != EQUALIZER_STATE_ACTIVE) {
701 return -ENOSYS;
702 }
703 pContext->state = EQUALIZER_STATE_INITIALIZED;
704 LOGV("EFFECT_CMD_DISABLE() OK");
Eric Laurentffe9c252010-06-23 17:38:20 -0700705 *(int *)pReplyData = 0;
706 break;
707 case EFFECT_CMD_SET_DEVICE:
708 case EFFECT_CMD_SET_VOLUME:
709 case EFFECT_CMD_SET_AUDIO_MODE:
710 break;
Eric Laurent135ad072010-05-21 06:05:13 -0700711 default:
712 LOGW("Equalizer_command invalid command %d",cmdCode);
713 return -EINVAL;
714 }
715
716 return 0;
717}
718
Eric Laurente1315cf2011-05-17 19:16:02 -0700719extern "C" int Equalizer_getDescriptor(effect_handle_t self,
720 effect_descriptor_t *pDescriptor)
721{
722 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
723
724 if (pContext == NULL || pDescriptor == NULL) {
725 LOGV("Equalizer_getDescriptor() invalid param");
726 return -EINVAL;
727 }
728
729 memcpy(pDescriptor, &android::gEqualizerDescriptor, sizeof(effect_descriptor_t));
730
731 return 0;
732}
733
734// effect_handle_t interface implementation for equalizer effect
Eric Laurent135ad072010-05-21 06:05:13 -0700735const struct effect_interface_s gEqualizerInterface = {
736 Equalizer_process,
Eric Laurente1315cf2011-05-17 19:16:02 -0700737 Equalizer_command,
738 Equalizer_getDescriptor
Eric Laurent135ad072010-05-21 06:05:13 -0700739};
740
741
Eric Laurente1315cf2011-05-17 19:16:02 -0700742audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
743 tag : AUDIO_EFFECT_LIBRARY_TAG,
744 version : EFFECT_LIBRARY_API_VERSION,
745 name : "Test Equalizer Library",
746 implementor : "The Android Open Source Project",
747 query_num_effects : android::EffectQueryNumberEffects,
748 query_effect : android::EffectQueryEffect,
749 create_effect : android::EffectCreate,
750 release_effect : android::EffectRelease,
751 get_descriptor : android::EffectGetDescriptor,
752};