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 <media/EffectEqualizerApi.h> 30 31// effect_interface_t interface implementation for equalizer effect 32extern "C" const struct effect_interface_s gEqualizerInterface; 33 34enum equalizer_state_e { 35 EQUALIZER_STATE_UNINITIALIZED, 36 EQUALIZER_STATE_INITIALIZED, 37 EQUALIZER_STATE_ACTIVE, 38}; 39 40namespace android { 41namespace { 42 43// Google Graphic Equalizer UUID: e25aa840-543b-11df-98a5-0002a5d5c51b 44const 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), 49 0, // TODO 50 1, 51 "Graphic Equalizer", 52 "Google Inc.", 53}; 54 55/////////////////// BEGIN EQ PRESETS /////////////////////////////////////////// 56const int kNumBands = 5; 57const uint32_t gFreqs[kNumBands] = { 50000, 125000, 900000, 3200000, 6300000 }; 58const uint32_t gBandwidths[kNumBands] = { 0, 3600, 3600, 2400, 0 }; 59 60const 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 68const 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 76const 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 84const 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 92const AudioEqualizer::PresetConfig gEqualizerPresets[] = { 93 { "Classic", gBandsClassic }, 94 { "Jazz", gBandsJazz }, 95 { "Pop", gBandsPop }, 96 { "Rock", gBandsRock } 97}; 98 99/////////////////// END EQ PRESETS ///////////////////////////////////////////// 100 101static const size_t kBufferSize = 32; 102 103typedef AudioFormatAdapter<AudioEqualizer, kBufferSize> FormatAdapter; 104 105struct EqualizerContext { 106 const struct effect_interface_s *itfe; 107 effect_config_t config; 108 FormatAdapter adapter; 109 AudioEqualizer * pEqualizer; 110 uint32_t state; 111}; 112 113//--- local function prototypes 114 115int Equalizer_init(EqualizerContext *pContext); 116int Equalizer_configure(EqualizerContext *pContext, effect_config_t *pConfig); 117int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue); 118int Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue); 119 120 121// 122//--- Effect Library Interface Implementation 123// 124 125extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects) { 126 *pNumEffects = 1; 127 return 0; 128} /* end EffectQueryNumberEffects */ 129 130extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) { 131 if (pDescriptor == NULL) { 132 return -EINVAL; 133 } 134 if (index > 0) { 135 return -EINVAL; 136 } 137 memcpy(pDescriptor, &gEqualizerDescriptor, sizeof(effect_descriptor_t)); 138 return 0; 139} /* end EffectQueryNext */ 140 141extern "C" int EffectCreate(effect_uuid_t *uuid, 142 int32_t sessionId, 143 int32_t ioId, 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; 162 pContext->state = EQUALIZER_STATE_UNINITIALIZED; 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; 172 pContext->state = EQUALIZER_STATE_INITIALIZED; 173 174 LOGV("EffectLibCreateEffect %p, size %d", pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext)); 175 176 return 0; 177 178} /* end EffectCreate */ 179 180extern "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 188 pContext->state = EQUALIZER_STATE_UNINITIALIZED; 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 221int 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); 234 CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S7_24 235 || pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15); 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 245 memcpy(&pContext->config, pConfig, sizeof(effect_config_t)); 246 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 271int 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; 285 pContext->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15; 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; 293 pContext->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15; 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 342int 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 case EQ_PARAM_BAND_LEVEL: 354 case EQ_PARAM_GET_BAND: 355 if (*pValueSize < sizeof(int16_t)) { 356 return -EINVAL; 357 } 358 *pValueSize = sizeof(int16_t); 359 break; 360 361 case EQ_PARAM_LEVEL_RANGE: 362 if (*pValueSize < 2 * sizeof(int16_t)) { 363 return -EINVAL; 364 } 365 *pValueSize = 2 * sizeof(int16_t); 366 break; 367 368 case EQ_PARAM_BAND_FREQ_RANGE: 369 if (*pValueSize < 2 * sizeof(int32_t)) { 370 return -EINVAL; 371 } 372 *pValueSize = 2 * sizeof(int32_t); 373 break; 374 375 case EQ_PARAM_CENTER_FREQ: 376 if (*pValueSize < sizeof(int32_t)) { 377 return -EINVAL; 378 } 379 *pValueSize = sizeof(int32_t); 380 break; 381 382 case EQ_PARAM_GET_PRESET_NAME: 383 break; 384 385 case EQ_PARAM_PROPERTIES: 386 if (*pValueSize < (2 + kNumBands) * sizeof(uint16_t)) { 387 return -EINVAL; 388 } 389 *pValueSize = (2 + kNumBands) * sizeof(uint16_t); 390 break; 391 392 default: 393 return -EINVAL; 394 } 395 396 switch (param) { 397 case EQ_PARAM_NUM_BANDS: 398 *(uint16_t *)pValue = (uint16_t)kNumBands; 399 LOGV("Equalizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue); 400 break; 401 402 case EQ_PARAM_LEVEL_RANGE: 403 *(int16_t *)pValue = -9600; 404 *((int16_t *)pValue + 1) = 4800; 405 LOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d", *(int32_t *)pValue, *((int32_t *)pValue + 1)); 406 break; 407 408 case EQ_PARAM_BAND_LEVEL: 409 param2 = *pParam; 410 if (param2 >= kNumBands) { 411 status = -EINVAL; 412 break; 413 } 414 *(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2); 415 LOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", param2, *(int32_t *)pValue); 416 break; 417 418 case EQ_PARAM_CENTER_FREQ: 419 param2 = *pParam; 420 if (param2 >= kNumBands) { 421 status = -EINVAL; 422 break; 423 } 424 *(int32_t *)pValue = pEqualizer->getFrequency(param2); 425 LOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d", param2, *(int32_t *)pValue); 426 break; 427 428 case EQ_PARAM_BAND_FREQ_RANGE: 429 param2 = *pParam; 430 if (param2 >= kNumBands) { 431 status = -EINVAL; 432 break; 433 } 434 pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1)); 435 LOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", param2, *(int32_t *)pValue, *((int32_t *)pValue + 1)); 436 break; 437 438 case EQ_PARAM_GET_BAND: 439 param2 = *pParam; 440 *(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2); 441 LOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d", param2, *(int32_t *)pValue); 442 break; 443 444 case EQ_PARAM_CUR_PRESET: 445 *(uint16_t *)pValue = (uint16_t)pEqualizer->getPreset(); 446 LOGV("Equalizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue); 447 break; 448 449 case EQ_PARAM_GET_NUM_OF_PRESETS: 450 *(uint16_t *)pValue = (uint16_t)pEqualizer->getNumPresets(); 451 LOGV("Equalizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue); 452 break; 453 454 case EQ_PARAM_GET_PRESET_NAME: 455 param2 = *pParam; 456 if (param2 >= pEqualizer->getNumPresets()) { 457 status = -EINVAL; 458 break; 459 } 460 name = (char *)pValue; 461 strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1); 462 name[*pValueSize - 1] = 0; 463 *pValueSize = strlen(name) + 1; 464 LOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", param2, gEqualizerPresets[param2].name, *pValueSize); 465 break; 466 467 case EQ_PARAM_PROPERTIES: { 468 int16_t *p = (int16_t *)pValue; 469 LOGV("Equalizer_getParameter() EQ_PARAM_PROPERTIES"); 470 p[0] = (int16_t)pEqualizer->getPreset(); 471 p[1] = (int16_t)kNumBands; 472 for (int i = 0; i < kNumBands; i++) { 473 p[2 + i] = (int16_t)pEqualizer->getGain(i); 474 } 475 } break; 476 477 default: 478 LOGV("Equalizer_getParameter() invalid param %d", param); 479 status = -EINVAL; 480 break; 481 } 482 483 return status; 484} // end Equalizer_getParameter 485 486 487//---------------------------------------------------------------------------- 488// Equalizer_setParameter() 489//---------------------------------------------------------------------------- 490// Purpose: 491// Set a Equalizer parameter 492// 493// Inputs: 494// pEqualizer - handle to instance data 495// pParam - pointer to parameter 496// pValue - pointer to value 497// 498// Outputs: 499// 500// 501// Side Effects: 502// 503//---------------------------------------------------------------------------- 504 505int Equalizer_setParameter (AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue) 506{ 507 int status = 0; 508 int32_t preset; 509 int32_t band; 510 int32_t level; 511 int32_t param = *pParam++; 512 513 514 switch (param) { 515 case EQ_PARAM_CUR_PRESET: 516 preset = (int32_t)(*(uint16_t *)pValue); 517 518 LOGV("setParameter() EQ_PARAM_CUR_PRESET %d", preset); 519 if (preset < 0 || preset >= pEqualizer->getNumPresets()) { 520 status = -EINVAL; 521 break; 522 } 523 pEqualizer->setPreset(preset); 524 pEqualizer->commit(true); 525 break; 526 case EQ_PARAM_BAND_LEVEL: 527 band = *pParam; 528 level = (int32_t)(*(int16_t *)pValue); 529 LOGV("setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level); 530 if (band >= kNumBands) { 531 status = -EINVAL; 532 break; 533 } 534 pEqualizer->setGain(band, level); 535 pEqualizer->commit(true); 536 break; 537 case EQ_PARAM_PROPERTIES: { 538 LOGV("setParameter() EQ_PARAM_PROPERTIES"); 539 int16_t *p = (int16_t *)pValue; 540 if ((int)p[0] >= pEqualizer->getNumPresets()) { 541 status = -EINVAL; 542 break; 543 } 544 if (p[0] >= 0) { 545 pEqualizer->setPreset((int)p[0]); 546 } else { 547 if ((int)p[1] != kNumBands) { 548 status = -EINVAL; 549 break; 550 } 551 for (int i = 0; i < kNumBands; i++) { 552 pEqualizer->setGain(i, (int32_t)p[2 + i]); 553 } 554 } 555 pEqualizer->commit(true); 556 } break; 557 default: 558 LOGV("setParameter() invalid param %d", param); 559 status = -EINVAL; 560 break; 561 } 562 563 return status; 564} // end Equalizer_setParameter 565 566} // namespace 567} // namespace 568 569 570// 571//--- Effect Control Interface Implementation 572// 573 574extern "C" int Equalizer_process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) 575{ 576 android::EqualizerContext * pContext = (android::EqualizerContext *) self; 577 578 if (pContext == NULL) { 579 return -EINVAL; 580 } 581 if (inBuffer == NULL || inBuffer->raw == NULL || 582 outBuffer == NULL || outBuffer->raw == NULL || 583 inBuffer->frameCount != outBuffer->frameCount) { 584 return -EINVAL; 585 } 586 587 if (pContext->state == EQUALIZER_STATE_UNINITIALIZED) { 588 return -EINVAL; 589 } 590 if (pContext->state == EQUALIZER_STATE_INITIALIZED) { 591 return -ENODATA; 592 } 593 594 pContext->adapter.process(inBuffer->raw, outBuffer->raw, outBuffer->frameCount); 595 596 return 0; 597} // end Equalizer_process 598 599extern "C" int Equalizer_command(effect_interface_t self, uint32_t cmdCode, uint32_t cmdSize, 600 void *pCmdData, uint32_t *replySize, void *pReplyData) { 601 602 android::EqualizerContext * pContext = (android::EqualizerContext *) self; 603 int retsize; 604 605 if (pContext == NULL || pContext->state == EQUALIZER_STATE_UNINITIALIZED) { 606 return -EINVAL; 607 } 608 609 android::AudioEqualizer * pEqualizer = pContext->pEqualizer; 610 611 LOGV("Equalizer_command command %d cmdSize %d",cmdCode, cmdSize); 612 613 switch (cmdCode) { 614 case EFFECT_CMD_INIT: 615 if (pReplyData == NULL || *replySize != sizeof(int)) { 616 return -EINVAL; 617 } 618 *(int *) pReplyData = Equalizer_init(pContext); 619 break; 620 case EFFECT_CMD_CONFIGURE: 621 if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) 622 || pReplyData == NULL || *replySize != sizeof(int)) { 623 return -EINVAL; 624 } 625 *(int *) pReplyData = Equalizer_configure(pContext, 626 (effect_config_t *) pCmdData); 627 break; 628 case EFFECT_CMD_RESET: 629 Equalizer_configure(pContext, &pContext->config); 630 break; 631 case EFFECT_CMD_GET_PARAM: { 632 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) || 633 pReplyData == NULL || *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))) { 634 return -EINVAL; 635 } 636 effect_param_t *p = (effect_param_t *)pCmdData; 637 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize); 638 p = (effect_param_t *)pReplyData; 639 int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t); 640 p->status = android::Equalizer_getParameter(pEqualizer, (int32_t *)p->data, &p->vsize, 641 p->data + voffset); 642 *replySize = sizeof(effect_param_t) + voffset + p->vsize; 643 LOGV("Equalizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x", 644 *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize, 645 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset), 646 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset + sizeof(int32_t))); 647 648 } break; 649 case EFFECT_CMD_SET_PARAM: { 650 LOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData); 651 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) || 652 pReplyData == NULL || *replySize != sizeof(int32_t)) { 653 return -EINVAL; 654 } 655 effect_param_t *p = (effect_param_t *) pCmdData; 656 *(int *)pReplyData = android::Equalizer_setParameter(pEqualizer, (int32_t *)p->data, 657 p->data + p->psize); 658 } break; 659 case EFFECT_CMD_ENABLE: 660 if (pReplyData == NULL || *replySize != sizeof(int)) { 661 return -EINVAL; 662 } 663 if (pContext->state != EQUALIZER_STATE_INITIALIZED) { 664 return -ENOSYS; 665 } 666 pContext->state = EQUALIZER_STATE_ACTIVE; 667 LOGV("EFFECT_CMD_ENABLE() OK"); 668 *(int *)pReplyData = 0; 669 break; 670 case EFFECT_CMD_DISABLE: 671 if (pReplyData == NULL || *replySize != sizeof(int)) { 672 return -EINVAL; 673 } 674 if (pContext->state != EQUALIZER_STATE_ACTIVE) { 675 return -ENOSYS; 676 } 677 pContext->state = EQUALIZER_STATE_INITIALIZED; 678 LOGV("EFFECT_CMD_DISABLE() OK"); 679 *(int *)pReplyData = 0; 680 break; 681 case EFFECT_CMD_SET_DEVICE: 682 case EFFECT_CMD_SET_VOLUME: 683 case EFFECT_CMD_SET_AUDIO_MODE: 684 break; 685 default: 686 LOGW("Equalizer_command invalid command %d",cmdCode); 687 return -EINVAL; 688 } 689 690 return 0; 691} 692 693// effect_interface_t interface implementation for equalizer effect 694const struct effect_interface_s gEqualizerInterface = { 695 Equalizer_process, 696 Equalizer_command 697}; 698 699 700