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