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]) 19 // 20 #define LOG_NDEBUG 0 21 #include <cutils/log.h> 22 #include <assert.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <new> 26 #include "AudioEqualizer.h" 27 #include "AudioBiquadFilter.h" 28 #include "AudioFormatAdapter.h" 29 #include <audio_effects/effect_equalizer.h> 30 31 32 // effect_handle_t interface implementation for equalizer effect 33 extern "C" const struct effect_interface_s gEqualizerInterface; 34 35 enum equalizer_state_e { 36 EQUALIZER_STATE_UNINITIALIZED, 37 EQUALIZER_STATE_INITIALIZED, 38 EQUALIZER_STATE_ACTIVE, 39 }; 40 41 namespace android { 42 namespace { 43 44 // Google Graphic Equalizer UUID: e25aa840-543b-11df-98a5-0002a5d5c51b 45 const 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 48 EFFECT_CONTROL_API_VERSION, 49 (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST), 50 0, // TODO 51 1, 52 "Graphic Equalizer", 53 "The Android Open Source Project", 54 }; 55 56 /////////////////// BEGIN EQ PRESETS /////////////////////////////////////////// 57 const int kNumBands = 5; 58 const uint32_t gFreqs[kNumBands] = { 50000, 125000, 900000, 3200000, 6300000 }; 59 const uint32_t gBandwidths[kNumBands] = { 0, 3600, 3600, 2400, 0 }; 60 61 const 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 69 const 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 77 const 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 85 const 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 93 const AudioEqualizer::PresetConfig gEqualizerPresets[] = { 94 { "Classic", gBandsClassic }, 95 { "Jazz", gBandsJazz }, 96 { "Pop", gBandsPop }, 97 { "Rock", gBandsRock } 98 }; 99 100 /////////////////// END EQ PRESETS ///////////////////////////////////////////// 101 102 static const size_t kBufferSize = 32; 103 104 typedef AudioFormatAdapter<AudioEqualizer, kBufferSize> FormatAdapter; 105 106 struct EqualizerContext { 107 const struct effect_interface_s *itfe; 108 effect_config_t config; 109 FormatAdapter adapter; 110 AudioEqualizer * pEqualizer; 111 uint32_t state; 112 }; 113 114 //--- local function prototypes 115 116 int Equalizer_init(EqualizerContext *pContext); 117 int Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig); 118 int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, uint32_t *pValueSize, void *pValue); 119 int Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue); 120 121 122 // 123 //--- Effect Library Interface Implementation 124 // 125 126 extern "C" int EffectCreate(const effect_uuid_t *uuid, 127 int32_t sessionId, 128 int32_t ioId, 129 effect_handle_t *pHandle) { 130 int ret; 131 int i; 132 133 ALOGV("EffectLibCreateEffect start"); 134 135 if (pHandle == NULL || uuid == NULL) { 136 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; 147 pContext->state = EQUALIZER_STATE_UNINITIALIZED; 148 149 ret = Equalizer_init(pContext); 150 if (ret < 0) { 151 ALOGW("EffectLibCreateEffect() init failed"); 152 delete pContext; 153 return ret; 154 } 155 156 *pHandle = (effect_handle_t)pContext; 157 pContext->state = EQUALIZER_STATE_INITIALIZED; 158 159 ALOGV("EffectLibCreateEffect %p, size %d", 160 pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext)); 161 162 return 0; 163 164 } /* end EffectCreate */ 165 166 extern "C" int EffectRelease(effect_handle_t handle) { 167 EqualizerContext * pContext = (EqualizerContext *)handle; 168 169 ALOGV("EffectLibReleaseEffect %p", handle); 170 if (pContext == NULL) { 171 return -EINVAL; 172 } 173 174 pContext->state = EQUALIZER_STATE_UNINITIALIZED; 175 pContext->pEqualizer->free(); 176 delete pContext; 177 178 return 0; 179 } /* end EffectRelease */ 180 181 extern "C" int EffectGetDescriptor(const effect_uuid_t *uuid, 182 effect_descriptor_t *pDescriptor) { 183 184 if (pDescriptor == NULL || uuid == NULL){ 185 ALOGV("EffectGetDescriptor() called with NULL pointer"); 186 return -EINVAL; 187 } 188 189 if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) { 190 *pDescriptor = gEqualizerDescriptor; 191 return 0; 192 } 193 194 return -EINVAL; 195 } /* end EffectGetDescriptor */ 196 197 198 // 199 //--- local functions 200 // 201 202 #define CHECK_ARG(cond) { \ 203 if (!(cond)) { \ 204 ALOGV("Invalid argument: "#cond); \ 205 return -EINVAL; \ 206 } \ 207 } 208 209 //---------------------------------------------------------------------------- 210 // Equalizer_setConfig() 211 //---------------------------------------------------------------------------- 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 223 int Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig) 224 { 225 ALOGV("Equalizer_setConfig start"); 226 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); 233 CHECK_ARG((pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) || 234 (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO)); 235 CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE 236 || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE); 237 CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT); 238 239 int channelCount; 240 if (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) { 241 channelCount = 1; 242 } else { 243 channelCount = 2; 244 } 245 CHECK_ARG(channelCount <= AudioBiquadFilter::MAX_CHANNELS); 246 247 pContext->config = *pConfig; 248 249 pContext->pEqualizer->configure(channelCount, 250 pConfig->inputCfg.samplingRate); 251 252 pContext->adapter.configure(*pContext->pEqualizer, channelCount, 253 pConfig->inputCfg.format, 254 pConfig->outputCfg.accessMode); 255 256 return 0; 257 } // end Equalizer_setConfig 258 259 //---------------------------------------------------------------------------- 260 // Equalizer_getConfig() 261 //---------------------------------------------------------------------------- 262 // Purpose: Get input and output audio configuration. 263 // 264 // Inputs: 265 // pContext: effect engine context 266 // pConfig: pointer to effect_config_t structure holding input and output 267 // configuration parameters 268 // 269 // Outputs: 270 // 271 //---------------------------------------------------------------------------- 272 273 void Equalizer_getConfig(EqualizerContext *pContext, effect_config_t *pConfig) 274 { 275 *pConfig = pContext->config; 276 } // end Equalizer_getConfig 277 278 279 //---------------------------------------------------------------------------- 280 // Equalizer_init() 281 //---------------------------------------------------------------------------- 282 // Purpose: Initialize engine with default configuration and creates 283 // AudioEqualizer instance. 284 // 285 // Inputs: 286 // pContext: effect engine context 287 // 288 // Outputs: 289 // 290 //---------------------------------------------------------------------------- 291 292 int Equalizer_init(EqualizerContext *pContext) 293 { 294 int status; 295 296 ALOGV("Equalizer_init start"); 297 298 CHECK_ARG(pContext != NULL); 299 300 if (pContext->pEqualizer != NULL) { 301 pContext->pEqualizer->free(); 302 } 303 304 pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; 305 pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 306 pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 307 pContext->config.inputCfg.samplingRate = 44100; 308 pContext->config.inputCfg.bufferProvider.getBuffer = NULL; 309 pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL; 310 pContext->config.inputCfg.bufferProvider.cookie = NULL; 311 pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL; 312 pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE; 313 pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 314 pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 315 pContext->config.outputCfg.samplingRate = 44100; 316 pContext->config.outputCfg.bufferProvider.getBuffer = NULL; 317 pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL; 318 pContext->config.outputCfg.bufferProvider.cookie = NULL; 319 pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL; 320 321 pContext->pEqualizer = AudioEqualizer::CreateInstance( 322 NULL, 323 kNumBands, 324 AudioBiquadFilter::MAX_CHANNELS, 325 44100, 326 gEqualizerPresets, 327 ARRAY_SIZE(gEqualizerPresets)); 328 329 for (int i = 0; i < kNumBands; ++i) { 330 pContext->pEqualizer->setFrequency(i, gFreqs[i]); 331 pContext->pEqualizer->setBandwidth(i, gBandwidths[i]); 332 } 333 334 pContext->pEqualizer->enable(true); 335 336 Equalizer_setConfig(pContext, &pContext->config); 337 338 return 0; 339 } // end Equalizer_init 340 341 342 //---------------------------------------------------------------------------- 343 // Equalizer_getParameter() 344 //---------------------------------------------------------------------------- 345 // Purpose: 346 // Get a Equalizer parameter 347 // 348 // Inputs: 349 // pEqualizer - handle to instance data 350 // pParam - pointer to parameter 351 // pValue - pointer to variable to hold retrieved value 352 // pValueSize - pointer to value size: maximum size as input 353 // 354 // Outputs: 355 // *pValue updated with parameter value 356 // *pValueSize updated with actual value size 357 // 358 // 359 // Side Effects: 360 // 361 //---------------------------------------------------------------------------- 362 363 int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, uint32_t *pValueSize, void *pValue) 364 { 365 int status = 0; 366 int32_t param = *pParam++; 367 int32_t param2; 368 char *name; 369 370 switch (param) { 371 case EQ_PARAM_NUM_BANDS: 372 case EQ_PARAM_CUR_PRESET: 373 case EQ_PARAM_GET_NUM_OF_PRESETS: 374 case EQ_PARAM_BAND_LEVEL: 375 case EQ_PARAM_GET_BAND: 376 if (*pValueSize < sizeof(int16_t)) { 377 return -EINVAL; 378 } 379 *pValueSize = sizeof(int16_t); 380 break; 381 382 case EQ_PARAM_LEVEL_RANGE: 383 if (*pValueSize < 2 * sizeof(int16_t)) { 384 return -EINVAL; 385 } 386 *pValueSize = 2 * sizeof(int16_t); 387 break; 388 389 case EQ_PARAM_BAND_FREQ_RANGE: 390 if (*pValueSize < 2 * sizeof(int32_t)) { 391 return -EINVAL; 392 } 393 *pValueSize = 2 * sizeof(int32_t); 394 break; 395 396 case EQ_PARAM_CENTER_FREQ: 397 if (*pValueSize < sizeof(int32_t)) { 398 return -EINVAL; 399 } 400 *pValueSize = sizeof(int32_t); 401 break; 402 403 case EQ_PARAM_GET_PRESET_NAME: 404 break; 405 406 case EQ_PARAM_PROPERTIES: 407 if (*pValueSize < (2 + kNumBands) * sizeof(uint16_t)) { 408 return -EINVAL; 409 } 410 *pValueSize = (2 + kNumBands) * sizeof(uint16_t); 411 break; 412 413 default: 414 return -EINVAL; 415 } 416 417 switch (param) { 418 case EQ_PARAM_NUM_BANDS: 419 *(uint16_t *)pValue = (uint16_t)kNumBands; 420 ALOGV("Equalizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue); 421 break; 422 423 case EQ_PARAM_LEVEL_RANGE: 424 *(int16_t *)pValue = -9600; 425 *((int16_t *)pValue + 1) = 4800; 426 ALOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d", 427 *(int32_t *)pValue, *((int32_t *)pValue + 1)); 428 break; 429 430 case EQ_PARAM_BAND_LEVEL: 431 param2 = *pParam; 432 if (param2 >= kNumBands) { 433 status = -EINVAL; 434 break; 435 } 436 *(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2); 437 ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", 438 param2, *(int32_t *)pValue); 439 break; 440 441 case EQ_PARAM_CENTER_FREQ: 442 param2 = *pParam; 443 if (param2 >= kNumBands) { 444 status = -EINVAL; 445 break; 446 } 447 *(int32_t *)pValue = pEqualizer->getFrequency(param2); 448 ALOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d", 449 param2, *(int32_t *)pValue); 450 break; 451 452 case EQ_PARAM_BAND_FREQ_RANGE: 453 param2 = *pParam; 454 if (param2 >= kNumBands) { 455 status = -EINVAL; 456 break; 457 } 458 pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1)); 459 ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", 460 param2, *(int32_t *)pValue, *((int32_t *)pValue + 1)); 461 break; 462 463 case EQ_PARAM_GET_BAND: 464 param2 = *pParam; 465 *(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2); 466 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d", 467 param2, *(int32_t *)pValue); 468 break; 469 470 case EQ_PARAM_CUR_PRESET: 471 *(uint16_t *)pValue = (uint16_t)pEqualizer->getPreset(); 472 ALOGV("Equalizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue); 473 break; 474 475 case EQ_PARAM_GET_NUM_OF_PRESETS: 476 *(uint16_t *)pValue = (uint16_t)pEqualizer->getNumPresets(); 477 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue); 478 break; 479 480 case EQ_PARAM_GET_PRESET_NAME: 481 param2 = *pParam; 482 if (param2 >= pEqualizer->getNumPresets()) { 483 status = -EINVAL; 484 break; 485 } 486 name = (char *)pValue; 487 strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1); 488 name[*pValueSize - 1] = 0; 489 *pValueSize = strlen(name) + 1; 490 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", 491 param2, gEqualizerPresets[param2].name, *pValueSize); 492 break; 493 494 case EQ_PARAM_PROPERTIES: { 495 int16_t *p = (int16_t *)pValue; 496 ALOGV("Equalizer_getParameter() EQ_PARAM_PROPERTIES"); 497 p[0] = (int16_t)pEqualizer->getPreset(); 498 p[1] = (int16_t)kNumBands; 499 for (int i = 0; i < kNumBands; i++) { 500 p[2 + i] = (int16_t)pEqualizer->getGain(i); 501 } 502 } break; 503 504 default: 505 ALOGV("Equalizer_getParameter() invalid param %d", param); 506 status = -EINVAL; 507 break; 508 } 509 510 return status; 511 } // end Equalizer_getParameter 512 513 514 //---------------------------------------------------------------------------- 515 // Equalizer_setParameter() 516 //---------------------------------------------------------------------------- 517 // Purpose: 518 // Set a Equalizer parameter 519 // 520 // Inputs: 521 // pEqualizer - handle to instance data 522 // pParam - pointer to parameter 523 // pValue - pointer to value 524 // 525 // Outputs: 526 // 527 // 528 // Side Effects: 529 // 530 //---------------------------------------------------------------------------- 531 532 int Equalizer_setParameter (AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue) 533 { 534 int status = 0; 535 int32_t preset; 536 int32_t band; 537 int32_t level; 538 int32_t param = *pParam++; 539 540 541 switch (param) { 542 case EQ_PARAM_CUR_PRESET: 543 preset = (int32_t)(*(uint16_t *)pValue); 544 545 ALOGV("setParameter() EQ_PARAM_CUR_PRESET %d", preset); 546 if (preset < 0 || preset >= pEqualizer->getNumPresets()) { 547 status = -EINVAL; 548 break; 549 } 550 pEqualizer->setPreset(preset); 551 pEqualizer->commit(true); 552 break; 553 case EQ_PARAM_BAND_LEVEL: 554 band = *pParam; 555 level = (int32_t)(*(int16_t *)pValue); 556 ALOGV("setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level); 557 if (band >= kNumBands) { 558 status = -EINVAL; 559 break; 560 } 561 pEqualizer->setGain(band, level); 562 pEqualizer->commit(true); 563 break; 564 case EQ_PARAM_PROPERTIES: { 565 ALOGV("setParameter() EQ_PARAM_PROPERTIES"); 566 int16_t *p = (int16_t *)pValue; 567 if ((int)p[0] >= pEqualizer->getNumPresets()) { 568 status = -EINVAL; 569 break; 570 } 571 if (p[0] >= 0) { 572 pEqualizer->setPreset((int)p[0]); 573 } else { 574 if ((int)p[1] != kNumBands) { 575 status = -EINVAL; 576 break; 577 } 578 for (int i = 0; i < kNumBands; i++) { 579 pEqualizer->setGain(i, (int32_t)p[2 + i]); 580 } 581 } 582 pEqualizer->commit(true); 583 } break; 584 default: 585 ALOGV("setParameter() invalid param %d", param); 586 status = -EINVAL; 587 break; 588 } 589 590 return status; 591 } // end Equalizer_setParameter 592 593 } // namespace 594 } // namespace 595 596 597 // 598 //--- Effect Control Interface Implementation 599 // 600 601 extern "C" int Equalizer_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) 602 { 603 android::EqualizerContext * pContext = (android::EqualizerContext *) self; 604 605 if (pContext == NULL) { 606 return -EINVAL; 607 } 608 if (inBuffer == NULL || inBuffer->raw == NULL || 609 outBuffer == NULL || outBuffer->raw == NULL || 610 inBuffer->frameCount != outBuffer->frameCount) { 611 return -EINVAL; 612 } 613 614 if (pContext->state == EQUALIZER_STATE_UNINITIALIZED) { 615 return -EINVAL; 616 } 617 if (pContext->state == EQUALIZER_STATE_INITIALIZED) { 618 return -ENODATA; 619 } 620 621 pContext->adapter.process(inBuffer->raw, outBuffer->raw, outBuffer->frameCount); 622 623 return 0; 624 } // end Equalizer_process 625 626 extern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, 627 void *pCmdData, uint32_t *replySize, void *pReplyData) { 628 629 android::EqualizerContext * pContext = (android::EqualizerContext *) self; 630 int retsize; 631 632 if (pContext == NULL || pContext->state == EQUALIZER_STATE_UNINITIALIZED) { 633 return -EINVAL; 634 } 635 636 android::AudioEqualizer * pEqualizer = pContext->pEqualizer; 637 638 ALOGV("Equalizer_command command %d cmdSize %d",cmdCode, cmdSize); 639 640 switch (cmdCode) { 641 case EFFECT_CMD_INIT: 642 if (pReplyData == NULL || *replySize != sizeof(int)) { 643 return -EINVAL; 644 } 645 *(int *) pReplyData = Equalizer_init(pContext); 646 break; 647 case EFFECT_CMD_SET_CONFIG: 648 if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) 649 || pReplyData == NULL || *replySize != sizeof(int)) { 650 return -EINVAL; 651 } 652 *(int *) pReplyData = Equalizer_setConfig(pContext, 653 (effect_config_t *) pCmdData); 654 break; 655 case EFFECT_CMD_GET_CONFIG: 656 if (pReplyData == NULL || *replySize != sizeof(effect_config_t)) { 657 return -EINVAL; 658 } 659 Equalizer_getConfig(pContext, (effect_config_t *) pCmdData); 660 break; 661 case EFFECT_CMD_RESET: 662 Equalizer_setConfig(pContext, &pContext->config); 663 break; 664 case EFFECT_CMD_GET_PARAM: { 665 if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) || 666 pReplyData == NULL || *replySize < (sizeof(effect_param_t) + sizeof(int32_t))) { 667 return -EINVAL; 668 } 669 effect_param_t *p = (effect_param_t *)pCmdData; 670 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize); 671 p = (effect_param_t *)pReplyData; 672 int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t); 673 p->status = android::Equalizer_getParameter(pEqualizer, (int32_t *)p->data, &p->vsize, 674 p->data + voffset); 675 *replySize = sizeof(effect_param_t) + voffset + p->vsize; 676 ALOGV("Equalizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x", 677 *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize, 678 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset), 679 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset + sizeof(int32_t))); 680 681 } break; 682 case EFFECT_CMD_SET_PARAM: { 683 ALOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p", 684 cmdSize, pCmdData, *replySize, pReplyData); 685 if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) || 686 pReplyData == NULL || *replySize != sizeof(int32_t)) { 687 return -EINVAL; 688 } 689 effect_param_t *p = (effect_param_t *) pCmdData; 690 *(int *)pReplyData = android::Equalizer_setParameter(pEqualizer, (int32_t *)p->data, 691 p->data + p->psize); 692 } break; 693 case EFFECT_CMD_ENABLE: 694 if (pReplyData == NULL || *replySize != sizeof(int)) { 695 return -EINVAL; 696 } 697 if (pContext->state != EQUALIZER_STATE_INITIALIZED) { 698 return -ENOSYS; 699 } 700 pContext->state = EQUALIZER_STATE_ACTIVE; 701 ALOGV("EFFECT_CMD_ENABLE() OK"); 702 *(int *)pReplyData = 0; 703 break; 704 case EFFECT_CMD_DISABLE: 705 if (pReplyData == NULL || *replySize != sizeof(int)) { 706 return -EINVAL; 707 } 708 if (pContext->state != EQUALIZER_STATE_ACTIVE) { 709 return -ENOSYS; 710 } 711 pContext->state = EQUALIZER_STATE_INITIALIZED; 712 ALOGV("EFFECT_CMD_DISABLE() OK"); 713 *(int *)pReplyData = 0; 714 break; 715 case EFFECT_CMD_SET_DEVICE: 716 case EFFECT_CMD_SET_VOLUME: 717 case EFFECT_CMD_SET_AUDIO_MODE: 718 break; 719 default: 720 ALOGW("Equalizer_command invalid command %d",cmdCode); 721 return -EINVAL; 722 } 723 724 return 0; 725 } 726 727 extern "C" int Equalizer_getDescriptor(effect_handle_t self, 728 effect_descriptor_t *pDescriptor) 729 { 730 android::EqualizerContext * pContext = (android::EqualizerContext *) self; 731 732 if (pContext == NULL || pDescriptor == NULL) { 733 ALOGV("Equalizer_getDescriptor() invalid param"); 734 return -EINVAL; 735 } 736 737 *pDescriptor = android::gEqualizerDescriptor; 738 739 return 0; 740 } 741 742 // effect_handle_t interface implementation for equalizer effect 743 const struct effect_interface_s gEqualizerInterface = { 744 Equalizer_process, 745 Equalizer_command, 746 Equalizer_getDescriptor, 747 NULL 748 }; 749 750 751 audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { 752 tag : AUDIO_EFFECT_LIBRARY_TAG, 753 version : EFFECT_LIBRARY_API_VERSION, 754 name : "Test Equalizer Library", 755 implementor : "The Android Open Source Project", 756 create_effect : android::EffectCreate, 757 release_effect : android::EffectRelease, 758 get_descriptor : android::EffectGetDescriptor, 759 }; 760