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