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 22#include <assert.h> 23#include <stdlib.h> 24#include <string.h> 25 26#include <new> 27 28#include <log/log.h> 29 30#include "AudioEqualizer.h" 31#include "AudioBiquadFilter.h" 32#include "AudioFormatAdapter.h" 33#include <audio_effects/effect_equalizer.h> 34 35// effect_handle_t interface implementation for equalizer effect 36extern "C" const struct effect_interface_s gEqualizerInterface; 37 38enum equalizer_state_e { 39 EQUALIZER_STATE_UNINITIALIZED, 40 EQUALIZER_STATE_INITIALIZED, 41 EQUALIZER_STATE_ACTIVE, 42}; 43 44namespace 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 51 EFFECT_CONTROL_API_VERSION, 52 (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST), 53 0, // TODO 54 1, 55 "Graphic Equalizer", 56 "The Android Open Source Project", 57}; 58 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; 114 uint32_t state; 115}; 116 117//--- local function prototypes 118 119int Equalizer_init(EqualizerContext *pContext); 120int Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig); 121int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, uint32_t *pValueSize, void *pValue); 122int Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue); 123 124 125// 126//--- Effect Library Interface Implementation 127// 128 129extern "C" int EffectCreate(const effect_uuid_t *uuid, 130 int32_t sessionId, 131 int32_t ioId, 132 effect_handle_t *pHandle) { 133 int ret; 134 int i; 135 136 ALOGV("EffectLibCreateEffect start"); 137 138 if (pHandle == NULL || uuid == NULL) { 139 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; 150 pContext->state = EQUALIZER_STATE_UNINITIALIZED; 151 152 ret = Equalizer_init(pContext); 153 if (ret < 0) { 154 ALOGW("EffectLibCreateEffect() init failed"); 155 delete pContext; 156 return ret; 157 } 158 159 *pHandle = (effect_handle_t)pContext; 160 pContext->state = EQUALIZER_STATE_INITIALIZED; 161 162 ALOGV("EffectLibCreateEffect %p, size %d", 163 pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext)); 164 165 return 0; 166 167} /* end EffectCreate */ 168 169extern "C" int EffectRelease(effect_handle_t handle) { 170 EqualizerContext * pContext = (EqualizerContext *)handle; 171 172 ALOGV("EffectLibReleaseEffect %p", handle); 173 if (pContext == NULL) { 174 return -EINVAL; 175 } 176 177 pContext->state = EQUALIZER_STATE_UNINITIALIZED; 178 pContext->pEqualizer->free(); 179 delete pContext; 180 181 return 0; 182} /* end EffectRelease */ 183 184extern "C" int EffectGetDescriptor(const effect_uuid_t *uuid, 185 effect_descriptor_t *pDescriptor) { 186 187 if (pDescriptor == NULL || uuid == NULL){ 188 ALOGV("EffectGetDescriptor() called with NULL pointer"); 189 return -EINVAL; 190 } 191 192 if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) { 193 *pDescriptor = gEqualizerDescriptor; 194 return 0; 195 } 196 197 return -EINVAL; 198} /* end EffectGetDescriptor */ 199 200 201// 202//--- local functions 203// 204 205#define CHECK_ARG(cond) { \ 206 if (!(cond)) { \ 207 ALOGV("Invalid argument: "#cond); \ 208 return -EINVAL; \ 209 } \ 210} 211 212//---------------------------------------------------------------------------- 213// Equalizer_setConfig() 214//---------------------------------------------------------------------------- 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 226int Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig) 227{ 228 ALOGV("Equalizer_setConfig start"); 229 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); 236 CHECK_ARG((pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) || 237 (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO)); 238 CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE 239 || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE); 240 CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT); 241 242 int channelCount; 243 if (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) { 244 channelCount = 1; 245 } else { 246 channelCount = 2; 247 } 248 CHECK_ARG(channelCount <= AudioBiquadFilter::MAX_CHANNELS); 249 250 pContext->config = *pConfig; 251 252 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; 260} // 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{ 278 *pConfig = pContext->config; 279} // end Equalizer_getConfig 280 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 299 ALOGV("Equalizer_init start"); 300 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; 308 pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 309 pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 310 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; 316 pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 317 pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 318 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 339 Equalizer_setConfig(pContext, &pContext->config); 340 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 366int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, uint32_t *pValueSize, void *pValue) 367{ 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: 377 case EQ_PARAM_BAND_LEVEL: 378 case EQ_PARAM_GET_BAND: 379 if (*pValueSize < sizeof(int16_t)) { 380 return -EINVAL; 381 } 382 *pValueSize = sizeof(int16_t); 383 break; 384 385 case EQ_PARAM_LEVEL_RANGE: 386 if (*pValueSize < 2 * sizeof(int16_t)) { 387 return -EINVAL; 388 } 389 *pValueSize = 2 * sizeof(int16_t); 390 break; 391 392 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; 398 399 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 409 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 416 default: 417 return -EINVAL; 418 } 419 420 switch (param) { 421 case EQ_PARAM_NUM_BANDS: 422 *(uint16_t *)pValue = (uint16_t)kNumBands; 423 ALOGV("Equalizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue); 424 break; 425 426 case EQ_PARAM_LEVEL_RANGE: 427 *(int16_t *)pValue = -9600; 428 *((int16_t *)pValue + 1) = 4800; 429 ALOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d", 430 *(int32_t *)pValue, *((int32_t *)pValue + 1)); 431 break; 432 433 case EQ_PARAM_BAND_LEVEL: 434 param2 = *pParam; 435 if (param2 >= kNumBands) { 436 status = -EINVAL; 437 break; 438 } 439 *(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2); 440 ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", 441 param2, *(int32_t *)pValue); 442 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); 451 ALOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d", 452 param2, *(int32_t *)pValue); 453 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)); 462 ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", 463 param2, *(int32_t *)pValue, *((int32_t *)pValue + 1)); 464 break; 465 466 case EQ_PARAM_GET_BAND: 467 param2 = *pParam; 468 *(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2); 469 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d", 470 param2, *(int32_t *)pValue); 471 break; 472 473 case EQ_PARAM_CUR_PRESET: 474 *(uint16_t *)pValue = (uint16_t)pEqualizer->getPreset(); 475 ALOGV("Equalizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue); 476 break; 477 478 case EQ_PARAM_GET_NUM_OF_PRESETS: 479 *(uint16_t *)pValue = (uint16_t)pEqualizer->getNumPresets(); 480 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue); 481 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; 493 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", 494 param2, gEqualizerPresets[param2].name, *pValueSize); 495 break; 496 497 case EQ_PARAM_PROPERTIES: { 498 int16_t *p = (int16_t *)pValue; 499 ALOGV("Equalizer_getParameter() EQ_PARAM_PROPERTIES"); 500 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 507 default: 508 ALOGV("Equalizer_getParameter() invalid param %d", param); 509 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: 546 preset = (int32_t)(*(uint16_t *)pValue); 547 548 ALOGV("setParameter() EQ_PARAM_CUR_PRESET %d", preset); 549 if (preset < 0 || preset >= pEqualizer->getNumPresets()) { 550 status = -EINVAL; 551 break; 552 } 553 pEqualizer->setPreset(preset); 554 pEqualizer->commit(true); 555 break; 556 case EQ_PARAM_BAND_LEVEL: 557 band = *pParam; 558 level = (int32_t)(*(int16_t *)pValue); 559 ALOGV("setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level); 560 if (band >= kNumBands) { 561 status = -EINVAL; 562 break; 563 } 564 pEqualizer->setGain(band, level); 565 pEqualizer->commit(true); 566 break; 567 case EQ_PARAM_PROPERTIES: { 568 ALOGV("setParameter() EQ_PARAM_PROPERTIES"); 569 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; 587 default: 588 ALOGV("setParameter() invalid param %d", param); 589 status = -EINVAL; 590 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 604extern "C" int Equalizer_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) 605{ 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 617 if (pContext->state == EQUALIZER_STATE_UNINITIALIZED) { 618 return -EINVAL; 619 } 620 if (pContext->state == EQUALIZER_STATE_INITIALIZED) { 621 return -ENODATA; 622 } 623 624 pContext->adapter.process(inBuffer->raw, outBuffer->raw, outBuffer->frameCount); 625 626 return 0; 627} // end Equalizer_process 628 629extern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, 630 void *pCmdData, uint32_t *replySize, void *pReplyData) { 631 632 android::EqualizerContext * pContext = (android::EqualizerContext *) self; 633 int retsize; 634 635 if (pContext == NULL || pContext->state == EQUALIZER_STATE_UNINITIALIZED) { 636 return -EINVAL; 637 } 638 639 android::AudioEqualizer * pEqualizer = pContext->pEqualizer; 640 641 ALOGV("Equalizer_command command %d cmdSize %d",cmdCode, cmdSize); 642 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; 650 case EFFECT_CMD_SET_CONFIG: 651 if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) 652 || pReplyData == NULL || *replySize != sizeof(int)) { 653 return -EINVAL; 654 } 655 *(int *) pReplyData = Equalizer_setConfig(pContext, 656 (effect_config_t *) pCmdData); 657 break; 658 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; 664 case EFFECT_CMD_RESET: 665 Equalizer_setConfig(pContext, &pContext->config); 666 break; 667 case EFFECT_CMD_GET_PARAM: { 668 if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) || 669 pReplyData == NULL || *replySize < (sizeof(effect_param_t) + sizeof(int32_t))) { 670 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; 679 ALOGV("Equalizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x", 680 *(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: { 686 ALOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p", 687 cmdSize, pCmdData, *replySize, pReplyData); 688 if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) || 689 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; 696 case EFFECT_CMD_ENABLE: 697 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; 704 ALOGV("EFFECT_CMD_ENABLE() OK"); 705 *(int *)pReplyData = 0; 706 break; 707 case EFFECT_CMD_DISABLE: 708 if (pReplyData == NULL || *replySize != sizeof(int)) { 709 return -EINVAL; 710 } 711 if (pContext->state != EQUALIZER_STATE_ACTIVE) { 712 return -ENOSYS; 713 } 714 pContext->state = EQUALIZER_STATE_INITIALIZED; 715 ALOGV("EFFECT_CMD_DISABLE() OK"); 716 *(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; 722 default: 723 ALOGW("Equalizer_command invalid command %d",cmdCode); 724 return -EINVAL; 725 } 726 727 return 0; 728} 729 730extern "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) { 736 ALOGV("Equalizer_getDescriptor() invalid param"); 737 return -EINVAL; 738 } 739 740 *pDescriptor = android::gEqualizerDescriptor; 741 742 return 0; 743} 744 745// effect_handle_t interface implementation for equalizer effect 746const struct effect_interface_s gEqualizerInterface = { 747 Equalizer_process, 748 Equalizer_command, 749 Equalizer_getDescriptor, 750 NULL 751}; 752 753 754audio_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", 759 create_effect : android::EffectCreate, 760 release_effect : android::EffectRelease, 761 get_descriptor : android::EffectGetDescriptor, 762}; 763