EffectEqualizer.cpp revision 5ff1dd576bb93c45b44088a51544a18fc43ebf58
15541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown/* 25541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * Copyright (C) 2009 The Android Open Source Project 35541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * 45541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 55541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * you may not use this file except in compliance with the License. 65541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * You may obtain a copy of the License at 75541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * 85541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 95541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * 105541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * Unless required by applicable law or agreed to in writing, software 115541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 125541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * See the License for the specific language governing permissions and 145541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown * limitations under the License. 155541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown */ 165541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 175541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#define LOG_TAG "Equalizer" 185541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#define ARRAY_SIZE(array) (sizeof array / sizeof array[0]) 195541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// 205541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#define LOG_NDEBUG 0 215541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include <cutils/log.h> 225541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include <assert.h> 238335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <stdlib.h> 245541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include <string.h> 255541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include <new> 265541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include "AudioEqualizer.h" 275541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include "AudioBiquadFilter.h" 285541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include "AudioFormatAdapter.h" 295541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown#include <audio_effects/effect_equalizer.h> 305541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 315541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 325541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// effect_handle_t interface implementation for equalizer effect 335541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownextern "C" const struct effect_interface_s gEqualizerInterface; 342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 352352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownenum equalizer_state_e { 365541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown EQUALIZER_STATE_UNINITIALIZED, 375541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown EQUALIZER_STATE_INITIALIZED, 385541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown EQUALIZER_STATE_ACTIVE, 395541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown}; 405541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 415541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownnamespace android { 425541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownnamespace { 435541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 445541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// Google Graphic Equalizer UUID: e25aa840-543b-11df-98a5-0002a5d5c51b 455541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownconst effect_descriptor_t gEqualizerDescriptor = { 465541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type 475541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown {0xe25aa840, 0x543b, 0x11df, 0x98a5, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid 485541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown EFFECT_CONTROL_API_VERSION, 495541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST), 505541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 0, // TODO 515541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1, 525541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown "Graphic Equalizer", 535541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown "The Android Open Source Project", 545541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown}; 552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 562352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown/////////////////// BEGIN EQ PRESETS /////////////////////////////////////////// 572352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownconst int kNumBands = 5; 582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownconst uint32_t gFreqs[kNumBands] = { 50000, 125000, 900000, 3200000, 6300000 }; 592352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownconst uint32_t gBandwidths[kNumBands] = { 0, 3600, 3600, 2400, 0 }; 602352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownconst AudioEqualizer::BandConfig gBandsClassic[kNumBands] = { 622352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { 300, gFreqs[0], gBandwidths[0] }, 632352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { 400, gFreqs[1], gBandwidths[1] }, 642352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { 0, gFreqs[2], gBandwidths[2] }, 652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { 200, gFreqs[3], gBandwidths[3] }, 662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { -300, gFreqs[4], gBandwidths[4] } 672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown}; 682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownconst AudioEqualizer::BandConfig gBandsJazz[kNumBands] = { 702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { -600, gFreqs[0], gBandwidths[0] }, 712352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { 200, gFreqs[1], gBandwidths[1] }, 722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { 400, gFreqs[2], gBandwidths[2] }, 732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { -400, gFreqs[3], gBandwidths[3] }, 742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { -600, gFreqs[4], gBandwidths[4] } 752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown}; 762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 772352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownconst AudioEqualizer::BandConfig gBandsPop[kNumBands] = { 782352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { 400, gFreqs[0], gBandwidths[0] }, 792352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { -400, gFreqs[1], gBandwidths[1] }, 802352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { 300, gFreqs[2], gBandwidths[2] }, 812352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { -400, gFreqs[3], gBandwidths[3] }, 822352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { 600, gFreqs[4], gBandwidths[4] } 832352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown}; 845541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 855541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownconst AudioEqualizer::BandConfig gBandsRock[kNumBands] = { 865541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown { 700, gFreqs[0], gBandwidths[0] }, 875541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown { 400, gFreqs[1], gBandwidths[1] }, 885541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown { -400, gFreqs[2], gBandwidths[2] }, 895541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown { 400, gFreqs[3], gBandwidths[3] }, 905541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown { 200, gFreqs[4], gBandwidths[4] } 915541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown}; 925541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 935541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownconst AudioEqualizer::PresetConfig gEqualizerPresets[] = { 942352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { "Classic", gBandsClassic }, 952352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { "Jazz", gBandsJazz }, 962352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { "Pop", gBandsPop }, 972352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown { "Rock", gBandsRock } 982352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown}; 992352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1002352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown/////////////////// END EQ PRESETS ///////////////////////////////////////////// 1012352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1025541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownstatic const size_t kBufferSize = 32; 1035541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1042352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Browntypedef AudioFormatAdapter<AudioEqualizer, kBufferSize> FormatAdapter; 1052352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1062352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstruct EqualizerContext { 1072352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown const struct effect_interface_s *itfe; 1082352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown effect_config_t config; 1095541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown FormatAdapter adapter; 1105541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown AudioEqualizer * pEqualizer; 1115541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown uint32_t state; 1125541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown}; 1135541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1145541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown//--- local function prototypes 1155541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1165541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownint Equalizer_init(EqualizerContext *pContext); 1175541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownint Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig); 1185541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownint Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue); 1195541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownint Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue); 1205541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1215541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1225541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// 1235541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown//--- Effect Library Interface Implementation 1245541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// 1255541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1265541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownextern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects) { 1275541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown *pNumEffects = 1; 1285541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return 0; 1295541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} /* end EffectQueryNumberEffects */ 1305541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1315541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownextern "C" int EffectQueryEffect(uint32_t index, 1325541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown effect_descriptor_t *pDescriptor) { 1335541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (pDescriptor == NULL) { 1345541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return -EINVAL; 1355541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1365541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (index > 0) { 1375541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return -EINVAL; 1385541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1395541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown memcpy(pDescriptor, &gEqualizerDescriptor, sizeof(effect_descriptor_t)); 1405541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return 0; 1415541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} /* end EffectQueryNext */ 1425541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1435541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownextern "C" int EffectCreate(effect_uuid_t *uuid, 1445541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown int32_t sessionId, 1455541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown int32_t ioId, 1465541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown effect_handle_t *pHandle) { 1475541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown int ret; 1482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown int i; 1492352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown ALOGV("EffectLibCreateEffect start"); 1512352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1522352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (pHandle == NULL || uuid == NULL) { 1532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return -EINVAL; 1542352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 1552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1565541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) != 0) { 1575541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return -EINVAL; 1585541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1595541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1605541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown EqualizerContext *pContext = new EqualizerContext; 1615541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1625541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown pContext->itfe = &gEqualizerInterface; 1635541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown pContext->pEqualizer = NULL; 1645541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown pContext->state = EQUALIZER_STATE_UNINITIALIZED; 1655541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1665541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown ret = Equalizer_init(pContext); 1675541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (ret < 0) { 1685541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown ALOGW("EffectLibCreateEffect() init failed"); 1695541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown delete pContext; 1705541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return ret; 1715541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1725541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1735541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown *pHandle = (effect_handle_t)pContext; 1745541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown pContext->state = EQUALIZER_STATE_INITIALIZED; 1755541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1765541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown ALOGV("EffectLibCreateEffect %p, size %d", 1775541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext)); 1785541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1792352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return 0; 1805541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1815541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} /* end EffectCreate */ 1825541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1835541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownextern "C" int EffectRelease(effect_handle_t handle) { 1845541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown EqualizerContext * pContext = (EqualizerContext *)handle; 1855541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1862352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown ALOGV("EffectLibReleaseEffect %p", handle); 1875541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (pContext == NULL) { 1885541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return -EINVAL; 1895541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 1905541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1915541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown pContext->state = EQUALIZER_STATE_UNINITIALIZED; 1925541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown pContext->pEqualizer->free(); 1935541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown delete pContext; 1945541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1955541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return 0; 1965541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} /* end EffectRelease */ 1975541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 1985541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownextern "C" int EffectGetDescriptor(effect_uuid_t *uuid, 1995541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown effect_descriptor_t *pDescriptor) { 2005541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2012352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (pDescriptor == NULL || uuid == NULL){ 2025541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown ALOGV("EffectGetDescriptor() called with NULL pointer"); 2035541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return -EINVAL; 2045541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2055541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2065541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) { 2075541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown memcpy(pDescriptor, &gEqualizerDescriptor, sizeof(effect_descriptor_t)); 2085541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return 0; 2095541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2105541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2115541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return -EINVAL; 2125541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} /* end EffectGetDescriptor */ 2135541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2145541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2155541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// 2165541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown//--- local functions 2175541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// 2185541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define CHECK_ARG(cond) { \ 2205541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (!(cond)) { \ 2215541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown ALOGV("Invalid argument: "#cond); \ 2225541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown return -EINVAL; \ 2235541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } \ 2245541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown} 2255541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2265541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown//---------------------------------------------------------------------------- 2272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// Equalizer_setConfig() 2285541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown//---------------------------------------------------------------------------- 2295541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// Purpose: Set input and output audio configuration. 2305541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// 2312352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// Inputs: 2325541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// pContext: effect engine context 2335541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// pConfig: pointer to effect_config_t structure holding input and output 2345541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// configuration parameters 2355541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// 2362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// Outputs: 2372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// 2382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown//---------------------------------------------------------------------------- 2392352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 2402352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownint Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig) 2415541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown{ 2425541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown ALOGV("Equalizer_setConfig start"); 2435541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2445541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown CHECK_ARG(pContext != NULL); 2455541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown CHECK_ARG(pConfig != NULL); 2462352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 2472352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate); 2482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels); 2495541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format); 2505541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown CHECK_ARG((pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) || 2515541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO)); 2525541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE 2535541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE); 2545541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_8_24_BIT 2555541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown || pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT); 2565541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2575541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown int channelCount; 2585541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown if (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) { 2595541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown channelCount = 1; 2605541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } else { 2615541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown channelCount = 2; 2625541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown } 2635541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown CHECK_ARG(channelCount <= AudioBiquadFilter::MAX_CHANNELS); 2645541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2655541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown memcpy(&pContext->config, pConfig, sizeof(effect_config_t)); 2665541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2675541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown pContext->pEqualizer->configure(channelCount, 2685541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown pConfig->inputCfg.samplingRate); 2695541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2705541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown pContext->adapter.configure(*pContext->pEqualizer, channelCount, 2715541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown pConfig->inputCfg.format, 2725541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown pConfig->outputCfg.accessMode); 2732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 2742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return 0; 2752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} // end Equalizer_setConfig 2762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 2772352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown//---------------------------------------------------------------------------- 2782352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// Equalizer_getConfig() 2795541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown//---------------------------------------------------------------------------- 2805541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// Purpose: Get input and output audio configuration. 2815541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// 2825541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// Inputs: 2835541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// pContext: effect engine context 2845541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// pConfig: pointer to effect_config_t structure holding input and output 2855541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// configuration parameters 2865541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// 2875541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// Outputs: 2885541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown// 2895541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown//---------------------------------------------------------------------------- 2905541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown 2915541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brownvoid Equalizer_getConfig(EqualizerContext *pContext, effect_config_t *pConfig) 2925541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown{ 2935541de9ea3513a12d1ac2ad07e7e04a3aa7741a0Jeff Brown memcpy(pConfig, &pContext->config, sizeof(effect_config_t)); 294} // end Equalizer_getConfig 295 296 297//---------------------------------------------------------------------------- 298// Equalizer_init() 299//---------------------------------------------------------------------------- 300// Purpose: Initialize engine with default configuration and creates 301// AudioEqualizer instance. 302// 303// Inputs: 304// pContext: effect engine context 305// 306// Outputs: 307// 308//---------------------------------------------------------------------------- 309 310int Equalizer_init(EqualizerContext *pContext) 311{ 312 int status; 313 314 ALOGV("Equalizer_init start"); 315 316 CHECK_ARG(pContext != NULL); 317 318 if (pContext->pEqualizer != NULL) { 319 pContext->pEqualizer->free(); 320 } 321 322 pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; 323 pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 324 pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 325 pContext->config.inputCfg.samplingRate = 44100; 326 pContext->config.inputCfg.bufferProvider.getBuffer = NULL; 327 pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL; 328 pContext->config.inputCfg.bufferProvider.cookie = NULL; 329 pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL; 330 pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE; 331 pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 332 pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 333 pContext->config.outputCfg.samplingRate = 44100; 334 pContext->config.outputCfg.bufferProvider.getBuffer = NULL; 335 pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL; 336 pContext->config.outputCfg.bufferProvider.cookie = NULL; 337 pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL; 338 339 pContext->pEqualizer = AudioEqualizer::CreateInstance( 340 NULL, 341 kNumBands, 342 AudioBiquadFilter::MAX_CHANNELS, 343 44100, 344 gEqualizerPresets, 345 ARRAY_SIZE(gEqualizerPresets)); 346 347 for (int i = 0; i < kNumBands; ++i) { 348 pContext->pEqualizer->setFrequency(i, gFreqs[i]); 349 pContext->pEqualizer->setBandwidth(i, gBandwidths[i]); 350 } 351 352 pContext->pEqualizer->enable(true); 353 354 Equalizer_setConfig(pContext, &pContext->config); 355 356 return 0; 357} // end Equalizer_init 358 359 360//---------------------------------------------------------------------------- 361// Equalizer_getParameter() 362//---------------------------------------------------------------------------- 363// Purpose: 364// Get a Equalizer parameter 365// 366// Inputs: 367// pEqualizer - handle to instance data 368// pParam - pointer to parameter 369// pValue - pointer to variable to hold retrieved value 370// pValueSize - pointer to value size: maximum size as input 371// 372// Outputs: 373// *pValue updated with parameter value 374// *pValueSize updated with actual value size 375// 376// 377// Side Effects: 378// 379//---------------------------------------------------------------------------- 380 381int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue) 382{ 383 int status = 0; 384 int32_t param = *pParam++; 385 int32_t param2; 386 char *name; 387 388 switch (param) { 389 case EQ_PARAM_NUM_BANDS: 390 case EQ_PARAM_CUR_PRESET: 391 case EQ_PARAM_GET_NUM_OF_PRESETS: 392 case EQ_PARAM_BAND_LEVEL: 393 case EQ_PARAM_GET_BAND: 394 if (*pValueSize < sizeof(int16_t)) { 395 return -EINVAL; 396 } 397 *pValueSize = sizeof(int16_t); 398 break; 399 400 case EQ_PARAM_LEVEL_RANGE: 401 if (*pValueSize < 2 * sizeof(int16_t)) { 402 return -EINVAL; 403 } 404 *pValueSize = 2 * sizeof(int16_t); 405 break; 406 407 case EQ_PARAM_BAND_FREQ_RANGE: 408 if (*pValueSize < 2 * sizeof(int32_t)) { 409 return -EINVAL; 410 } 411 *pValueSize = 2 * sizeof(int32_t); 412 break; 413 414 case EQ_PARAM_CENTER_FREQ: 415 if (*pValueSize < sizeof(int32_t)) { 416 return -EINVAL; 417 } 418 *pValueSize = sizeof(int32_t); 419 break; 420 421 case EQ_PARAM_GET_PRESET_NAME: 422 break; 423 424 case EQ_PARAM_PROPERTIES: 425 if (*pValueSize < (2 + kNumBands) * sizeof(uint16_t)) { 426 return -EINVAL; 427 } 428 *pValueSize = (2 + kNumBands) * sizeof(uint16_t); 429 break; 430 431 default: 432 return -EINVAL; 433 } 434 435 switch (param) { 436 case EQ_PARAM_NUM_BANDS: 437 *(uint16_t *)pValue = (uint16_t)kNumBands; 438 ALOGV("Equalizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue); 439 break; 440 441 case EQ_PARAM_LEVEL_RANGE: 442 *(int16_t *)pValue = -9600; 443 *((int16_t *)pValue + 1) = 4800; 444 ALOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d", 445 *(int32_t *)pValue, *((int32_t *)pValue + 1)); 446 break; 447 448 case EQ_PARAM_BAND_LEVEL: 449 param2 = *pParam; 450 if (param2 >= kNumBands) { 451 status = -EINVAL; 452 break; 453 } 454 *(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2); 455 ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", 456 param2, *(int32_t *)pValue); 457 break; 458 459 case EQ_PARAM_CENTER_FREQ: 460 param2 = *pParam; 461 if (param2 >= kNumBands) { 462 status = -EINVAL; 463 break; 464 } 465 *(int32_t *)pValue = pEqualizer->getFrequency(param2); 466 ALOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d", 467 param2, *(int32_t *)pValue); 468 break; 469 470 case EQ_PARAM_BAND_FREQ_RANGE: 471 param2 = *pParam; 472 if (param2 >= kNumBands) { 473 status = -EINVAL; 474 break; 475 } 476 pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1)); 477 ALOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", 478 param2, *(int32_t *)pValue, *((int32_t *)pValue + 1)); 479 break; 480 481 case EQ_PARAM_GET_BAND: 482 param2 = *pParam; 483 *(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2); 484 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d", 485 param2, *(int32_t *)pValue); 486 break; 487 488 case EQ_PARAM_CUR_PRESET: 489 *(uint16_t *)pValue = (uint16_t)pEqualizer->getPreset(); 490 ALOGV("Equalizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue); 491 break; 492 493 case EQ_PARAM_GET_NUM_OF_PRESETS: 494 *(uint16_t *)pValue = (uint16_t)pEqualizer->getNumPresets(); 495 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue); 496 break; 497 498 case EQ_PARAM_GET_PRESET_NAME: 499 param2 = *pParam; 500 if (param2 >= pEqualizer->getNumPresets()) { 501 status = -EINVAL; 502 break; 503 } 504 name = (char *)pValue; 505 strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1); 506 name[*pValueSize - 1] = 0; 507 *pValueSize = strlen(name) + 1; 508 ALOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", 509 param2, gEqualizerPresets[param2].name, *pValueSize); 510 break; 511 512 case EQ_PARAM_PROPERTIES: { 513 int16_t *p = (int16_t *)pValue; 514 ALOGV("Equalizer_getParameter() EQ_PARAM_PROPERTIES"); 515 p[0] = (int16_t)pEqualizer->getPreset(); 516 p[1] = (int16_t)kNumBands; 517 for (int i = 0; i < kNumBands; i++) { 518 p[2 + i] = (int16_t)pEqualizer->getGain(i); 519 } 520 } break; 521 522 default: 523 ALOGV("Equalizer_getParameter() invalid param %d", param); 524 status = -EINVAL; 525 break; 526 } 527 528 return status; 529} // end Equalizer_getParameter 530 531 532//---------------------------------------------------------------------------- 533// Equalizer_setParameter() 534//---------------------------------------------------------------------------- 535// Purpose: 536// Set a Equalizer parameter 537// 538// Inputs: 539// pEqualizer - handle to instance data 540// pParam - pointer to parameter 541// pValue - pointer to value 542// 543// Outputs: 544// 545// 546// Side Effects: 547// 548//---------------------------------------------------------------------------- 549 550int Equalizer_setParameter (AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue) 551{ 552 int status = 0; 553 int32_t preset; 554 int32_t band; 555 int32_t level; 556 int32_t param = *pParam++; 557 558 559 switch (param) { 560 case EQ_PARAM_CUR_PRESET: 561 preset = (int32_t)(*(uint16_t *)pValue); 562 563 ALOGV("setParameter() EQ_PARAM_CUR_PRESET %d", preset); 564 if (preset < 0 || preset >= pEqualizer->getNumPresets()) { 565 status = -EINVAL; 566 break; 567 } 568 pEqualizer->setPreset(preset); 569 pEqualizer->commit(true); 570 break; 571 case EQ_PARAM_BAND_LEVEL: 572 band = *pParam; 573 level = (int32_t)(*(int16_t *)pValue); 574 ALOGV("setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level); 575 if (band >= kNumBands) { 576 status = -EINVAL; 577 break; 578 } 579 pEqualizer->setGain(band, level); 580 pEqualizer->commit(true); 581 break; 582 case EQ_PARAM_PROPERTIES: { 583 ALOGV("setParameter() EQ_PARAM_PROPERTIES"); 584 int16_t *p = (int16_t *)pValue; 585 if ((int)p[0] >= pEqualizer->getNumPresets()) { 586 status = -EINVAL; 587 break; 588 } 589 if (p[0] >= 0) { 590 pEqualizer->setPreset((int)p[0]); 591 } else { 592 if ((int)p[1] != kNumBands) { 593 status = -EINVAL; 594 break; 595 } 596 for (int i = 0; i < kNumBands; i++) { 597 pEqualizer->setGain(i, (int32_t)p[2 + i]); 598 } 599 } 600 pEqualizer->commit(true); 601 } break; 602 default: 603 ALOGV("setParameter() invalid param %d", param); 604 status = -EINVAL; 605 break; 606 } 607 608 return status; 609} // end Equalizer_setParameter 610 611} // namespace 612} // namespace 613 614 615// 616//--- Effect Control Interface Implementation 617// 618 619extern "C" int Equalizer_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) 620{ 621 android::EqualizerContext * pContext = (android::EqualizerContext *) self; 622 623 if (pContext == NULL) { 624 return -EINVAL; 625 } 626 if (inBuffer == NULL || inBuffer->raw == NULL || 627 outBuffer == NULL || outBuffer->raw == NULL || 628 inBuffer->frameCount != outBuffer->frameCount) { 629 return -EINVAL; 630 } 631 632 if (pContext->state == EQUALIZER_STATE_UNINITIALIZED) { 633 return -EINVAL; 634 } 635 if (pContext->state == EQUALIZER_STATE_INITIALIZED) { 636 return -ENODATA; 637 } 638 639 pContext->adapter.process(inBuffer->raw, outBuffer->raw, outBuffer->frameCount); 640 641 return 0; 642} // end Equalizer_process 643 644extern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, 645 void *pCmdData, uint32_t *replySize, void *pReplyData) { 646 647 android::EqualizerContext * pContext = (android::EqualizerContext *) self; 648 int retsize; 649 650 if (pContext == NULL || pContext->state == EQUALIZER_STATE_UNINITIALIZED) { 651 return -EINVAL; 652 } 653 654 android::AudioEqualizer * pEqualizer = pContext->pEqualizer; 655 656 ALOGV("Equalizer_command command %d cmdSize %d",cmdCode, cmdSize); 657 658 switch (cmdCode) { 659 case EFFECT_CMD_INIT: 660 if (pReplyData == NULL || *replySize != sizeof(int)) { 661 return -EINVAL; 662 } 663 *(int *) pReplyData = Equalizer_init(pContext); 664 break; 665 case EFFECT_CMD_SET_CONFIG: 666 if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) 667 || pReplyData == NULL || *replySize != sizeof(int)) { 668 return -EINVAL; 669 } 670 *(int *) pReplyData = Equalizer_setConfig(pContext, 671 (effect_config_t *) pCmdData); 672 break; 673 case EFFECT_CMD_GET_CONFIG: 674 if (pReplyData == NULL || *replySize != sizeof(effect_config_t)) { 675 return -EINVAL; 676 } 677 Equalizer_getConfig(pContext, (effect_config_t *) pCmdData); 678 break; 679 case EFFECT_CMD_RESET: 680 Equalizer_setConfig(pContext, &pContext->config); 681 break; 682 case EFFECT_CMD_GET_PARAM: { 683 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) || 684 pReplyData == NULL || *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))) { 685 return -EINVAL; 686 } 687 effect_param_t *p = (effect_param_t *)pCmdData; 688 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize); 689 p = (effect_param_t *)pReplyData; 690 int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t); 691 p->status = android::Equalizer_getParameter(pEqualizer, (int32_t *)p->data, &p->vsize, 692 p->data + voffset); 693 *replySize = sizeof(effect_param_t) + voffset + p->vsize; 694 ALOGV("Equalizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x", 695 *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize, 696 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset), 697 *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset + sizeof(int32_t))); 698 699 } break; 700 case EFFECT_CMD_SET_PARAM: { 701 ALOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p", 702 cmdSize, pCmdData, *replySize, pReplyData); 703 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) || 704 pReplyData == NULL || *replySize != sizeof(int32_t)) { 705 return -EINVAL; 706 } 707 effect_param_t *p = (effect_param_t *) pCmdData; 708 *(int *)pReplyData = android::Equalizer_setParameter(pEqualizer, (int32_t *)p->data, 709 p->data + p->psize); 710 } break; 711 case EFFECT_CMD_ENABLE: 712 if (pReplyData == NULL || *replySize != sizeof(int)) { 713 return -EINVAL; 714 } 715 if (pContext->state != EQUALIZER_STATE_INITIALIZED) { 716 return -ENOSYS; 717 } 718 pContext->state = EQUALIZER_STATE_ACTIVE; 719 ALOGV("EFFECT_CMD_ENABLE() OK"); 720 *(int *)pReplyData = 0; 721 break; 722 case EFFECT_CMD_DISABLE: 723 if (pReplyData == NULL || *replySize != sizeof(int)) { 724 return -EINVAL; 725 } 726 if (pContext->state != EQUALIZER_STATE_ACTIVE) { 727 return -ENOSYS; 728 } 729 pContext->state = EQUALIZER_STATE_INITIALIZED; 730 ALOGV("EFFECT_CMD_DISABLE() OK"); 731 *(int *)pReplyData = 0; 732 break; 733 case EFFECT_CMD_SET_DEVICE: 734 case EFFECT_CMD_SET_VOLUME: 735 case EFFECT_CMD_SET_AUDIO_MODE: 736 break; 737 default: 738 ALOGW("Equalizer_command invalid command %d",cmdCode); 739 return -EINVAL; 740 } 741 742 return 0; 743} 744 745extern "C" int Equalizer_getDescriptor(effect_handle_t self, 746 effect_descriptor_t *pDescriptor) 747{ 748 android::EqualizerContext * pContext = (android::EqualizerContext *) self; 749 750 if (pContext == NULL || pDescriptor == NULL) { 751 ALOGV("Equalizer_getDescriptor() invalid param"); 752 return -EINVAL; 753 } 754 755 memcpy(pDescriptor, &android::gEqualizerDescriptor, sizeof(effect_descriptor_t)); 756 757 return 0; 758} 759 760// effect_handle_t interface implementation for equalizer effect 761const struct effect_interface_s gEqualizerInterface = { 762 Equalizer_process, 763 Equalizer_command, 764 Equalizer_getDescriptor, 765 NULL 766}; 767 768 769audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { 770 tag : AUDIO_EFFECT_LIBRARY_TAG, 771 version : EFFECT_LIBRARY_API_VERSION, 772 name : "Test Equalizer Library", 773 implementor : "The Android Open Source Project", 774 query_num_effects : android::EffectQueryNumberEffects, 775 query_effect : android::EffectQueryEffect, 776 create_effect : android::EffectCreate, 777 release_effect : android::EffectRelease, 778 get_descriptor : android::EffectGetDescriptor, 779}; 780