Home | History | Annotate | Download | only in testlibs
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "Equalizer"
     18 #define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
     19 //
     20 #define LOG_NDEBUG 0
     21 #include <cutils/log.h>
     22 #include <assert.h>
     23 #include <stdlib.h>
     24 #include <string.h>
     25 #include <new>
     26 #include "AudioEqualizer.h"
     27 #include "AudioBiquadFilter.h"
     28 #include "AudioFormatAdapter.h"
     29 #include <audio_effects/effect_equalizer.h>
     30 
     31 
     32 // effect_handle_t interface implementation for equalizer effect
     33 extern "C" const struct effect_interface_s gEqualizerInterface;
     34 
     35 enum equalizer_state_e {
     36     EQUALIZER_STATE_UNINITIALIZED,
     37     EQUALIZER_STATE_INITIALIZED,
     38     EQUALIZER_STATE_ACTIVE,
     39 };
     40 
     41 namespace android {
     42 namespace {
     43 
     44 // Google Graphic Equalizer UUID: e25aa840-543b-11df-98a5-0002a5d5c51b
     45 const effect_descriptor_t gEqualizerDescriptor = {
     46         {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
     47         {0xe25aa840, 0x543b, 0x11df, 0x98a5, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
     48         EFFECT_CONTROL_API_VERSION,
     49         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
     50         0, // TODO
     51         1,
     52         "Graphic Equalizer",
     53         "The Android Open Source Project",
     54 };
     55 
     56 /////////////////// BEGIN EQ PRESETS ///////////////////////////////////////////
     57 const int kNumBands = 5;
     58 const uint32_t gFreqs[kNumBands] =      { 50000, 125000, 900000, 3200000, 6300000 };
     59 const uint32_t gBandwidths[kNumBands] = { 0,     3600,   3600,   2400,    0       };
     60 
     61 const AudioEqualizer::BandConfig gBandsClassic[kNumBands] = {
     62     { 300,  gFreqs[0], gBandwidths[0] },
     63     { 400,  gFreqs[1], gBandwidths[1] },
     64     { 0,    gFreqs[2], gBandwidths[2] },
     65     { 200,  gFreqs[3], gBandwidths[3] },
     66     { -300, gFreqs[4], gBandwidths[4] }
     67 };
     68 
     69 const AudioEqualizer::BandConfig gBandsJazz[kNumBands] = {
     70     { -600, gFreqs[0], gBandwidths[0] },
     71     { 200,  gFreqs[1], gBandwidths[1] },
     72     { 400,  gFreqs[2], gBandwidths[2] },
     73     { -400, gFreqs[3], gBandwidths[3] },
     74     { -600, gFreqs[4], gBandwidths[4] }
     75 };
     76 
     77 const AudioEqualizer::BandConfig gBandsPop[kNumBands] = {
     78     { 400,  gFreqs[0], gBandwidths[0] },
     79     { -400, gFreqs[1], gBandwidths[1] },
     80     { 300,  gFreqs[2], gBandwidths[2] },
     81     { -400, gFreqs[3], gBandwidths[3] },
     82     { 600,  gFreqs[4], gBandwidths[4] }
     83 };
     84 
     85 const AudioEqualizer::BandConfig gBandsRock[kNumBands] = {
     86     { 700,  gFreqs[0], gBandwidths[0] },
     87     { 400,  gFreqs[1], gBandwidths[1] },
     88     { -400, gFreqs[2], gBandwidths[2] },
     89     { 400,  gFreqs[3], gBandwidths[3] },
     90     { 200,  gFreqs[4], gBandwidths[4] }
     91 };
     92 
     93 const AudioEqualizer::PresetConfig gEqualizerPresets[] = {
     94     { "Classic", gBandsClassic },
     95     { "Jazz",    gBandsJazz    },
     96     { "Pop",     gBandsPop     },
     97     { "Rock",    gBandsRock    }
     98 };
     99 
    100 /////////////////// END EQ PRESETS /////////////////////////////////////////////
    101 
    102 static const size_t kBufferSize = 32;
    103 
    104 typedef AudioFormatAdapter<AudioEqualizer, kBufferSize> FormatAdapter;
    105 
    106 struct EqualizerContext {
    107     const struct effect_interface_s *itfe;
    108     effect_config_t config;
    109     FormatAdapter adapter;
    110     AudioEqualizer * pEqualizer;
    111     uint32_t state;
    112 };
    113 
    114 //--- local function prototypes
    115 
    116 int Equalizer_init(EqualizerContext *pContext);
    117 int Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig);
    118 int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, 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     *pDescriptor = gEqualizerDescriptor;
    140     return 0;
    141 } /* end EffectQueryNext */
    142 
    143 extern "C" int EffectCreate(const 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     ALOGV("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         ALOGW("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     ALOGV("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     ALOGV("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(const effect_uuid_t *uuid,
    199                                    effect_descriptor_t *pDescriptor) {
    200 
    201     if (pDescriptor == NULL || uuid == NULL){
    202         ALOGV("EffectGetDescriptor() called with NULL pointer");
    203         return -EINVAL;
    204     }
    205 
    206     if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
    207         *pDescriptor = gEqualizerDescriptor;
    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         ALOGV("Invalid argument: "#cond);      \
    222         return -EINVAL;                       \
    223     }                                         \
    224 }
    225 
    226 //----------------------------------------------------------------------------
    227 // Equalizer_setConfig()
    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_setConfig(EqualizerContext *pContext, effect_config_t *pConfig)
    241 {
    242     ALOGV("Equalizer_setConfig 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     pContext->config = *pConfig;
    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_setConfig
    276 
    277 //----------------------------------------------------------------------------
    278 // Equalizer_getConfig()
    279 //----------------------------------------------------------------------------
    280 // Purpose: Get input and output audio configuration.
    281 //
    282 // Inputs:
    283 //  pContext:   effect engine context
    284 //  pConfig:    pointer to effect_config_t structure holding input and output
    285 //      configuration parameters
    286 //
    287 // Outputs:
    288 //
    289 //----------------------------------------------------------------------------
    290 
    291 void Equalizer_getConfig(EqualizerContext *pContext, effect_config_t *pConfig)
    292 {
    293     *pConfig = pContext->config;
    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 
    310 int 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 
    381 int 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 
    550 int 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 
    619 extern "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 
    644 extern "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 
    745 extern "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     *pDescriptor = android::gEqualizerDescriptor;
    756 
    757     return 0;
    758 }
    759 
    760 // effect_handle_t interface implementation for equalizer effect
    761 const struct effect_interface_s gEqualizerInterface = {
    762         Equalizer_process,
    763         Equalizer_command,
    764         Equalizer_getDescriptor,
    765         NULL
    766 };
    767 
    768 
    769 audio_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