blob: c35453b8f63cddd37cdbca62317f15a4a7cd196c [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"
Eric Laurent6d8b6942011-06-24 07:01:31 -070029#include <audio_effects/effect_equalizer.h>
30
Eric Laurent135ad072010-05-21 06:05:13 -070031
Eric Laurente1315cf2011-05-17 19:16:02 -070032// effect_handle_t interface implementation for equalizer effect
Eric Laurent135ad072010-05-21 06:05:13 -070033extern "C" const struct effect_interface_s gEqualizerInterface;
34
Eric Laurente44b1ef2010-07-09 13:34:17 -070035enum equalizer_state_e {
36 EQUALIZER_STATE_UNINITIALIZED,
37 EQUALIZER_STATE_INITIALIZED,
38 EQUALIZER_STATE_ACTIVE,
39};
40
Eric Laurent135ad072010-05-21 06:05:13 -070041namespace android {
42namespace {
43
44// Google Graphic Equalizer UUID: e25aa840-543b-11df-98a5-0002a5d5c51b
45const 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
Eric Laurente1315cf2011-05-17 19:16:02 -070048 EFFECT_CONTROL_API_VERSION,
Eric Laurent135ad072010-05-21 06:05:13 -070049 (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
Eric Laurentffe9c252010-06-23 17:38:20 -070050 0, // TODO
51 1,
Eric Laurent135ad072010-05-21 06:05:13 -070052 "Graphic Equalizer",
Eric Laurente1315cf2011-05-17 19:16:02 -070053 "The Android Open Source Project",
Eric Laurent135ad072010-05-21 06:05:13 -070054};
Eric Laurent135ad072010-05-21 06:05:13 -070055
56/////////////////// BEGIN EQ PRESETS ///////////////////////////////////////////
57const int kNumBands = 5;
58const uint32_t gFreqs[kNumBands] = { 50000, 125000, 900000, 3200000, 6300000 };
59const uint32_t gBandwidths[kNumBands] = { 0, 3600, 3600, 2400, 0 };
60
61const 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
69const 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
77const 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
85const 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
93const AudioEqualizer::PresetConfig gEqualizerPresets[] = {
94 { "Classic", gBandsClassic },
95 { "Jazz", gBandsJazz },
96 { "Pop", gBandsPop },
97 { "Rock", gBandsRock }
98};
99
100/////////////////// END EQ PRESETS /////////////////////////////////////////////
101
102static const size_t kBufferSize = 32;
103
104typedef AudioFormatAdapter<AudioEqualizer, kBufferSize> FormatAdapter;
105
106struct EqualizerContext {
107 const struct effect_interface_s *itfe;
108 effect_config_t config;
109 FormatAdapter adapter;
110 AudioEqualizer * pEqualizer;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700111 uint32_t state;
Eric Laurent135ad072010-05-21 06:05:13 -0700112};
113
Eric Laurent135ad072010-05-21 06:05:13 -0700114//--- local function prototypes
115
116int Equalizer_init(EqualizerContext *pContext);
Eric Laurent3d5188b2011-12-16 15:30:36 -0800117int Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig);
Eric Laurent135ad072010-05-21 06:05:13 -0700118int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue);
119int Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue);
120
121
122//
123//--- Effect Library Interface Implementation
124//
125
Glenn Kasten5e92a782012-01-30 07:40:52 -0800126extern "C" int EffectCreate(const effect_uuid_t *uuid,
Eric Laurente1315cf2011-05-17 19:16:02 -0700127 int32_t sessionId,
128 int32_t ioId,
129 effect_handle_t *pHandle) {
Eric Laurent135ad072010-05-21 06:05:13 -0700130 int ret;
131 int i;
132
Steve Block3856b092011-10-20 11:56:00 +0100133 ALOGV("EffectLibCreateEffect start");
Eric Laurent135ad072010-05-21 06:05:13 -0700134
Eric Laurente1315cf2011-05-17 19:16:02 -0700135 if (pHandle == NULL || uuid == NULL) {
Eric Laurent135ad072010-05-21 06:05:13 -0700136 return -EINVAL;
137 }
138
139 if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) != 0) {
140 return -EINVAL;
141 }
142
143 EqualizerContext *pContext = new EqualizerContext;
144
145 pContext->itfe = &gEqualizerInterface;
146 pContext->pEqualizer = NULL;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700147 pContext->state = EQUALIZER_STATE_UNINITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700148
149 ret = Equalizer_init(pContext);
150 if (ret < 0) {
Steve Block5ff1dd52012-01-05 23:22:43 +0000151 ALOGW("EffectLibCreateEffect() init failed");
Eric Laurent135ad072010-05-21 06:05:13 -0700152 delete pContext;
153 return ret;
154 }
155
Eric Laurente1315cf2011-05-17 19:16:02 -0700156 *pHandle = (effect_handle_t)pContext;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700157 pContext->state = EQUALIZER_STATE_INITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700158
Steve Block3856b092011-10-20 11:56:00 +0100159 ALOGV("EffectLibCreateEffect %p, size %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700160 pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext));
Eric Laurent135ad072010-05-21 06:05:13 -0700161
162 return 0;
163
164} /* end EffectCreate */
165
Eric Laurente1315cf2011-05-17 19:16:02 -0700166extern "C" int EffectRelease(effect_handle_t handle) {
167 EqualizerContext * pContext = (EqualizerContext *)handle;
Eric Laurent135ad072010-05-21 06:05:13 -0700168
Steve Block3856b092011-10-20 11:56:00 +0100169 ALOGV("EffectLibReleaseEffect %p", handle);
Eric Laurent135ad072010-05-21 06:05:13 -0700170 if (pContext == NULL) {
171 return -EINVAL;
172 }
173
Eric Laurente44b1ef2010-07-09 13:34:17 -0700174 pContext->state = EQUALIZER_STATE_UNINITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700175 pContext->pEqualizer->free();
176 delete pContext;
177
178 return 0;
179} /* end EffectRelease */
180
Glenn Kasten5e92a782012-01-30 07:40:52 -0800181extern "C" int EffectGetDescriptor(const effect_uuid_t *uuid,
Eric Laurente1315cf2011-05-17 19:16:02 -0700182 effect_descriptor_t *pDescriptor) {
183
184 if (pDescriptor == NULL || uuid == NULL){
Steve Block3856b092011-10-20 11:56:00 +0100185 ALOGV("EffectGetDescriptor() called with NULL pointer");
Eric Laurente1315cf2011-05-17 19:16:02 -0700186 return -EINVAL;
187 }
188
189 if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
Glenn Kastena189a682012-02-20 12:16:30 -0800190 *pDescriptor = gEqualizerDescriptor;
Eric Laurente1315cf2011-05-17 19:16:02 -0700191 return 0;
192 }
193
194 return -EINVAL;
195} /* end EffectGetDescriptor */
196
Eric Laurent135ad072010-05-21 06:05:13 -0700197
198//
199//--- local functions
200//
201
202#define CHECK_ARG(cond) { \
203 if (!(cond)) { \
Steve Block3856b092011-10-20 11:56:00 +0100204 ALOGV("Invalid argument: "#cond); \
Eric Laurent135ad072010-05-21 06:05:13 -0700205 return -EINVAL; \
206 } \
207}
208
209//----------------------------------------------------------------------------
Eric Laurent3d5188b2011-12-16 15:30:36 -0800210// Equalizer_setConfig()
Eric Laurent135ad072010-05-21 06:05:13 -0700211//----------------------------------------------------------------------------
212// Purpose: Set input and output audio configuration.
213//
214// Inputs:
215// pContext: effect engine context
216// pConfig: pointer to effect_config_t structure holding input and output
217// configuration parameters
218//
219// Outputs:
220//
221//----------------------------------------------------------------------------
222
Eric Laurent3d5188b2011-12-16 15:30:36 -0800223int Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig)
Eric Laurent135ad072010-05-21 06:05:13 -0700224{
Eric Laurent3d5188b2011-12-16 15:30:36 -0800225 ALOGV("Equalizer_setConfig start");
Eric Laurent135ad072010-05-21 06:05:13 -0700226
227 CHECK_ARG(pContext != NULL);
228 CHECK_ARG(pConfig != NULL);
229
230 CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
231 CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
232 CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
Eric Laurente1315cf2011-05-17 19:16:02 -0700233 CHECK_ARG((pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) ||
234 (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO));
Eric Laurent135ad072010-05-21 06:05:13 -0700235 CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
236 || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
Eric Laurente1315cf2011-05-17 19:16:02 -0700237 CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_8_24_BIT
238 || pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT);
Eric Laurent135ad072010-05-21 06:05:13 -0700239
240 int channelCount;
Eric Laurente1315cf2011-05-17 19:16:02 -0700241 if (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) {
Eric Laurent135ad072010-05-21 06:05:13 -0700242 channelCount = 1;
243 } else {
244 channelCount = 2;
245 }
246 CHECK_ARG(channelCount <= AudioBiquadFilter::MAX_CHANNELS);
247
Glenn Kastena189a682012-02-20 12:16:30 -0800248 pContext->config = *pConfig;
Eric Laurentffe9c252010-06-23 17:38:20 -0700249
Eric Laurent135ad072010-05-21 06:05:13 -0700250 pContext->pEqualizer->configure(channelCount,
251 pConfig->inputCfg.samplingRate);
252
253 pContext->adapter.configure(*pContext->pEqualizer, channelCount,
254 pConfig->inputCfg.format,
255 pConfig->outputCfg.accessMode);
256
257 return 0;
Eric Laurent3d5188b2011-12-16 15:30:36 -0800258} // end Equalizer_setConfig
259
260//----------------------------------------------------------------------------
261// Equalizer_getConfig()
262//----------------------------------------------------------------------------
263// Purpose: Get input and output audio configuration.
264//
265// Inputs:
266// pContext: effect engine context
267// pConfig: pointer to effect_config_t structure holding input and output
268// configuration parameters
269//
270// Outputs:
271//
272//----------------------------------------------------------------------------
273
274void Equalizer_getConfig(EqualizerContext *pContext, effect_config_t *pConfig)
275{
Glenn Kastena189a682012-02-20 12:16:30 -0800276 *pConfig = pContext->config;
Eric Laurent3d5188b2011-12-16 15:30:36 -0800277} // end Equalizer_getConfig
Eric Laurent135ad072010-05-21 06:05:13 -0700278
279
280//----------------------------------------------------------------------------
281// Equalizer_init()
282//----------------------------------------------------------------------------
283// Purpose: Initialize engine with default configuration and creates
284// AudioEqualizer instance.
285//
286// Inputs:
287// pContext: effect engine context
288//
289// Outputs:
290//
291//----------------------------------------------------------------------------
292
293int Equalizer_init(EqualizerContext *pContext)
294{
295 int status;
296
Steve Block3856b092011-10-20 11:56:00 +0100297 ALOGV("Equalizer_init start");
Eric Laurent135ad072010-05-21 06:05:13 -0700298
299 CHECK_ARG(pContext != NULL);
300
301 if (pContext->pEqualizer != NULL) {
302 pContext->pEqualizer->free();
303 }
304
305 pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
Eric Laurente1315cf2011-05-17 19:16:02 -0700306 pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
307 pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
Eric Laurent135ad072010-05-21 06:05:13 -0700308 pContext->config.inputCfg.samplingRate = 44100;
309 pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
310 pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
311 pContext->config.inputCfg.bufferProvider.cookie = NULL;
312 pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
313 pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
Eric Laurente1315cf2011-05-17 19:16:02 -0700314 pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
315 pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
Eric Laurent135ad072010-05-21 06:05:13 -0700316 pContext->config.outputCfg.samplingRate = 44100;
317 pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
318 pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
319 pContext->config.outputCfg.bufferProvider.cookie = NULL;
320 pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL;
321
322 pContext->pEqualizer = AudioEqualizer::CreateInstance(
323 NULL,
324 kNumBands,
325 AudioBiquadFilter::MAX_CHANNELS,
326 44100,
327 gEqualizerPresets,
328 ARRAY_SIZE(gEqualizerPresets));
329
330 for (int i = 0; i < kNumBands; ++i) {
331 pContext->pEqualizer->setFrequency(i, gFreqs[i]);
332 pContext->pEqualizer->setBandwidth(i, gBandwidths[i]);
333 }
334
335 pContext->pEqualizer->enable(true);
336
Eric Laurent3d5188b2011-12-16 15:30:36 -0800337 Equalizer_setConfig(pContext, &pContext->config);
Eric Laurent135ad072010-05-21 06:05:13 -0700338
339 return 0;
340} // end Equalizer_init
341
342
343//----------------------------------------------------------------------------
344// Equalizer_getParameter()
345//----------------------------------------------------------------------------
346// Purpose:
347// Get a Equalizer parameter
348//
349// Inputs:
350// pEqualizer - handle to instance data
351// pParam - pointer to parameter
352// pValue - pointer to variable to hold retrieved value
353// pValueSize - pointer to value size: maximum size as input
354//
355// Outputs:
356// *pValue updated with parameter value
357// *pValueSize updated with actual value size
358//
359//
360// Side Effects:
361//
362//----------------------------------------------------------------------------
363
364int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue)
365{
366 int status = 0;
367 int32_t param = *pParam++;
368 int32_t param2;
369 char *name;
370
371 switch (param) {
372 case EQ_PARAM_NUM_BANDS:
373 case EQ_PARAM_CUR_PRESET:
374 case EQ_PARAM_GET_NUM_OF_PRESETS:
Eric Laurent3be95232010-07-30 09:12:51 -0700375 case EQ_PARAM_BAND_LEVEL:
376 case EQ_PARAM_GET_BAND:
Eric Laurent135ad072010-05-21 06:05:13 -0700377 if (*pValueSize < sizeof(int16_t)) {
378 return -EINVAL;
379 }
380 *pValueSize = sizeof(int16_t);
381 break;
382
383 case EQ_PARAM_LEVEL_RANGE:
Eric Laurent3be95232010-07-30 09:12:51 -0700384 if (*pValueSize < 2 * sizeof(int16_t)) {
385 return -EINVAL;
386 }
387 *pValueSize = 2 * sizeof(int16_t);
388 break;
389
Eric Laurent135ad072010-05-21 06:05:13 -0700390 case EQ_PARAM_BAND_FREQ_RANGE:
391 if (*pValueSize < 2 * sizeof(int32_t)) {
392 return -EINVAL;
393 }
394 *pValueSize = 2 * sizeof(int32_t);
395 break;
Eric Laurent3be95232010-07-30 09:12:51 -0700396
Eric Laurent135ad072010-05-21 06:05:13 -0700397 case EQ_PARAM_CENTER_FREQ:
398 if (*pValueSize < sizeof(int32_t)) {
399 return -EINVAL;
400 }
401 *pValueSize = sizeof(int32_t);
402 break;
403
404 case EQ_PARAM_GET_PRESET_NAME:
405 break;
406
Eric Laurent3be95232010-07-30 09:12:51 -0700407 case EQ_PARAM_PROPERTIES:
408 if (*pValueSize < (2 + kNumBands) * sizeof(uint16_t)) {
409 return -EINVAL;
410 }
411 *pValueSize = (2 + kNumBands) * sizeof(uint16_t);
412 break;
413
Eric Laurent135ad072010-05-21 06:05:13 -0700414 default:
415 return -EINVAL;
416 }
417
418 switch (param) {
419 case EQ_PARAM_NUM_BANDS:
Eric Laurent3be95232010-07-30 09:12:51 -0700420 *(uint16_t *)pValue = (uint16_t)kNumBands;
Steve Block3856b092011-10-20 11:56:00 +0100421 ALOGV("Equalizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700422 break;
423
424 case EQ_PARAM_LEVEL_RANGE:
Eric Laurent3be95232010-07-30 09:12:51 -0700425 *(int16_t *)pValue = -9600;
426 *((int16_t *)pValue + 1) = 4800;
Steve Block3856b092011-10-20 11:56:00 +0100427 ALOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700428 *(int32_t *)pValue, *((int32_t *)pValue + 1));
Eric Laurent135ad072010-05-21 06:05:13 -0700429 break;
430
431 case EQ_PARAM_BAND_LEVEL:
432 param2 = *pParam;
433 if (param2 >= kNumBands) {
434 status = -EINVAL;
435 break;
436 }
Eric Laurent3be95232010-07-30 09:12:51 -0700437 *(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2);
Steve Block3856b092011-10-20 11:56:00 +0100438 ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700439 param2, *(int32_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700440 break;
441
442 case EQ_PARAM_CENTER_FREQ:
443 param2 = *pParam;
444 if (param2 >= kNumBands) {
445 status = -EINVAL;
446 break;
447 }
448 *(int32_t *)pValue = pEqualizer->getFrequency(param2);
Steve Block3856b092011-10-20 11:56:00 +0100449 ALOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700450 param2, *(int32_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700451 break;
452
453 case EQ_PARAM_BAND_FREQ_RANGE:
454 param2 = *pParam;
455 if (param2 >= kNumBands) {
456 status = -EINVAL;
457 break;
458 }
459 pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1));
Steve Block3856b092011-10-20 11:56:00 +0100460 ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700461 param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
Eric Laurent135ad072010-05-21 06:05:13 -0700462 break;
463
464 case EQ_PARAM_GET_BAND:
465 param2 = *pParam;
Eric Laurent3be95232010-07-30 09:12:51 -0700466 *(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2);
Steve Block3856b092011-10-20 11:56:00 +0100467 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700468 param2, *(int32_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700469 break;
470
471 case EQ_PARAM_CUR_PRESET:
Eric Laurent3be95232010-07-30 09:12:51 -0700472 *(uint16_t *)pValue = (uint16_t)pEqualizer->getPreset();
Steve Block3856b092011-10-20 11:56:00 +0100473 ALOGV("Equalizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700474 break;
475
476 case EQ_PARAM_GET_NUM_OF_PRESETS:
Eric Laurent3be95232010-07-30 09:12:51 -0700477 *(uint16_t *)pValue = (uint16_t)pEqualizer->getNumPresets();
Steve Block3856b092011-10-20 11:56:00 +0100478 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700479 break;
480
481 case EQ_PARAM_GET_PRESET_NAME:
482 param2 = *pParam;
483 if (param2 >= pEqualizer->getNumPresets()) {
484 status = -EINVAL;
485 break;
486 }
487 name = (char *)pValue;
488 strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1);
489 name[*pValueSize - 1] = 0;
490 *pValueSize = strlen(name) + 1;
Steve Block3856b092011-10-20 11:56:00 +0100491 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700492 param2, gEqualizerPresets[param2].name, *pValueSize);
Eric Laurent135ad072010-05-21 06:05:13 -0700493 break;
494
Eric Laurent3be95232010-07-30 09:12:51 -0700495 case EQ_PARAM_PROPERTIES: {
496 int16_t *p = (int16_t *)pValue;
Steve Block3856b092011-10-20 11:56:00 +0100497 ALOGV("Equalizer_getParameter() EQ_PARAM_PROPERTIES");
Eric Laurent3be95232010-07-30 09:12:51 -0700498 p[0] = (int16_t)pEqualizer->getPreset();
499 p[1] = (int16_t)kNumBands;
500 for (int i = 0; i < kNumBands; i++) {
501 p[2 + i] = (int16_t)pEqualizer->getGain(i);
502 }
503 } break;
504
Eric Laurent135ad072010-05-21 06:05:13 -0700505 default:
Steve Block3856b092011-10-20 11:56:00 +0100506 ALOGV("Equalizer_getParameter() invalid param %d", param);
Eric Laurent135ad072010-05-21 06:05:13 -0700507 status = -EINVAL;
508 break;
509 }
510
511 return status;
512} // end Equalizer_getParameter
513
514
515//----------------------------------------------------------------------------
516// Equalizer_setParameter()
517//----------------------------------------------------------------------------
518// Purpose:
519// Set a Equalizer parameter
520//
521// Inputs:
522// pEqualizer - handle to instance data
523// pParam - pointer to parameter
524// pValue - pointer to value
525//
526// Outputs:
527//
528//
529// Side Effects:
530//
531//----------------------------------------------------------------------------
532
533int Equalizer_setParameter (AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue)
534{
535 int status = 0;
536 int32_t preset;
537 int32_t band;
538 int32_t level;
539 int32_t param = *pParam++;
540
541
542 switch (param) {
543 case EQ_PARAM_CUR_PRESET:
Eric Laurent3be95232010-07-30 09:12:51 -0700544 preset = (int32_t)(*(uint16_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700545
Steve Block3856b092011-10-20 11:56:00 +0100546 ALOGV("setParameter() EQ_PARAM_CUR_PRESET %d", preset);
Eric Laurent3be95232010-07-30 09:12:51 -0700547 if (preset < 0 || preset >= pEqualizer->getNumPresets()) {
Eric Laurent135ad072010-05-21 06:05:13 -0700548 status = -EINVAL;
549 break;
550 }
551 pEqualizer->setPreset(preset);
552 pEqualizer->commit(true);
553 break;
554 case EQ_PARAM_BAND_LEVEL:
555 band = *pParam;
Eric Laurent3be95232010-07-30 09:12:51 -0700556 level = (int32_t)(*(int16_t *)pValue);
Steve Block3856b092011-10-20 11:56:00 +0100557 ALOGV("setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level);
Eric Laurent135ad072010-05-21 06:05:13 -0700558 if (band >= kNumBands) {
559 status = -EINVAL;
560 break;
561 }
562 pEqualizer->setGain(band, level);
563 pEqualizer->commit(true);
564 break;
Eric Laurent3be95232010-07-30 09:12:51 -0700565 case EQ_PARAM_PROPERTIES: {
Steve Block3856b092011-10-20 11:56:00 +0100566 ALOGV("setParameter() EQ_PARAM_PROPERTIES");
Eric Laurent3be95232010-07-30 09:12:51 -0700567 int16_t *p = (int16_t *)pValue;
568 if ((int)p[0] >= pEqualizer->getNumPresets()) {
569 status = -EINVAL;
570 break;
571 }
572 if (p[0] >= 0) {
573 pEqualizer->setPreset((int)p[0]);
574 } else {
575 if ((int)p[1] != kNumBands) {
576 status = -EINVAL;
577 break;
578 }
579 for (int i = 0; i < kNumBands; i++) {
580 pEqualizer->setGain(i, (int32_t)p[2 + i]);
581 }
582 }
583 pEqualizer->commit(true);
584 } break;
Eric Laurent135ad072010-05-21 06:05:13 -0700585 default:
Steve Block3856b092011-10-20 11:56:00 +0100586 ALOGV("setParameter() invalid param %d", param);
Eric Laurent3be95232010-07-30 09:12:51 -0700587 status = -EINVAL;
Eric Laurent135ad072010-05-21 06:05:13 -0700588 break;
589 }
590
591 return status;
592} // end Equalizer_setParameter
593
594} // namespace
595} // namespace
596
597
598//
599//--- Effect Control Interface Implementation
600//
601
Eric Laurente1315cf2011-05-17 19:16:02 -0700602extern "C" int Equalizer_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
Eric Laurent135ad072010-05-21 06:05:13 -0700603{
604 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
605
606 if (pContext == NULL) {
607 return -EINVAL;
608 }
609 if (inBuffer == NULL || inBuffer->raw == NULL ||
610 outBuffer == NULL || outBuffer->raw == NULL ||
611 inBuffer->frameCount != outBuffer->frameCount) {
612 return -EINVAL;
613 }
614
Eric Laurente44b1ef2010-07-09 13:34:17 -0700615 if (pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
616 return -EINVAL;
617 }
618 if (pContext->state == EQUALIZER_STATE_INITIALIZED) {
619 return -ENODATA;
620 }
621
Eric Laurent135ad072010-05-21 06:05:13 -0700622 pContext->adapter.process(inBuffer->raw, outBuffer->raw, outBuffer->frameCount);
Eric Laurentffe9c252010-06-23 17:38:20 -0700623
Eric Laurent135ad072010-05-21 06:05:13 -0700624 return 0;
625} // end Equalizer_process
626
Eric Laurente1315cf2011-05-17 19:16:02 -0700627extern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
Eric Laurent25f43952010-07-28 05:40:18 -0700628 void *pCmdData, uint32_t *replySize, void *pReplyData) {
Eric Laurent135ad072010-05-21 06:05:13 -0700629
630 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
631 int retsize;
632
Eric Laurente44b1ef2010-07-09 13:34:17 -0700633 if (pContext == NULL || pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
Eric Laurent135ad072010-05-21 06:05:13 -0700634 return -EINVAL;
635 }
636
637 android::AudioEqualizer * pEqualizer = pContext->pEqualizer;
638
Steve Block3856b092011-10-20 11:56:00 +0100639 ALOGV("Equalizer_command command %d cmdSize %d",cmdCode, cmdSize);
Eric Laurent135ad072010-05-21 06:05:13 -0700640
641 switch (cmdCode) {
642 case EFFECT_CMD_INIT:
643 if (pReplyData == NULL || *replySize != sizeof(int)) {
644 return -EINVAL;
645 }
646 *(int *) pReplyData = Equalizer_init(pContext);
647 break;
Eric Laurent3d5188b2011-12-16 15:30:36 -0800648 case EFFECT_CMD_SET_CONFIG:
Eric Laurent135ad072010-05-21 06:05:13 -0700649 if (pCmdData == NULL || cmdSize != sizeof(effect_config_t)
650 || pReplyData == NULL || *replySize != sizeof(int)) {
651 return -EINVAL;
652 }
Eric Laurent3d5188b2011-12-16 15:30:36 -0800653 *(int *) pReplyData = Equalizer_setConfig(pContext,
Eric Laurent135ad072010-05-21 06:05:13 -0700654 (effect_config_t *) pCmdData);
655 break;
Eric Laurent3d5188b2011-12-16 15:30:36 -0800656 case EFFECT_CMD_GET_CONFIG:
657 if (pReplyData == NULL || *replySize != sizeof(effect_config_t)) {
658 return -EINVAL;
659 }
660 Equalizer_getConfig(pContext, (effect_config_t *) pCmdData);
661 break;
Eric Laurent135ad072010-05-21 06:05:13 -0700662 case EFFECT_CMD_RESET:
Eric Laurent3d5188b2011-12-16 15:30:36 -0800663 Equalizer_setConfig(pContext, &pContext->config);
Eric Laurent135ad072010-05-21 06:05:13 -0700664 break;
665 case EFFECT_CMD_GET_PARAM: {
666 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
667 pReplyData == NULL || *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))) {
668 return -EINVAL;
669 }
670 effect_param_t *p = (effect_param_t *)pCmdData;
671 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
672 p = (effect_param_t *)pReplyData;
673 int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
674 p->status = android::Equalizer_getParameter(pEqualizer, (int32_t *)p->data, &p->vsize,
675 p->data + voffset);
676 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
Steve Block3856b092011-10-20 11:56:00 +0100677 ALOGV("Equalizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x",
Eric Laurent135ad072010-05-21 06:05:13 -0700678 *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize,
679 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset),
680 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset + sizeof(int32_t)));
681
682 } break;
683 case EFFECT_CMD_SET_PARAM: {
Steve Block3856b092011-10-20 11:56:00 +0100684 ALOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p",
Eric Laurente1315cf2011-05-17 19:16:02 -0700685 cmdSize, pCmdData, *replySize, pReplyData);
Eric Laurent135ad072010-05-21 06:05:13 -0700686 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
687 pReplyData == NULL || *replySize != sizeof(int32_t)) {
688 return -EINVAL;
689 }
690 effect_param_t *p = (effect_param_t *) pCmdData;
691 *(int *)pReplyData = android::Equalizer_setParameter(pEqualizer, (int32_t *)p->data,
692 p->data + p->psize);
693 } break;
Eric Laurentffe9c252010-06-23 17:38:20 -0700694 case EFFECT_CMD_ENABLE:
Eric Laurente44b1ef2010-07-09 13:34:17 -0700695 if (pReplyData == NULL || *replySize != sizeof(int)) {
696 return -EINVAL;
697 }
698 if (pContext->state != EQUALIZER_STATE_INITIALIZED) {
699 return -ENOSYS;
700 }
701 pContext->state = EQUALIZER_STATE_ACTIVE;
Steve Block3856b092011-10-20 11:56:00 +0100702 ALOGV("EFFECT_CMD_ENABLE() OK");
Eric Laurente44b1ef2010-07-09 13:34:17 -0700703 *(int *)pReplyData = 0;
704 break;
Eric Laurentffe9c252010-06-23 17:38:20 -0700705 case EFFECT_CMD_DISABLE:
706 if (pReplyData == NULL || *replySize != sizeof(int)) {
707 return -EINVAL;
708 }
Eric Laurente44b1ef2010-07-09 13:34:17 -0700709 if (pContext->state != EQUALIZER_STATE_ACTIVE) {
710 return -ENOSYS;
711 }
712 pContext->state = EQUALIZER_STATE_INITIALIZED;
Steve Block3856b092011-10-20 11:56:00 +0100713 ALOGV("EFFECT_CMD_DISABLE() OK");
Eric Laurentffe9c252010-06-23 17:38:20 -0700714 *(int *)pReplyData = 0;
715 break;
716 case EFFECT_CMD_SET_DEVICE:
717 case EFFECT_CMD_SET_VOLUME:
718 case EFFECT_CMD_SET_AUDIO_MODE:
719 break;
Eric Laurent135ad072010-05-21 06:05:13 -0700720 default:
Steve Block5ff1dd52012-01-05 23:22:43 +0000721 ALOGW("Equalizer_command invalid command %d",cmdCode);
Eric Laurent135ad072010-05-21 06:05:13 -0700722 return -EINVAL;
723 }
724
725 return 0;
726}
727
Eric Laurente1315cf2011-05-17 19:16:02 -0700728extern "C" int Equalizer_getDescriptor(effect_handle_t self,
729 effect_descriptor_t *pDescriptor)
730{
731 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
732
733 if (pContext == NULL || pDescriptor == NULL) {
Steve Block3856b092011-10-20 11:56:00 +0100734 ALOGV("Equalizer_getDescriptor() invalid param");
Eric Laurente1315cf2011-05-17 19:16:02 -0700735 return -EINVAL;
736 }
737
Glenn Kastena189a682012-02-20 12:16:30 -0800738 *pDescriptor = android::gEqualizerDescriptor;
Eric Laurente1315cf2011-05-17 19:16:02 -0700739
740 return 0;
741}
742
743// effect_handle_t interface implementation for equalizer effect
Eric Laurent135ad072010-05-21 06:05:13 -0700744const struct effect_interface_s gEqualizerInterface = {
745 Equalizer_process,
Eric Laurente1315cf2011-05-17 19:16:02 -0700746 Equalizer_command,
Eric Laurentba7b8f82011-06-17 18:54:16 -0700747 Equalizer_getDescriptor,
748 NULL
Eric Laurent135ad072010-05-21 06:05:13 -0700749};
750
751
Eric Laurente1315cf2011-05-17 19:16:02 -0700752audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
753 tag : AUDIO_EFFECT_LIBRARY_TAG,
754 version : EFFECT_LIBRARY_API_VERSION,
755 name : "Test Equalizer Library",
756 implementor : "The Android Open Source Project",
Eric Laurente1315cf2011-05-17 19:16:02 -0700757 create_effect : android::EffectCreate,
758 release_effect : android::EffectRelease,
759 get_descriptor : android::EffectGetDescriptor,
760};