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