blob: db4d009a69caad8c084628f2af70f56f3e136526 [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
Mark Salyzyn60d02072016-09-29 08:48:48 -070021
Eric Laurent135ad072010-05-21 06:05:13 -070022#include <assert.h>
23#include <stdlib.h>
Eric Laurent17217ab2010-05-25 12:38:34 -070024#include <string.h>
Mark Salyzyne74bbf12017-01-12 15:10:27 -080025
Eric Laurent135ad072010-05-21 06:05:13 -070026#include <new>
Mark Salyzyn60d02072016-09-29 08:48:48 -070027
Mark Salyzyne74bbf12017-01-12 15:10:27 -080028#include <log/log.h>
Mark Salyzyn60d02072016-09-29 08:48:48 -070029
Eric Laurent135ad072010-05-21 06:05:13 -070030#include "AudioEqualizer.h"
31#include "AudioBiquadFilter.h"
32#include "AudioFormatAdapter.h"
Eric Laurent6d8b6942011-06-24 07:01:31 -070033#include <audio_effects/effect_equalizer.h>
34
Eric Laurente1315cf2011-05-17 19:16:02 -070035// effect_handle_t interface implementation for equalizer effect
Eric Laurent135ad072010-05-21 06:05:13 -070036extern "C" const struct effect_interface_s gEqualizerInterface;
37
Eric Laurente44b1ef2010-07-09 13:34:17 -070038enum equalizer_state_e {
39 EQUALIZER_STATE_UNINITIALIZED,
40 EQUALIZER_STATE_INITIALIZED,
41 EQUALIZER_STATE_ACTIVE,
42};
43
Eric Laurent135ad072010-05-21 06:05:13 -070044namespace android {
45namespace {
46
47// Google Graphic Equalizer UUID: e25aa840-543b-11df-98a5-0002a5d5c51b
48const effect_descriptor_t gEqualizerDescriptor = {
49 {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
50 {0xe25aa840, 0x543b, 0x11df, 0x98a5, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
Eric Laurente1315cf2011-05-17 19:16:02 -070051 EFFECT_CONTROL_API_VERSION,
Eric Laurent135ad072010-05-21 06:05:13 -070052 (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
Eric Laurentffe9c252010-06-23 17:38:20 -070053 0, // TODO
54 1,
Eric Laurent135ad072010-05-21 06:05:13 -070055 "Graphic Equalizer",
Eric Laurente1315cf2011-05-17 19:16:02 -070056 "The Android Open Source Project",
Eric Laurent135ad072010-05-21 06:05:13 -070057};
Eric Laurent135ad072010-05-21 06:05:13 -070058
59/////////////////// BEGIN EQ PRESETS ///////////////////////////////////////////
60const int kNumBands = 5;
61const uint32_t gFreqs[kNumBands] = { 50000, 125000, 900000, 3200000, 6300000 };
62const uint32_t gBandwidths[kNumBands] = { 0, 3600, 3600, 2400, 0 };
63
64const AudioEqualizer::BandConfig gBandsClassic[kNumBands] = {
65 { 300, gFreqs[0], gBandwidths[0] },
66 { 400, gFreqs[1], gBandwidths[1] },
67 { 0, gFreqs[2], gBandwidths[2] },
68 { 200, gFreqs[3], gBandwidths[3] },
69 { -300, gFreqs[4], gBandwidths[4] }
70};
71
72const AudioEqualizer::BandConfig gBandsJazz[kNumBands] = {
73 { -600, gFreqs[0], gBandwidths[0] },
74 { 200, gFreqs[1], gBandwidths[1] },
75 { 400, gFreqs[2], gBandwidths[2] },
76 { -400, gFreqs[3], gBandwidths[3] },
77 { -600, gFreqs[4], gBandwidths[4] }
78};
79
80const AudioEqualizer::BandConfig gBandsPop[kNumBands] = {
81 { 400, gFreqs[0], gBandwidths[0] },
82 { -400, gFreqs[1], gBandwidths[1] },
83 { 300, gFreqs[2], gBandwidths[2] },
84 { -400, gFreqs[3], gBandwidths[3] },
85 { 600, gFreqs[4], gBandwidths[4] }
86};
87
88const AudioEqualizer::BandConfig gBandsRock[kNumBands] = {
89 { 700, gFreqs[0], gBandwidths[0] },
90 { 400, gFreqs[1], gBandwidths[1] },
91 { -400, gFreqs[2], gBandwidths[2] },
92 { 400, gFreqs[3], gBandwidths[3] },
93 { 200, gFreqs[4], gBandwidths[4] }
94};
95
96const AudioEqualizer::PresetConfig gEqualizerPresets[] = {
97 { "Classic", gBandsClassic },
98 { "Jazz", gBandsJazz },
99 { "Pop", gBandsPop },
100 { "Rock", gBandsRock }
101};
102
103/////////////////// END EQ PRESETS /////////////////////////////////////////////
104
105static const size_t kBufferSize = 32;
106
107typedef AudioFormatAdapter<AudioEqualizer, kBufferSize> FormatAdapter;
108
109struct EqualizerContext {
110 const struct effect_interface_s *itfe;
111 effect_config_t config;
112 FormatAdapter adapter;
113 AudioEqualizer * pEqualizer;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700114 uint32_t state;
Eric Laurent135ad072010-05-21 06:05:13 -0700115};
116
Eric Laurent135ad072010-05-21 06:05:13 -0700117//--- local function prototypes
118
119int Equalizer_init(EqualizerContext *pContext);
Eric Laurent3d5188b2011-12-16 15:30:36 -0800120int Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig);
Ashok Bhatb302bd52014-02-18 11:40:00 +0000121int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, uint32_t *pValueSize, void *pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700122int Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue);
123
124
125//
126//--- Effect Library Interface Implementation
127//
128
Glenn Kasten5e92a782012-01-30 07:40:52 -0800129extern "C" int EffectCreate(const effect_uuid_t *uuid,
Eric Laurente1315cf2011-05-17 19:16:02 -0700130 int32_t sessionId,
131 int32_t ioId,
132 effect_handle_t *pHandle) {
Eric Laurent135ad072010-05-21 06:05:13 -0700133 int ret;
134 int i;
135
Steve Block3856b092011-10-20 11:56:00 +0100136 ALOGV("EffectLibCreateEffect start");
Eric Laurent135ad072010-05-21 06:05:13 -0700137
Eric Laurente1315cf2011-05-17 19:16:02 -0700138 if (pHandle == NULL || uuid == NULL) {
Eric Laurent135ad072010-05-21 06:05:13 -0700139 return -EINVAL;
140 }
141
142 if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) != 0) {
143 return -EINVAL;
144 }
145
146 EqualizerContext *pContext = new EqualizerContext;
147
148 pContext->itfe = &gEqualizerInterface;
149 pContext->pEqualizer = NULL;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700150 pContext->state = EQUALIZER_STATE_UNINITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700151
152 ret = Equalizer_init(pContext);
153 if (ret < 0) {
Steve Block5ff1dd52012-01-05 23:22:43 +0000154 ALOGW("EffectLibCreateEffect() init failed");
Eric Laurent135ad072010-05-21 06:05:13 -0700155 delete pContext;
156 return ret;
157 }
158
Eric Laurente1315cf2011-05-17 19:16:02 -0700159 *pHandle = (effect_handle_t)pContext;
Eric Laurente44b1ef2010-07-09 13:34:17 -0700160 pContext->state = EQUALIZER_STATE_INITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700161
Steve Block3856b092011-10-20 11:56:00 +0100162 ALOGV("EffectLibCreateEffect %p, size %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700163 pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext));
Eric Laurent135ad072010-05-21 06:05:13 -0700164
165 return 0;
166
167} /* end EffectCreate */
168
Eric Laurente1315cf2011-05-17 19:16:02 -0700169extern "C" int EffectRelease(effect_handle_t handle) {
170 EqualizerContext * pContext = (EqualizerContext *)handle;
Eric Laurent135ad072010-05-21 06:05:13 -0700171
Steve Block3856b092011-10-20 11:56:00 +0100172 ALOGV("EffectLibReleaseEffect %p", handle);
Eric Laurent135ad072010-05-21 06:05:13 -0700173 if (pContext == NULL) {
174 return -EINVAL;
175 }
176
Eric Laurente44b1ef2010-07-09 13:34:17 -0700177 pContext->state = EQUALIZER_STATE_UNINITIALIZED;
Eric Laurent135ad072010-05-21 06:05:13 -0700178 pContext->pEqualizer->free();
179 delete pContext;
180
181 return 0;
182} /* end EffectRelease */
183
Glenn Kasten5e92a782012-01-30 07:40:52 -0800184extern "C" int EffectGetDescriptor(const effect_uuid_t *uuid,
Eric Laurente1315cf2011-05-17 19:16:02 -0700185 effect_descriptor_t *pDescriptor) {
186
187 if (pDescriptor == NULL || uuid == NULL){
Steve Block3856b092011-10-20 11:56:00 +0100188 ALOGV("EffectGetDescriptor() called with NULL pointer");
Eric Laurente1315cf2011-05-17 19:16:02 -0700189 return -EINVAL;
190 }
191
192 if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
Glenn Kastena189a682012-02-20 12:16:30 -0800193 *pDescriptor = gEqualizerDescriptor;
Eric Laurente1315cf2011-05-17 19:16:02 -0700194 return 0;
195 }
196
197 return -EINVAL;
198} /* end EffectGetDescriptor */
199
Eric Laurent135ad072010-05-21 06:05:13 -0700200
201//
202//--- local functions
203//
204
205#define CHECK_ARG(cond) { \
206 if (!(cond)) { \
Steve Block3856b092011-10-20 11:56:00 +0100207 ALOGV("Invalid argument: "#cond); \
Eric Laurent135ad072010-05-21 06:05:13 -0700208 return -EINVAL; \
209 } \
210}
211
212//----------------------------------------------------------------------------
Eric Laurent3d5188b2011-12-16 15:30:36 -0800213// Equalizer_setConfig()
Eric Laurent135ad072010-05-21 06:05:13 -0700214//----------------------------------------------------------------------------
215// Purpose: Set input and output audio configuration.
216//
217// Inputs:
218// pContext: effect engine context
219// pConfig: pointer to effect_config_t structure holding input and output
220// configuration parameters
221//
222// Outputs:
223//
224//----------------------------------------------------------------------------
225
Eric Laurent3d5188b2011-12-16 15:30:36 -0800226int Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig)
Eric Laurent135ad072010-05-21 06:05:13 -0700227{
Eric Laurent3d5188b2011-12-16 15:30:36 -0800228 ALOGV("Equalizer_setConfig start");
Eric Laurent135ad072010-05-21 06:05:13 -0700229
230 CHECK_ARG(pContext != NULL);
231 CHECK_ARG(pConfig != NULL);
232
233 CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
234 CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
235 CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
Eric Laurente1315cf2011-05-17 19:16:02 -0700236 CHECK_ARG((pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) ||
237 (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO));
Eric Laurent135ad072010-05-21 06:05:13 -0700238 CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
239 || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
Glenn Kastenb7f08d32013-06-18 11:46:28 -0700240 CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT);
Eric Laurent135ad072010-05-21 06:05:13 -0700241
242 int channelCount;
Eric Laurente1315cf2011-05-17 19:16:02 -0700243 if (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) {
Eric Laurent135ad072010-05-21 06:05:13 -0700244 channelCount = 1;
245 } else {
246 channelCount = 2;
247 }
248 CHECK_ARG(channelCount <= AudioBiquadFilter::MAX_CHANNELS);
249
Glenn Kastena189a682012-02-20 12:16:30 -0800250 pContext->config = *pConfig;
Eric Laurentffe9c252010-06-23 17:38:20 -0700251
Eric Laurent135ad072010-05-21 06:05:13 -0700252 pContext->pEqualizer->configure(channelCount,
253 pConfig->inputCfg.samplingRate);
254
255 pContext->adapter.configure(*pContext->pEqualizer, channelCount,
256 pConfig->inputCfg.format,
257 pConfig->outputCfg.accessMode);
258
259 return 0;
Eric Laurent3d5188b2011-12-16 15:30:36 -0800260} // end Equalizer_setConfig
261
262//----------------------------------------------------------------------------
263// Equalizer_getConfig()
264//----------------------------------------------------------------------------
265// Purpose: Get input and output audio configuration.
266//
267// Inputs:
268// pContext: effect engine context
269// pConfig: pointer to effect_config_t structure holding input and output
270// configuration parameters
271//
272// Outputs:
273//
274//----------------------------------------------------------------------------
275
276void Equalizer_getConfig(EqualizerContext *pContext, effect_config_t *pConfig)
277{
Glenn Kastena189a682012-02-20 12:16:30 -0800278 *pConfig = pContext->config;
Eric Laurent3d5188b2011-12-16 15:30:36 -0800279} // end Equalizer_getConfig
Eric Laurent135ad072010-05-21 06:05:13 -0700280
281
282//----------------------------------------------------------------------------
283// Equalizer_init()
284//----------------------------------------------------------------------------
285// Purpose: Initialize engine with default configuration and creates
286// AudioEqualizer instance.
287//
288// Inputs:
289// pContext: effect engine context
290//
291// Outputs:
292//
293//----------------------------------------------------------------------------
294
295int Equalizer_init(EqualizerContext *pContext)
296{
297 int status;
298
Steve Block3856b092011-10-20 11:56:00 +0100299 ALOGV("Equalizer_init start");
Eric Laurent135ad072010-05-21 06:05:13 -0700300
301 CHECK_ARG(pContext != NULL);
302
303 if (pContext->pEqualizer != NULL) {
304 pContext->pEqualizer->free();
305 }
306
307 pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
Eric Laurente1315cf2011-05-17 19:16:02 -0700308 pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
309 pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
Eric Laurent135ad072010-05-21 06:05:13 -0700310 pContext->config.inputCfg.samplingRate = 44100;
311 pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
312 pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
313 pContext->config.inputCfg.bufferProvider.cookie = NULL;
314 pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
315 pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
Eric Laurente1315cf2011-05-17 19:16:02 -0700316 pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
317 pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
Eric Laurent135ad072010-05-21 06:05:13 -0700318 pContext->config.outputCfg.samplingRate = 44100;
319 pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
320 pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
321 pContext->config.outputCfg.bufferProvider.cookie = NULL;
322 pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL;
323
324 pContext->pEqualizer = AudioEqualizer::CreateInstance(
325 NULL,
326 kNumBands,
327 AudioBiquadFilter::MAX_CHANNELS,
328 44100,
329 gEqualizerPresets,
330 ARRAY_SIZE(gEqualizerPresets));
331
332 for (int i = 0; i < kNumBands; ++i) {
333 pContext->pEqualizer->setFrequency(i, gFreqs[i]);
334 pContext->pEqualizer->setBandwidth(i, gBandwidths[i]);
335 }
336
337 pContext->pEqualizer->enable(true);
338
Eric Laurent3d5188b2011-12-16 15:30:36 -0800339 Equalizer_setConfig(pContext, &pContext->config);
Eric Laurent135ad072010-05-21 06:05:13 -0700340
341 return 0;
342} // end Equalizer_init
343
344
345//----------------------------------------------------------------------------
346// Equalizer_getParameter()
347//----------------------------------------------------------------------------
348// Purpose:
349// Get a Equalizer parameter
350//
351// Inputs:
352// pEqualizer - handle to instance data
353// pParam - pointer to parameter
354// pValue - pointer to variable to hold retrieved value
355// pValueSize - pointer to value size: maximum size as input
356//
357// Outputs:
358// *pValue updated with parameter value
359// *pValueSize updated with actual value size
360//
361//
362// Side Effects:
363//
364//----------------------------------------------------------------------------
365
Ashok Bhatb302bd52014-02-18 11:40:00 +0000366int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, uint32_t *pValueSize, void *pValue)
Eric Laurent135ad072010-05-21 06:05:13 -0700367{
368 int status = 0;
369 int32_t param = *pParam++;
370 int32_t param2;
371 char *name;
372
373 switch (param) {
374 case EQ_PARAM_NUM_BANDS:
375 case EQ_PARAM_CUR_PRESET:
376 case EQ_PARAM_GET_NUM_OF_PRESETS:
Eric Laurent3be95232010-07-30 09:12:51 -0700377 case EQ_PARAM_BAND_LEVEL:
378 case EQ_PARAM_GET_BAND:
Eric Laurent135ad072010-05-21 06:05:13 -0700379 if (*pValueSize < sizeof(int16_t)) {
380 return -EINVAL;
381 }
382 *pValueSize = sizeof(int16_t);
383 break;
384
385 case EQ_PARAM_LEVEL_RANGE:
Eric Laurent3be95232010-07-30 09:12:51 -0700386 if (*pValueSize < 2 * sizeof(int16_t)) {
387 return -EINVAL;
388 }
389 *pValueSize = 2 * sizeof(int16_t);
390 break;
391
Eric Laurent135ad072010-05-21 06:05:13 -0700392 case EQ_PARAM_BAND_FREQ_RANGE:
393 if (*pValueSize < 2 * sizeof(int32_t)) {
394 return -EINVAL;
395 }
396 *pValueSize = 2 * sizeof(int32_t);
397 break;
Eric Laurent3be95232010-07-30 09:12:51 -0700398
Eric Laurent135ad072010-05-21 06:05:13 -0700399 case EQ_PARAM_CENTER_FREQ:
400 if (*pValueSize < sizeof(int32_t)) {
401 return -EINVAL;
402 }
403 *pValueSize = sizeof(int32_t);
404 break;
405
406 case EQ_PARAM_GET_PRESET_NAME:
407 break;
408
Eric Laurent3be95232010-07-30 09:12:51 -0700409 case EQ_PARAM_PROPERTIES:
410 if (*pValueSize < (2 + kNumBands) * sizeof(uint16_t)) {
411 return -EINVAL;
412 }
413 *pValueSize = (2 + kNumBands) * sizeof(uint16_t);
414 break;
415
Eric Laurent135ad072010-05-21 06:05:13 -0700416 default:
417 return -EINVAL;
418 }
419
420 switch (param) {
421 case EQ_PARAM_NUM_BANDS:
Eric Laurent3be95232010-07-30 09:12:51 -0700422 *(uint16_t *)pValue = (uint16_t)kNumBands;
Steve Block3856b092011-10-20 11:56:00 +0100423 ALOGV("Equalizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700424 break;
425
426 case EQ_PARAM_LEVEL_RANGE:
Eric Laurent3be95232010-07-30 09:12:51 -0700427 *(int16_t *)pValue = -9600;
428 *((int16_t *)pValue + 1) = 4800;
Steve Block3856b092011-10-20 11:56:00 +0100429 ALOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700430 *(int32_t *)pValue, *((int32_t *)pValue + 1));
Eric Laurent135ad072010-05-21 06:05:13 -0700431 break;
432
433 case EQ_PARAM_BAND_LEVEL:
434 param2 = *pParam;
435 if (param2 >= kNumBands) {
436 status = -EINVAL;
437 break;
438 }
Eric Laurent3be95232010-07-30 09:12:51 -0700439 *(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2);
Steve Block3856b092011-10-20 11:56:00 +0100440 ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700441 param2, *(int32_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700442 break;
443
444 case EQ_PARAM_CENTER_FREQ:
445 param2 = *pParam;
446 if (param2 >= kNumBands) {
447 status = -EINVAL;
448 break;
449 }
450 *(int32_t *)pValue = pEqualizer->getFrequency(param2);
Steve Block3856b092011-10-20 11:56:00 +0100451 ALOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700452 param2, *(int32_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700453 break;
454
455 case EQ_PARAM_BAND_FREQ_RANGE:
456 param2 = *pParam;
457 if (param2 >= kNumBands) {
458 status = -EINVAL;
459 break;
460 }
461 pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1));
Steve Block3856b092011-10-20 11:56:00 +0100462 ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700463 param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
Eric Laurent135ad072010-05-21 06:05:13 -0700464 break;
465
466 case EQ_PARAM_GET_BAND:
467 param2 = *pParam;
Eric Laurent3be95232010-07-30 09:12:51 -0700468 *(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2);
Steve Block3856b092011-10-20 11:56:00 +0100469 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700470 param2, *(int32_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700471 break;
472
473 case EQ_PARAM_CUR_PRESET:
Eric Laurent3be95232010-07-30 09:12:51 -0700474 *(uint16_t *)pValue = (uint16_t)pEqualizer->getPreset();
Steve Block3856b092011-10-20 11:56:00 +0100475 ALOGV("Equalizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700476 break;
477
478 case EQ_PARAM_GET_NUM_OF_PRESETS:
Eric Laurent3be95232010-07-30 09:12:51 -0700479 *(uint16_t *)pValue = (uint16_t)pEqualizer->getNumPresets();
Steve Block3856b092011-10-20 11:56:00 +0100480 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700481 break;
482
483 case EQ_PARAM_GET_PRESET_NAME:
484 param2 = *pParam;
485 if (param2 >= pEqualizer->getNumPresets()) {
486 status = -EINVAL;
487 break;
488 }
489 name = (char *)pValue;
490 strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1);
491 name[*pValueSize - 1] = 0;
492 *pValueSize = strlen(name) + 1;
Steve Block3856b092011-10-20 11:56:00 +0100493 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d",
Eric Laurente1315cf2011-05-17 19:16:02 -0700494 param2, gEqualizerPresets[param2].name, *pValueSize);
Eric Laurent135ad072010-05-21 06:05:13 -0700495 break;
496
Eric Laurent3be95232010-07-30 09:12:51 -0700497 case EQ_PARAM_PROPERTIES: {
498 int16_t *p = (int16_t *)pValue;
Steve Block3856b092011-10-20 11:56:00 +0100499 ALOGV("Equalizer_getParameter() EQ_PARAM_PROPERTIES");
Eric Laurent3be95232010-07-30 09:12:51 -0700500 p[0] = (int16_t)pEqualizer->getPreset();
501 p[1] = (int16_t)kNumBands;
502 for (int i = 0; i < kNumBands; i++) {
503 p[2 + i] = (int16_t)pEqualizer->getGain(i);
504 }
505 } break;
506
Eric Laurent135ad072010-05-21 06:05:13 -0700507 default:
Steve Block3856b092011-10-20 11:56:00 +0100508 ALOGV("Equalizer_getParameter() invalid param %d", param);
Eric Laurent135ad072010-05-21 06:05:13 -0700509 status = -EINVAL;
510 break;
511 }
512
513 return status;
514} // end Equalizer_getParameter
515
516
517//----------------------------------------------------------------------------
518// Equalizer_setParameter()
519//----------------------------------------------------------------------------
520// Purpose:
521// Set a Equalizer parameter
522//
523// Inputs:
524// pEqualizer - handle to instance data
525// pParam - pointer to parameter
526// pValue - pointer to value
527//
528// Outputs:
529//
530//
531// Side Effects:
532//
533//----------------------------------------------------------------------------
534
535int Equalizer_setParameter (AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue)
536{
537 int status = 0;
538 int32_t preset;
539 int32_t band;
540 int32_t level;
541 int32_t param = *pParam++;
542
543
544 switch (param) {
545 case EQ_PARAM_CUR_PRESET:
Eric Laurent3be95232010-07-30 09:12:51 -0700546 preset = (int32_t)(*(uint16_t *)pValue);
Eric Laurent135ad072010-05-21 06:05:13 -0700547
Steve Block3856b092011-10-20 11:56:00 +0100548 ALOGV("setParameter() EQ_PARAM_CUR_PRESET %d", preset);
Eric Laurent3be95232010-07-30 09:12:51 -0700549 if (preset < 0 || preset >= pEqualizer->getNumPresets()) {
Eric Laurent135ad072010-05-21 06:05:13 -0700550 status = -EINVAL;
551 break;
552 }
553 pEqualizer->setPreset(preset);
554 pEqualizer->commit(true);
555 break;
556 case EQ_PARAM_BAND_LEVEL:
557 band = *pParam;
Eric Laurent3be95232010-07-30 09:12:51 -0700558 level = (int32_t)(*(int16_t *)pValue);
Steve Block3856b092011-10-20 11:56:00 +0100559 ALOGV("setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level);
Eric Laurent135ad072010-05-21 06:05:13 -0700560 if (band >= kNumBands) {
561 status = -EINVAL;
562 break;
563 }
564 pEqualizer->setGain(band, level);
565 pEqualizer->commit(true);
566 break;
Eric Laurent3be95232010-07-30 09:12:51 -0700567 case EQ_PARAM_PROPERTIES: {
Steve Block3856b092011-10-20 11:56:00 +0100568 ALOGV("setParameter() EQ_PARAM_PROPERTIES");
Eric Laurent3be95232010-07-30 09:12:51 -0700569 int16_t *p = (int16_t *)pValue;
570 if ((int)p[0] >= pEqualizer->getNumPresets()) {
571 status = -EINVAL;
572 break;
573 }
574 if (p[0] >= 0) {
575 pEqualizer->setPreset((int)p[0]);
576 } else {
577 if ((int)p[1] != kNumBands) {
578 status = -EINVAL;
579 break;
580 }
581 for (int i = 0; i < kNumBands; i++) {
582 pEqualizer->setGain(i, (int32_t)p[2 + i]);
583 }
584 }
585 pEqualizer->commit(true);
586 } break;
Eric Laurent135ad072010-05-21 06:05:13 -0700587 default:
Steve Block3856b092011-10-20 11:56:00 +0100588 ALOGV("setParameter() invalid param %d", param);
Eric Laurent3be95232010-07-30 09:12:51 -0700589 status = -EINVAL;
Eric Laurent135ad072010-05-21 06:05:13 -0700590 break;
591 }
592
593 return status;
594} // end Equalizer_setParameter
595
596} // namespace
597} // namespace
598
599
600//
601//--- Effect Control Interface Implementation
602//
603
Eric Laurente1315cf2011-05-17 19:16:02 -0700604extern "C" int Equalizer_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
Eric Laurent135ad072010-05-21 06:05:13 -0700605{
606 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
607
608 if (pContext == NULL) {
609 return -EINVAL;
610 }
611 if (inBuffer == NULL || inBuffer->raw == NULL ||
612 outBuffer == NULL || outBuffer->raw == NULL ||
613 inBuffer->frameCount != outBuffer->frameCount) {
614 return -EINVAL;
615 }
616
Eric Laurente44b1ef2010-07-09 13:34:17 -0700617 if (pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
618 return -EINVAL;
619 }
620 if (pContext->state == EQUALIZER_STATE_INITIALIZED) {
621 return -ENODATA;
622 }
623
Eric Laurent135ad072010-05-21 06:05:13 -0700624 pContext->adapter.process(inBuffer->raw, outBuffer->raw, outBuffer->frameCount);
Eric Laurentffe9c252010-06-23 17:38:20 -0700625
Eric Laurent135ad072010-05-21 06:05:13 -0700626 return 0;
627} // end Equalizer_process
628
Eric Laurente1315cf2011-05-17 19:16:02 -0700629extern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
Eric Laurent25f43952010-07-28 05:40:18 -0700630 void *pCmdData, uint32_t *replySize, void *pReplyData) {
Eric Laurent135ad072010-05-21 06:05:13 -0700631
632 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
633 int retsize;
634
Eric Laurente44b1ef2010-07-09 13:34:17 -0700635 if (pContext == NULL || pContext->state == EQUALIZER_STATE_UNINITIALIZED) {
Eric Laurent135ad072010-05-21 06:05:13 -0700636 return -EINVAL;
637 }
638
639 android::AudioEqualizer * pEqualizer = pContext->pEqualizer;
640
Steve Block3856b092011-10-20 11:56:00 +0100641 ALOGV("Equalizer_command command %d cmdSize %d",cmdCode, cmdSize);
Eric Laurent135ad072010-05-21 06:05:13 -0700642
643 switch (cmdCode) {
644 case EFFECT_CMD_INIT:
645 if (pReplyData == NULL || *replySize != sizeof(int)) {
646 return -EINVAL;
647 }
648 *(int *) pReplyData = Equalizer_init(pContext);
649 break;
Eric Laurent3d5188b2011-12-16 15:30:36 -0800650 case EFFECT_CMD_SET_CONFIG:
Eric Laurent135ad072010-05-21 06:05:13 -0700651 if (pCmdData == NULL || cmdSize != sizeof(effect_config_t)
652 || pReplyData == NULL || *replySize != sizeof(int)) {
653 return -EINVAL;
654 }
Eric Laurent3d5188b2011-12-16 15:30:36 -0800655 *(int *) pReplyData = Equalizer_setConfig(pContext,
Eric Laurent135ad072010-05-21 06:05:13 -0700656 (effect_config_t *) pCmdData);
657 break;
Eric Laurent3d5188b2011-12-16 15:30:36 -0800658 case EFFECT_CMD_GET_CONFIG:
659 if (pReplyData == NULL || *replySize != sizeof(effect_config_t)) {
660 return -EINVAL;
661 }
662 Equalizer_getConfig(pContext, (effect_config_t *) pCmdData);
663 break;
Eric Laurent135ad072010-05-21 06:05:13 -0700664 case EFFECT_CMD_RESET:
Eric Laurent3d5188b2011-12-16 15:30:36 -0800665 Equalizer_setConfig(pContext, &pContext->config);
Eric Laurent135ad072010-05-21 06:05:13 -0700666 break;
667 case EFFECT_CMD_GET_PARAM: {
Ashok Bhatb302bd52014-02-18 11:40:00 +0000668 if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
669 pReplyData == NULL || *replySize < (sizeof(effect_param_t) + sizeof(int32_t))) {
Eric Laurent135ad072010-05-21 06:05:13 -0700670 return -EINVAL;
671 }
672 effect_param_t *p = (effect_param_t *)pCmdData;
673 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
674 p = (effect_param_t *)pReplyData;
675 int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
676 p->status = android::Equalizer_getParameter(pEqualizer, (int32_t *)p->data, &p->vsize,
677 p->data + voffset);
678 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
Steve Block3856b092011-10-20 11:56:00 +0100679 ALOGV("Equalizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x",
Eric Laurent135ad072010-05-21 06:05:13 -0700680 *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize,
681 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset),
682 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset + sizeof(int32_t)));
683
684 } break;
685 case EFFECT_CMD_SET_PARAM: {
Steve Block3856b092011-10-20 11:56:00 +0100686 ALOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p",
Eric Laurente1315cf2011-05-17 19:16:02 -0700687 cmdSize, pCmdData, *replySize, pReplyData);
Ashok Bhatb302bd52014-02-18 11:40:00 +0000688 if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
Eric Laurent135ad072010-05-21 06:05:13 -0700689 pReplyData == NULL || *replySize != sizeof(int32_t)) {
690 return -EINVAL;
691 }
692 effect_param_t *p = (effect_param_t *) pCmdData;
693 *(int *)pReplyData = android::Equalizer_setParameter(pEqualizer, (int32_t *)p->data,
694 p->data + p->psize);
695 } break;
Eric Laurentffe9c252010-06-23 17:38:20 -0700696 case EFFECT_CMD_ENABLE:
Eric Laurente44b1ef2010-07-09 13:34:17 -0700697 if (pReplyData == NULL || *replySize != sizeof(int)) {
698 return -EINVAL;
699 }
700 if (pContext->state != EQUALIZER_STATE_INITIALIZED) {
701 return -ENOSYS;
702 }
703 pContext->state = EQUALIZER_STATE_ACTIVE;
Steve Block3856b092011-10-20 11:56:00 +0100704 ALOGV("EFFECT_CMD_ENABLE() OK");
Eric Laurente44b1ef2010-07-09 13:34:17 -0700705 *(int *)pReplyData = 0;
706 break;
Eric Laurentffe9c252010-06-23 17:38:20 -0700707 case EFFECT_CMD_DISABLE:
708 if (pReplyData == NULL || *replySize != sizeof(int)) {
709 return -EINVAL;
710 }
Eric Laurente44b1ef2010-07-09 13:34:17 -0700711 if (pContext->state != EQUALIZER_STATE_ACTIVE) {
712 return -ENOSYS;
713 }
714 pContext->state = EQUALIZER_STATE_INITIALIZED;
Steve Block3856b092011-10-20 11:56:00 +0100715 ALOGV("EFFECT_CMD_DISABLE() OK");
Eric Laurentffe9c252010-06-23 17:38:20 -0700716 *(int *)pReplyData = 0;
717 break;
718 case EFFECT_CMD_SET_DEVICE:
719 case EFFECT_CMD_SET_VOLUME:
720 case EFFECT_CMD_SET_AUDIO_MODE:
721 break;
Eric Laurent135ad072010-05-21 06:05:13 -0700722 default:
Steve Block5ff1dd52012-01-05 23:22:43 +0000723 ALOGW("Equalizer_command invalid command %d",cmdCode);
Eric Laurent135ad072010-05-21 06:05:13 -0700724 return -EINVAL;
725 }
726
727 return 0;
728}
729
Eric Laurente1315cf2011-05-17 19:16:02 -0700730extern "C" int Equalizer_getDescriptor(effect_handle_t self,
731 effect_descriptor_t *pDescriptor)
732{
733 android::EqualizerContext * pContext = (android::EqualizerContext *) self;
734
735 if (pContext == NULL || pDescriptor == NULL) {
Steve Block3856b092011-10-20 11:56:00 +0100736 ALOGV("Equalizer_getDescriptor() invalid param");
Eric Laurente1315cf2011-05-17 19:16:02 -0700737 return -EINVAL;
738 }
739
Glenn Kastena189a682012-02-20 12:16:30 -0800740 *pDescriptor = android::gEqualizerDescriptor;
Eric Laurente1315cf2011-05-17 19:16:02 -0700741
742 return 0;
743}
744
745// effect_handle_t interface implementation for equalizer effect
Eric Laurent135ad072010-05-21 06:05:13 -0700746const struct effect_interface_s gEqualizerInterface = {
747 Equalizer_process,
Eric Laurente1315cf2011-05-17 19:16:02 -0700748 Equalizer_command,
Eric Laurentba7b8f82011-06-17 18:54:16 -0700749 Equalizer_getDescriptor,
750 NULL
Eric Laurent135ad072010-05-21 06:05:13 -0700751};
752
753
Eric Laurente1315cf2011-05-17 19:16:02 -0700754audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
755 tag : AUDIO_EFFECT_LIBRARY_TAG,
756 version : EFFECT_LIBRARY_API_VERSION,
757 name : "Test Equalizer Library",
758 implementor : "The Android Open Source Project",
Eric Laurente1315cf2011-05-17 19:16:02 -0700759 create_effect : android::EffectCreate,
760 release_effect : android::EffectRelease,
761 get_descriptor : android::EffectGetDescriptor,
762};