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