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