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