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