Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright (C) 2010 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 
     18 #include "sles_allinclusive.h"
     19 #include "math.h"
     20 #include "utils/RefBase.h"
     21 #include <audio_effects/effect_bassboost.h>
     22 #include <audio_effects/effect_equalizer.h>
     23 #include <audio_effects/effect_environmentalreverb.h>
     24 #include <audio_effects/effect_presetreverb.h>
     25 #include <audio_effects/effect_virtualizer.h>
     26 
     27 #include <audio_effects/effect_aec.h>
     28 #include <audio_effects/effect_agc.h>
     29 #include <audio_effects/effect_ns.h>
     30 
     31 #include <system/audio.h>
     32 
     33 static const int EQUALIZER_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t)
     34         + EFFECT_STRING_LEN_MAX;
     35 
     36 static const int BASSBOOST_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t);
     37 
     38 static const int VIRTUALIZER_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t);
     39 
     40 static const int ENVREVERB_PARAM_SIZE_MAX_SINGLE = sizeof(effect_param_t) + 2 * sizeof(int32_t);
     41 
     42 static const int ENVREVERB_PARAM_SIZE_MAX_ALL = sizeof(effect_param_t) + sizeof(int32_t)
     43         + sizeof(s_reverb_settings);
     44 
     45 static const int PRESETREVERB_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t);
     46 
     47 static inline SLuint32 KEY_FROM_GUID(SLInterfaceID pUuid) {
     48     return pUuid->time_low;
     49 }
     50 
     51 
     52 //-----------------------------------------------------------------------------
     53 uint32_t eq_paramSize(int32_t param) {
     54     uint32_t size;
     55 
     56     switch (param) {
     57     case EQ_PARAM_NUM_BANDS:
     58     case EQ_PARAM_LEVEL_RANGE:
     59     case EQ_PARAM_CUR_PRESET:
     60     case EQ_PARAM_GET_NUM_OF_PRESETS:
     61         size = sizeof(int32_t);
     62         break;
     63     case EQ_PARAM_BAND_LEVEL:
     64     case EQ_PARAM_CENTER_FREQ:
     65     case EQ_PARAM_BAND_FREQ_RANGE:
     66     case EQ_PARAM_GET_BAND:
     67     case EQ_PARAM_GET_PRESET_NAME:
     68         size = 2 * sizeof(int32_t);
     69         break;
     70     default:
     71         size = 2 * sizeof(int32_t);
     72         SL_LOGE("Trying to use an unknown EQ parameter %d", param);
     73         break;
     74     }
     75     return size;
     76 }
     77 
     78 uint32_t eq_valueSize(int32_t param) {
     79     uint32_t size;
     80 
     81     switch (param) {
     82     case EQ_PARAM_NUM_BANDS:
     83     case EQ_PARAM_CUR_PRESET:
     84     case EQ_PARAM_GET_NUM_OF_PRESETS:
     85     case EQ_PARAM_BAND_LEVEL:
     86     case EQ_PARAM_GET_BAND:
     87         size = sizeof(int16_t);
     88         break;
     89     case EQ_PARAM_LEVEL_RANGE:
     90         size = 2 * sizeof(int16_t);
     91         break;
     92     case EQ_PARAM_CENTER_FREQ:
     93         size = sizeof(int32_t);
     94         break;
     95     case EQ_PARAM_BAND_FREQ_RANGE:
     96         size = 2 * sizeof(int32_t);
     97         break;
     98     case EQ_PARAM_GET_PRESET_NAME:
     99         size = EFFECT_STRING_LEN_MAX;
    100         break;
    101     default:
    102         size = sizeof(int32_t);
    103         SL_LOGE("Trying to access an unknown EQ parameter %d", param);
    104         break;
    105     }
    106     return size;
    107 }
    108 
    109 //-----------------------------------------------------------------------------
    110 /**
    111  * returns the size in bytes of the value of each bass boost parameter
    112  */
    113 uint32_t bb_valueSize(int32_t param) {
    114     uint32_t size;
    115 
    116     switch (param) {
    117     case BASSBOOST_PARAM_STRENGTH_SUPPORTED:
    118         size = sizeof(int32_t);
    119         break;
    120     case BASSBOOST_PARAM_STRENGTH:
    121         size = sizeof(int16_t);
    122         break;
    123     default:
    124         size = sizeof(int32_t);
    125         SL_LOGE("Trying to access an unknown BassBoost parameter %d", param);
    126         break;
    127     }
    128 
    129     return size;
    130 }
    131 
    132 //-----------------------------------------------------------------------------
    133 /**
    134  * returns the size in bytes of the value of each virtualizer parameter
    135  */
    136 uint32_t virt_valueSize(int32_t param) {
    137     uint32_t size;
    138 
    139     switch (param) {
    140     case VIRTUALIZER_PARAM_STRENGTH_SUPPORTED:
    141         size = sizeof(int32_t);
    142         break;
    143     case VIRTUALIZER_PARAM_STRENGTH:
    144         size = sizeof(int16_t);
    145         break;
    146     default:
    147         size = sizeof(int32_t);
    148         SL_LOGE("Trying to access an unknown Virtualizer parameter %d", param);
    149         break;
    150     }
    151 
    152     return size;
    153 }
    154 
    155 //-----------------------------------------------------------------------------
    156 /**
    157  * returns the size in bytes of the value of each environmental reverb parameter
    158  */
    159 uint32_t erev_valueSize(int32_t param) {
    160     uint32_t size;
    161 
    162     switch (param) {
    163     case REVERB_PARAM_ROOM_LEVEL:
    164     case REVERB_PARAM_ROOM_HF_LEVEL:
    165     case REVERB_PARAM_REFLECTIONS_LEVEL:
    166     case REVERB_PARAM_REVERB_LEVEL:
    167         size = sizeof(int16_t); // millibel
    168         break;
    169     case REVERB_PARAM_DECAY_TIME:
    170     case REVERB_PARAM_REFLECTIONS_DELAY:
    171     case REVERB_PARAM_REVERB_DELAY:
    172         size = sizeof(uint32_t); // milliseconds
    173         break;
    174     case REVERB_PARAM_DECAY_HF_RATIO:
    175     case REVERB_PARAM_DIFFUSION:
    176     case REVERB_PARAM_DENSITY:
    177         size = sizeof(int16_t); // permille
    178         break;
    179     case REVERB_PARAM_PROPERTIES:
    180         size = sizeof(s_reverb_settings); // struct of all reverb properties
    181         break;
    182     default:
    183         size = sizeof(int32_t);
    184         SL_LOGE("Trying to access an unknown Environmental Reverb parameter %d", param);
    185         break;
    186     }
    187 
    188     return size;
    189 }
    190 
    191 //-----------------------------------------------------------------------------
    192 android::status_t android_eq_getParam(android::sp<android::AudioEffect> pFx,
    193         int32_t param, int32_t param2, void *pValue)
    194 {
    195      android::status_t status;
    196      uint32_t buf32[(EQUALIZER_PARAM_SIZE_MAX - 1) / sizeof(uint32_t) + 1];
    197      effect_param_t *p = (effect_param_t *)buf32;
    198 
    199      p->psize = eq_paramSize(param);
    200      *(int32_t *)p->data = param;
    201      if (p->psize == 2 * sizeof(int32_t)) {
    202          *((int32_t *)p->data + 1) = param2;
    203      }
    204      p->vsize = eq_valueSize(param);
    205      status = pFx->getParameter(p);
    206      if (android::NO_ERROR == status) {
    207          status = p->status;
    208          if (android::NO_ERROR == status) {
    209              memcpy(pValue, p->data + p->psize, p->vsize);
    210          }
    211      }
    212 
    213      return status;
    214  }
    215 
    216 
    217 //-----------------------------------------------------------------------------
    218 android::status_t android_eq_setParam(android::sp<android::AudioEffect> pFx,
    219         int32_t param, int32_t param2, void *pValue)
    220 {
    221     android::status_t status;
    222     uint32_t buf32[(EQUALIZER_PARAM_SIZE_MAX - 1) / sizeof(uint32_t) + 1];
    223     effect_param_t *p = (effect_param_t *)buf32;
    224 
    225     p->psize = eq_paramSize(param);
    226     *(int32_t *)p->data = param;
    227     if (p->psize == 2 * sizeof(int32_t)) {
    228         *((int32_t *)p->data + 1) = param2;
    229     }
    230     p->vsize = eq_valueSize(param);
    231     memcpy(p->data + p->psize, pValue, p->vsize);
    232     status = pFx->setParameter(p);
    233     if (android::NO_ERROR == status) {
    234         status = p->status;
    235     }
    236 
    237     return status;
    238 }
    239 
    240 //-----------------------------------------------------------------------------
    241 android::status_t android_bb_setParam(android::sp<android::AudioEffect> pFx,
    242         int32_t param, void *pValue) {
    243 
    244     return android_fx_setParam(pFx, param, BASSBOOST_PARAM_SIZE_MAX,
    245             pValue, bb_valueSize(param));
    246 }
    247 
    248 //-----------------------------------------------------------------------------
    249 android::status_t android_bb_getParam(android::sp<android::AudioEffect> pFx,
    250         int32_t param, void *pValue) {
    251 
    252     return android_fx_getParam(pFx, param, BASSBOOST_PARAM_SIZE_MAX,
    253             pValue, bb_valueSize(param));
    254 }
    255 
    256 //-----------------------------------------------------------------------------
    257 void android_bb_init(int sessionId, IBassBoost* ibb) {
    258     SL_LOGV("session %d", sessionId);
    259 
    260     if (!android_fx_initEffectObj(sessionId, ibb->mBassBoostEffect,
    261             &ibb->mBassBoostDescriptor.type))
    262     {
    263         SL_LOGE("BassBoost effect initialization failed");
    264         return;
    265     }
    266 
    267     // initialize strength
    268     int16_t strength;
    269     if (android::NO_ERROR == android_bb_getParam(ibb->mBassBoostEffect,
    270             BASSBOOST_PARAM_STRENGTH, &strength)) {
    271         ibb->mStrength = (SLpermille) strength;
    272     }
    273 }
    274 
    275 
    276 //-----------------------------------------------------------------------------
    277 void android_eq_init(int sessionId, IEqualizer* ieq) {
    278     SL_LOGV("android_eq_init on session %d", sessionId);
    279 
    280     if (!android_fx_initEffectObj(sessionId, ieq->mEqEffect, &ieq->mEqDescriptor.type)) {
    281         SL_LOGE("Equalizer effect initialization failed");
    282         return;
    283     }
    284 
    285     // initialize number of bands, band level range, and number of presets
    286     uint16_t num = 0;
    287     if (android::NO_ERROR == android_eq_getParam(ieq->mEqEffect, EQ_PARAM_NUM_BANDS, 0, &num)) {
    288         ieq->mNumBands = num;
    289     }
    290     int16_t range[2] = {0, 0};
    291     if (android::NO_ERROR == android_eq_getParam(ieq->mEqEffect, EQ_PARAM_LEVEL_RANGE, 0, range)) {
    292         ieq->mBandLevelRangeMin = range[0];
    293         ieq->mBandLevelRangeMax = range[1];
    294     }
    295 
    296     SL_LOGV(" EQ init: num bands = %u, band range=[%d %d]mB", num, range[0], range[1]);
    297 
    298     // FIXME don't store presets names, they can be queried each time they're needed
    299     // initialize preset number and names, store in IEngine
    300     uint16_t numPresets = 0;
    301     if (android::NO_ERROR == android_eq_getParam(ieq->mEqEffect,
    302             EQ_PARAM_GET_NUM_OF_PRESETS, 0, &numPresets)) {
    303         ieq->mThis->mEngine->mEqNumPresets = numPresets;
    304         ieq->mNumPresets = numPresets;
    305     }
    306 
    307     object_lock_exclusive(&ieq->mThis->mEngine->mObject);
    308     char name[EFFECT_STRING_LEN_MAX];
    309     if ((0 < numPresets) && (NULL == ieq->mThis->mEngine->mEqPresetNames)) {
    310         ieq->mThis->mEngine->mEqPresetNames = (char **)new char *[numPresets];
    311         for(uint32_t i = 0 ; i < numPresets ; i++) {
    312             if (android::NO_ERROR == android_eq_getParam(ieq->mEqEffect,
    313                     EQ_PARAM_GET_PRESET_NAME, i, name)) {
    314                 ieq->mThis->mEngine->mEqPresetNames[i] = new char[strlen(name) + 1];
    315                 strcpy(ieq->mThis->mEngine->mEqPresetNames[i], name);
    316                 SL_LOGV(" EQ init: presets = %u is %s", i, ieq->mThis->mEngine->mEqPresetNames[i]);
    317             }
    318         }
    319     }
    320     object_unlock_exclusive(&ieq->mThis->mEngine->mObject);
    321 
    322 }
    323 
    324 
    325 //-----------------------------------------------------------------------------
    326 void android_virt_init(int sessionId, IVirtualizer* ivi) {
    327     SL_LOGV("android_virt_init on session %d", sessionId);
    328 
    329     if (!android_fx_initEffectObj(sessionId, ivi->mVirtualizerEffect,
    330             &ivi->mVirtualizerDescriptor.type)) {
    331         SL_LOGE("Virtualizer effect initialization failed");
    332         return;
    333     }
    334 
    335     // initialize strength
    336     int16_t strength;
    337     if (android::NO_ERROR == android_virt_getParam(ivi->mVirtualizerEffect,
    338             VIRTUALIZER_PARAM_STRENGTH, &strength)) {
    339         ivi->mStrength = (SLpermille) strength;
    340     }
    341 }
    342 
    343 //-----------------------------------------------------------------------------
    344 android::status_t android_virt_setParam(android::sp<android::AudioEffect> pFx,
    345         int32_t param, void *pValue) {
    346 
    347     return android_fx_setParam(pFx, param, VIRTUALIZER_PARAM_SIZE_MAX,
    348             pValue, virt_valueSize(param));
    349 }
    350 
    351 //-----------------------------------------------------------------------------
    352 android::status_t android_virt_getParam(android::sp<android::AudioEffect> pFx,
    353         int32_t param, void *pValue) {
    354 
    355     return android_fx_getParam(pFx, param, VIRTUALIZER_PARAM_SIZE_MAX,
    356             pValue, virt_valueSize(param));
    357 }
    358 
    359 
    360 //-----------------------------------------------------------------------------
    361 void android_prev_init(IPresetReverb* ipr) {
    362     SL_LOGV("session is implicitly %d (aux effect)", AUDIO_SESSION_OUTPUT_MIX);
    363 
    364     if (!android_fx_initEffectObj(AUDIO_SESSION_OUTPUT_MIX /*sessionId*/,
    365             ipr->mPresetReverbEffect, &ipr->mPresetReverbDescriptor.type)) {
    366         SL_LOGE("PresetReverb effect initialization failed");
    367         return;
    368     }
    369 
    370     // initialize preset
    371     uint16_t preset;
    372     if (android::NO_ERROR == android_prev_getPreset(ipr->mPresetReverbEffect, &preset)) {
    373         ipr->mPreset = preset;
    374         // enable the effect if it has a preset loaded
    375         ipr->mPresetReverbEffect->setEnabled(SL_REVERBPRESET_NONE != preset);
    376     }
    377 }
    378 
    379 //-----------------------------------------------------------------------------
    380 android::status_t android_prev_setPreset(android::sp<android::AudioEffect> pFx, uint16_t preset) {
    381     android::status_t status = android_fx_setParam(pFx, REVERB_PARAM_PRESET,
    382             PRESETREVERB_PARAM_SIZE_MAX, &preset, sizeof(uint16_t));
    383     // enable the effect if the preset is different from SL_REVERBPRESET_NONE
    384     pFx->setEnabled(SL_REVERBPRESET_NONE != preset);
    385     return status;
    386 }
    387 
    388 //-----------------------------------------------------------------------------
    389 android::status_t android_prev_getPreset(android::sp<android::AudioEffect> pFx, uint16_t* preset) {
    390     return android_fx_getParam(pFx, REVERB_PARAM_PRESET, PRESETREVERB_PARAM_SIZE_MAX, preset,
    391             sizeof(uint16_t));
    392 }
    393 
    394 
    395 //-----------------------------------------------------------------------------
    396 void android_erev_init(IEnvironmentalReverb* ier) {
    397     SL_LOGV("session is implicitly %d (aux effect)", AUDIO_SESSION_OUTPUT_MIX);
    398 
    399     if (!android_fx_initEffectObj(AUDIO_SESSION_OUTPUT_MIX /*sessionId*/,
    400             ier->mEnvironmentalReverbEffect, &ier->mEnvironmentalReverbDescriptor.type)) {
    401         SL_LOGE("EnvironmentalReverb effect initialization failed");
    402         return;
    403     }
    404 
    405     // enable env reverb: other SL ES effects have an explicit SetEnabled() function, and the
    406     //  preset reverb state depends on the selected preset.
    407     ier->mEnvironmentalReverbEffect->setEnabled(true);
    408 
    409     // initialize reverb properties
    410     SLEnvironmentalReverbSettings properties;
    411     if (android::NO_ERROR == android_erev_getParam(ier->mEnvironmentalReverbEffect,
    412             REVERB_PARAM_PROPERTIES, &properties)) {
    413         ier->mProperties = properties;
    414     }
    415 }
    416 
    417 //-----------------------------------------------------------------------------
    418 android::status_t android_erev_setParam(android::sp<android::AudioEffect> pFx,
    419         int32_t param, void *pValue) {
    420 
    421     // given the size difference between a single reverb property and the whole set of reverb
    422     // properties, select which max size to pass to avoid allocating too much memory
    423     if (param == REVERB_PARAM_PROPERTIES) {
    424         return android_fx_setParam(pFx, param, ENVREVERB_PARAM_SIZE_MAX_ALL,
    425                 pValue, erev_valueSize(param));
    426     } else {
    427         return android_fx_setParam(pFx, param, ENVREVERB_PARAM_SIZE_MAX_SINGLE,
    428                 pValue, erev_valueSize(param));
    429     }
    430 }
    431 
    432 //-----------------------------------------------------------------------------
    433 android::status_t android_erev_getParam(android::sp<android::AudioEffect> pFx,
    434         int32_t param, void *pValue) {
    435 
    436     // given the size difference between a single reverb property and the whole set of reverb
    437     // properties, select which max size to pass to avoid allocating too much memory
    438     if (param == REVERB_PARAM_PROPERTIES) {
    439         return android_fx_getParam(pFx, param, ENVREVERB_PARAM_SIZE_MAX_ALL,
    440                 pValue, erev_valueSize(param));
    441     } else {
    442         return android_fx_getParam(pFx, param, ENVREVERB_PARAM_SIZE_MAX_SINGLE,
    443                 pValue, erev_valueSize(param));
    444     }
    445 }
    446 
    447 
    448 //-----------------------------------------------------------------------------
    449 /**
    450  * pre-condition:
    451  *    ap != NULL
    452  *    for media players:
    453  *      ap->mAPlayer != 0
    454  *      ap->mAudioTrack == 0
    455  *    for buffer queue players:
    456  *      ap->mAPlayer == 0
    457  *      ap->mAudioTrack != 0 is optional; if no track yet then the setting is deferred
    458  */
    459 android::status_t android_fxSend_attach(CAudioPlayer* ap, bool attach,
    460         android::sp<android::AudioEffect> pFx, SLmillibel sendLevel) {
    461 
    462     if (pFx == 0) {
    463         return android::INVALID_OPERATION;
    464     }
    465 
    466     // There are 3 cases:
    467     //  mAPlayer != 0 && mAudioTrack == 0 means playing decoded audio
    468     //  mAPlayer == 0 && mAudioTrack != 0 means playing PCM audio
    469     //  mAPlayer == 0 && mAudioTrack == 0 means player not fully configured yet
    470     // The asserts document and verify this.
    471     if (ap->mAPlayer != 0) {
    472         assert(ap->mAudioTrack == 0);
    473         if (attach) {
    474             ap->mAPlayer->attachAuxEffect(pFx->id());
    475             ap->mAPlayer->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
    476         } else {
    477             ap->mAPlayer->attachAuxEffect(0);
    478         }
    479         return android::NO_ERROR;
    480     }
    481 
    482     if (ap->mAudioTrack == 0) {
    483         // the player doesn't have an AudioTrack at the moment, so store this info to use it
    484         // when the AudioTrack becomes available
    485         if (attach) {
    486             ap->mAuxEffect = pFx;
    487         } else {
    488             ap->mAuxEffect.clear();
    489         }
    490         // we keep track of the send level, independently of the current audio player level
    491         ap->mAuxSendLevel = sendLevel - ap->mVolume.mLevel;
    492         return android::NO_ERROR;
    493     }
    494 
    495     if (attach) {
    496         android::status_t status = ap->mAudioTrack->attachAuxEffect(pFx->id());
    497         //SL_LOGV("attachAuxEffect(%d) returned %d", pFx->id(), status);
    498         if (android::NO_ERROR == status) {
    499             status =
    500                 ap->mAudioTrack->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
    501         }
    502         return status;
    503     } else {
    504         return ap->mAudioTrack->attachAuxEffect(0);
    505     }
    506 }
    507 
    508 //-----------------------------------------------------------------------------
    509 /**
    510  * pre-condition:
    511  *    ap != NULL
    512  *    ap->mOutputMix != NULL
    513  */
    514 SLresult android_fxSend_attachToAux(CAudioPlayer* ap, SLInterfaceID pUuid, SLboolean attach,
    515         SLmillibel sendLevel) {
    516     COutputMix *outputMix = CAudioPlayer_GetOutputMix(ap);
    517     ssize_t index = outputMix->mAndroidEffect.mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
    518 
    519     if (0 > index) {
    520         SL_LOGE("invalid effect ID: no such effect attached to the OutputMix");
    521         return SL_RESULT_PARAMETER_INVALID;
    522     }
    523 
    524     android::AudioEffect* pFx = outputMix->mAndroidEffect.mEffects->valueAt(index);
    525     if (NULL == pFx) {
    526         return SL_RESULT_RESOURCE_ERROR;
    527     }
    528     if (android::NO_ERROR == android_fxSend_attach( ap, (bool) attach, pFx, sendLevel) ) {
    529         return SL_RESULT_SUCCESS;
    530     } else {
    531         return SL_RESULT_RESOURCE_ERROR;
    532     }
    533 
    534 }
    535 
    536 //-----------------------------------------------------------------------------
    537 /**
    538  * pre-condition:
    539  *    ap != NULL
    540  *    for media players:
    541  *      ap->mAPlayer != 0
    542  *      ap->mAudioTrack == 0
    543  *    for buffer queue players:
    544  *      ap->mAPlayer == 0
    545  *      ap->mAudioTrack != 0 is optional; if no track yet then the setting is deferred
    546  */
    547 android::status_t android_fxSend_setSendLevel(CAudioPlayer* ap, SLmillibel sendLevel) {
    548     // we keep track of the send level, independently of the current audio player level
    549     ap->mAuxSendLevel = sendLevel - ap->mVolume.mLevel;
    550 
    551     if (ap->mAPlayer != 0) {
    552         assert(ap->mAudioTrack == 0);
    553         ap->mAPlayer->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
    554         return android::NO_ERROR;
    555     }
    556 
    557     if (ap->mAudioTrack == 0) {
    558         return android::NO_ERROR;
    559     }
    560 
    561     return ap->mAudioTrack->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
    562 }
    563 
    564 //-----------------------------------------------------------------------------
    565 android::status_t android_fx_setParam(android::sp<android::AudioEffect> pFx,
    566         int32_t param, uint32_t paramSizeMax, void *pValue, uint32_t valueSize)
    567 {
    568 
    569     android::status_t status;
    570     uint32_t buf32[(paramSizeMax - 1) / sizeof(uint32_t) + 1];
    571     effect_param_t *p = (effect_param_t *)buf32;
    572 
    573     p->psize = sizeof(int32_t);
    574     *(int32_t *)p->data = param;
    575     p->vsize = valueSize;
    576     memcpy(p->data + p->psize, pValue, p->vsize);
    577     status = pFx->setParameter(p);
    578     if (android::NO_ERROR == status) {
    579         status = p->status;
    580     }
    581     return status;
    582 }
    583 
    584 
    585 //-----------------------------------------------------------------------------
    586 android::status_t android_fx_getParam(android::sp<android::AudioEffect> pFx,
    587         int32_t param, uint32_t paramSizeMax, void *pValue, uint32_t valueSize)
    588 {
    589     android::status_t status;
    590     uint32_t buf32[(paramSizeMax - 1) / sizeof(uint32_t) + 1];
    591     effect_param_t *p = (effect_param_t *)buf32;
    592 
    593     p->psize = sizeof(int32_t);
    594     *(int32_t *)p->data = param;
    595     p->vsize = valueSize;
    596     status = pFx->getParameter(p);
    597     if (android::NO_ERROR == status) {
    598         status = p->status;
    599         if (android::NO_ERROR == status) {
    600             memcpy(pValue, p->data + p->psize, p->vsize);
    601         }
    602     }
    603 
    604     return status;
    605 }
    606 
    607 
    608 //-----------------------------------------------------------------------------
    609 SLresult android_fx_statusToResult(android::status_t status) {
    610 
    611     if ((android::INVALID_OPERATION == status) || (android::DEAD_OBJECT == status)) {
    612         return SL_RESULT_CONTROL_LOST;
    613     } else {
    614         return SL_RESULT_SUCCESS;
    615     }
    616 }
    617 
    618 
    619 //-----------------------------------------------------------------------------
    620 bool android_fx_initEffectObj(int sessionId, android::sp<android::AudioEffect>& effect,
    621         const effect_uuid_t *type) {
    622     //SL_LOGV("android_fx_initEffectObj on session %d", sessionId);
    623 
    624     effect = new android::AudioEffect(type, EFFECT_UUID_NULL,
    625             0,// priority
    626             0,// effect callback
    627             0,// callback data
    628             sessionId,// session ID
    629             0 );// output
    630 
    631     android::status_t status = effect->initCheck();
    632     if (android::NO_ERROR != status) {
    633         effect.clear();
    634         SL_LOGE("Effect initCheck() returned %d", status);
    635         return false;
    636     }
    637 
    638     return true;
    639 }
    640 
    641 
    642 //-----------------------------------------------------------------------------
    643 bool android_fx_initEffectDescriptor(const SLInterfaceID effectId,
    644         effect_descriptor_t* fxDescrLoc) {
    645     uint32_t numEffects = 0;
    646     effect_descriptor_t descriptor;
    647     bool foundEffect = false;
    648 
    649     // any effects?
    650     android::status_t res = android::AudioEffect::queryNumberEffects(&numEffects);
    651     if (android::NO_ERROR != res) {
    652         SL_LOGE("unable to find any effects.");
    653         goto effectError;
    654     }
    655 
    656     // request effect in the effects?
    657     for (uint32_t i=0 ; i < numEffects ; i++) {
    658         res = android::AudioEffect::queryEffect(i, &descriptor);
    659         if ((android::NO_ERROR == res) &&
    660                 (0 == memcmp(effectId, &descriptor.type, sizeof(effect_uuid_t)))) {
    661             SL_LOGV("found effect %d %s", i, descriptor.name);
    662             foundEffect = true;
    663             break;
    664         }
    665     }
    666     if (foundEffect) {
    667         memcpy(fxDescrLoc, &descriptor, sizeof(effect_descriptor_t));
    668     } else {
    669         SL_LOGE("unable to find an implementation for the requested effect.");
    670         goto effectError;
    671     }
    672 
    673     return true;
    674 
    675 effectError:
    676     // the requested effect wasn't found
    677     memset(fxDescrLoc, 0, sizeof(effect_descriptor_t));
    678 
    679     return false;
    680 }
    681 
    682 //-----------------------------------------------------------------------------
    683 SLresult android_genericFx_queryNumEffects(SLuint32 *pNumSupportedAudioEffects) {
    684 
    685     if (NULL == pNumSupportedAudioEffects) {
    686         return SL_RESULT_PARAMETER_INVALID;
    687     }
    688 
    689     android::status_t status =
    690             android::AudioEffect::queryNumberEffects((uint32_t*)pNumSupportedAudioEffects);
    691 
    692     SLresult result = SL_RESULT_SUCCESS;
    693     switch(status) {
    694         case android::NO_ERROR:
    695             result = SL_RESULT_SUCCESS;
    696             break;
    697         case android::PERMISSION_DENIED:
    698             result = SL_RESULT_PERMISSION_DENIED;
    699             break;
    700         case android::NO_INIT:
    701             result = SL_RESULT_RESOURCE_ERROR;
    702             break;
    703         case android::BAD_VALUE:
    704             result = SL_RESULT_PARAMETER_INVALID;
    705             break;
    706         default:
    707             result = SL_RESULT_INTERNAL_ERROR;
    708             SL_LOGE("received invalid status %d from AudioEffect::queryNumberEffects()", status);
    709             break;
    710     }
    711     return result;
    712 }
    713 
    714 
    715 //-----------------------------------------------------------------------------
    716 SLresult android_genericFx_queryEffect(SLuint32 index, effect_descriptor_t* pDescriptor) {
    717 
    718     if (NULL == pDescriptor) {
    719         return SL_RESULT_PARAMETER_INVALID;
    720     }
    721 
    722     android::status_t status =
    723                 android::AudioEffect::queryEffect(index, pDescriptor);
    724 
    725     SLresult result = SL_RESULT_SUCCESS;
    726     if (android::NO_ERROR != status) {
    727         switch(status) {
    728         case android::PERMISSION_DENIED:
    729             result = SL_RESULT_PERMISSION_DENIED;
    730             break;
    731         case android::NO_INIT:
    732         case android::INVALID_OPERATION:
    733             result = SL_RESULT_RESOURCE_ERROR;
    734             break;
    735         case android::BAD_VALUE:
    736             result = SL_RESULT_PARAMETER_INVALID;
    737             break;
    738         default:
    739             result = SL_RESULT_INTERNAL_ERROR;
    740             SL_LOGE("received invalid status %d from AudioEffect::queryNumberEffects()", status);
    741             break;
    742         }
    743         // an error occurred, reset the effect descriptor
    744         memset(pDescriptor, 0, sizeof(effect_descriptor_t));
    745     }
    746 
    747     return result;
    748 }
    749 
    750 
    751 //-----------------------------------------------------------------------------
    752 SLresult android_genericFx_createEffect(IAndroidEffect* iae, SLInterfaceID pUuid, int sessionId) {
    753 
    754     SLresult result = SL_RESULT_SUCCESS;
    755 
    756     // does this effect already exist?
    757     if (0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid))) {
    758         return result;
    759     }
    760 
    761     // create new effect
    762     android::AudioEffect* pFx = new android::AudioEffect(
    763             NULL, // not using type to create effect
    764             (const effect_uuid_t*)pUuid,
    765             0,// priority
    766             0,// effect callback
    767             0,// callback data
    768             sessionId,
    769             0 );// output
    770 
    771     // verify effect was successfully created before storing it
    772     android::status_t status = pFx->initCheck();
    773     if (android::NO_ERROR != status) {
    774         SL_LOGE("AudioEffect initCheck() returned %d, effect will not be stored", status);
    775         delete pFx;
    776         result = SL_RESULT_RESOURCE_ERROR;
    777     } else {
    778         SL_LOGV("AudioEffect successfully created on session %d", sessionId);
    779         iae->mEffects->add(KEY_FROM_GUID(pUuid), pFx);
    780     }
    781 
    782     return result;
    783 }
    784 
    785 
    786 //-----------------------------------------------------------------------------
    787 SLresult android_genericFx_releaseEffect(IAndroidEffect* iae, SLInterfaceID pUuid) {
    788 
    789     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
    790 
    791     if (0 > index) {
    792         return SL_RESULT_PARAMETER_INVALID;
    793     } else {
    794         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
    795         delete pFx;
    796         iae->mEffects->removeItem(index);
    797         return SL_RESULT_SUCCESS;
    798     }
    799 }
    800 
    801 
    802 //-----------------------------------------------------------------------------
    803 SLresult android_genericFx_setEnabled(IAndroidEffect* iae, SLInterfaceID pUuid, SLboolean enabled) {
    804 
    805     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
    806 
    807     if (0 > index) {
    808         return SL_RESULT_PARAMETER_INVALID;
    809     } else {
    810         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
    811         android::status_t status = pFx->setEnabled(SL_BOOLEAN_TRUE == enabled);
    812         return android_fx_statusToResult(status);
    813     }
    814 }
    815 
    816 
    817 //-----------------------------------------------------------------------------
    818 SLresult android_genericFx_isEnabled(IAndroidEffect* iae, SLInterfaceID pUuid, SLboolean *pEnabled)
    819 {
    820     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
    821 
    822     if (0 > index) {
    823         return SL_RESULT_PARAMETER_INVALID;
    824     } else {
    825         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
    826         *pEnabled = (SLboolean) pFx->getEnabled();
    827         return SL_RESULT_SUCCESS;
    828     }
    829 }
    830 
    831 
    832 //-----------------------------------------------------------------------------
    833 SLresult android_genericFx_sendCommand(IAndroidEffect* iae, SLInterfaceID pUuid,
    834         SLuint32 command, SLuint32 commandSize, void* pCommandData,
    835         SLuint32 *replySize, void *pReplyData) {
    836 
    837     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
    838 
    839     if (0 > index) {
    840         return SL_RESULT_PARAMETER_INVALID;
    841     } else {
    842         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
    843         android::status_t status = pFx->command(
    844                 (uint32_t) command,
    845                 (uint32_t) commandSize,
    846                 pCommandData,
    847                 (uint32_t*)replySize,
    848                 pReplyData);
    849         if (android::BAD_VALUE == status) {
    850                 return SL_RESULT_PARAMETER_INVALID;
    851         } else {
    852             return SL_RESULT_SUCCESS;
    853         }
    854     }
    855 }
    856 
    857 //-----------------------------------------------------------------------------
    858 /**
    859  * returns true if the given effect id is present in the AndroidEffect interface
    860  */
    861 bool android_genericFx_hasEffect(IAndroidEffect* iae, SLInterfaceID pUuid) {
    862     return( 0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid)));
    863 }
    864 
    865 //-----------------------------------------------------------------------------
    866 static const int AEC_PARAM_SIZE_MAX = sizeof(effect_param_t) + (2 * sizeof(int32_t));
    867 /**
    868  * returns the size in bytes of the value of each acoustic echo cancellation parameter
    869  */
    870 uint32_t aec_valueSize(int32_t param) {
    871     uint32_t size;
    872     switch (param) {
    873     case AEC_PARAM_ECHO_DELAY:
    874         size = sizeof(int32_t);
    875         break;
    876     default:
    877         size = sizeof(int32_t);
    878         SL_LOGE("Trying to access an unknown Acoustic Echo Cancellation parameter %d", param);
    879         break;
    880     }
    881 
    882     return size;
    883 }
    884 
    885 android::status_t android_aec_setParam(android::sp<android::AudioEffect> pFx,
    886         int32_t param, void *pValue) {
    887     return android_fx_setParam(pFx, param, AEC_PARAM_SIZE_MAX,
    888             pValue, aec_valueSize(param));
    889 }
    890 
    891 android::status_t android_aec_getParam(android::sp<android::AudioEffect> pFx,
    892         int32_t param, void *pValue) {
    893     return android_fx_getParam(pFx, param, AEC_PARAM_SIZE_MAX,
    894             pValue, aec_valueSize(param));
    895 }
    896 
    897 //-----------------------------------------------------------------------------
    898 static const int AGC_PARAM_SIZE_MAX = sizeof(effect_param_t) + (2 * sizeof(int16_t)) + sizeof(bool);
    899 /**
    900  * returns the size in bytes of the value of each automatic gain control parameter
    901  */
    902 uint32_t agc_valueSize(int32_t param) {
    903     uint32_t size;
    904     switch (param) {
    905     case AGC_PARAM_TARGET_LEVEL:
    906     case AGC_PARAM_COMP_GAIN:
    907         size = sizeof(int16_t);
    908         break;
    909     case AGC_PARAM_LIMITER_ENA:
    910         size = sizeof(bool);
    911         break;
    912     default:
    913         size = sizeof(int32_t);
    914         SL_LOGE("Trying to access an unknown Automatic Gain Control parameter %d", param);
    915         break;
    916     }
    917 
    918     return size;
    919 }
    920 
    921 android::status_t android_agc_setParam(android::sp<android::AudioEffect> pFx,
    922         int32_t param, void *pValue) {
    923     return android_fx_setParam(pFx, param, AGC_PARAM_SIZE_MAX,
    924             pValue, agc_valueSize(param));
    925 }
    926 
    927 android::status_t android_agc_getParam(android::sp<android::AudioEffect> pFx,
    928         int32_t param, void *pValue) {
    929     return android_fx_getParam(pFx, param, AGC_PARAM_SIZE_MAX,
    930             pValue, agc_valueSize(param));
    931 }
    932 
    933 //-----------------------------------------------------------------------------
    934 static const int NS_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t);
    935 /**
    936  * returns the size in bytes of the value of each noise suppression parameter
    937  */
    938 uint32_t ns_valueSize(int32_t param) {
    939     uint32_t size;
    940     switch (param) {
    941     case NS_PARAM_LEVEL:
    942         size = sizeof(int32_t);
    943         break;
    944     default:
    945         size = sizeof(int32_t);
    946         SL_LOGE("Trying to access an unknown Noise suppression parameter %d", param);
    947         break;
    948     }
    949 
    950     return size;
    951 }
    952 
    953 android::status_t android_ns_setParam(android::sp<android::AudioEffect> pFx,
    954         int32_t param, void *pValue)
    955 {
    956     return android_fx_setParam(pFx, param, NS_PARAM_SIZE_MAX,
    957             pValue, ns_valueSize(param));
    958 }
    959 
    960 android::status_t android_ns_getParam(android::sp<android::AudioEffect> pFx,
    961         int32_t param, void *pValue)
    962 {
    963     return android_fx_getParam(pFx, param, NS_PARAM_SIZE_MAX,
    964             pValue, ns_valueSize(param));
    965 }
    966