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 if it has a 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 /**
    446  * pre-condition:
    447  *    ap != NULL
    448  *    for media players:
    449  *      ap->mAPlayer != 0
    450  *      ap->mAudioTrack == 0
    451  *    for buffer queue players:
    452  *      ap->mAPlayer == 0
    453  *      ap->mAudioTrack != 0 is optional; if no track yet then the setting is deferred
    454  */
    455 android::status_t android_fxSend_attach(CAudioPlayer* ap, bool attach,
    456         android::sp<android::AudioEffect> pFx, SLmillibel sendLevel) {
    457 
    458     if (pFx == 0) {
    459         return android::INVALID_OPERATION;
    460     }
    461 
    462     // There are 3 cases:
    463     //  mAPlayer != 0 && mAudioTrack == 0 means playing decoded audio
    464     //  mAPlayer == 0 && mAudioTrack != 0 means playing PCM audio
    465     //  mAPlayer == 0 && mAudioTrack == 0 means player not fully configured yet
    466     // The asserts document and verify this.
    467     if (ap->mAPlayer != 0) {
    468         assert(ap->mAudioTrack == 0);
    469         if (attach) {
    470             ap->mAPlayer->attachAuxEffect(pFx->id());
    471             ap->mAPlayer->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
    472         } else {
    473             ap->mAPlayer->attachAuxEffect(0);
    474         }
    475         return android::NO_ERROR;
    476     }
    477 
    478     if (ap->mAudioTrack == 0) {
    479         // the player doesn't have an AudioTrack at the moment, so store this info to use it
    480         // when the AudioTrack becomes available
    481         if (attach) {
    482             ap->mAuxEffect = pFx;
    483         } else {
    484             ap->mAuxEffect.clear();
    485         }
    486         // we keep track of the send level, independently of the current audio player level
    487         ap->mAuxSendLevel = sendLevel - ap->mVolume.mLevel;
    488         return android::NO_ERROR;
    489     }
    490 
    491     if (attach) {
    492         android::status_t status = ap->mAudioTrack->attachAuxEffect(pFx->id());
    493         //SL_LOGV("attachAuxEffect(%d) returned %d", pFx->id(), status);
    494         if (android::NO_ERROR == status) {
    495             status =
    496                 ap->mAudioTrack->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
    497         }
    498         return status;
    499     } else {
    500         return ap->mAudioTrack->attachAuxEffect(0);
    501     }
    502 }
    503 
    504 //-----------------------------------------------------------------------------
    505 /**
    506  * pre-condition:
    507  *    ap != NULL
    508  *    ap->mOutputMix != NULL
    509  */
    510 SLresult android_fxSend_attachToAux(CAudioPlayer* ap, SLInterfaceID pUuid, SLboolean attach,
    511         SLmillibel sendLevel) {
    512     COutputMix *outputMix = CAudioPlayer_GetOutputMix(ap);
    513     ssize_t index = outputMix->mAndroidEffect.mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
    514 
    515     if (0 > index) {
    516         SL_LOGE("invalid effect ID: no such effect attached to the OutputMix");
    517         return SL_RESULT_PARAMETER_INVALID;
    518     }
    519 
    520     android::AudioEffect* pFx = outputMix->mAndroidEffect.mEffects->valueAt(index);
    521     if (NULL == pFx) {
    522         return SL_RESULT_RESOURCE_ERROR;
    523     }
    524     if (android::NO_ERROR == android_fxSend_attach( ap, (bool) attach, pFx, sendLevel) ) {
    525         return SL_RESULT_SUCCESS;
    526     } else {
    527         return SL_RESULT_RESOURCE_ERROR;
    528     }
    529 
    530 }
    531 
    532 //-----------------------------------------------------------------------------
    533 /**
    534  * pre-condition:
    535  *    ap != NULL
    536  *    for media players:
    537  *      ap->mAPlayer != 0
    538  *      ap->mAudioTrack == 0
    539  *    for buffer queue players:
    540  *      ap->mAPlayer == 0
    541  *      ap->mAudioTrack != 0 is optional; if no track yet then the setting is deferred
    542  */
    543 android::status_t android_fxSend_setSendLevel(CAudioPlayer* ap, SLmillibel sendLevel) {
    544     // we keep track of the send level, independently of the current audio player level
    545     ap->mAuxSendLevel = sendLevel - ap->mVolume.mLevel;
    546 
    547     if (ap->mAPlayer != 0) {
    548         assert(ap->mAudioTrack == 0);
    549         ap->mAPlayer->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
    550         return android::NO_ERROR;
    551     }
    552 
    553     if (ap->mAudioTrack == 0) {
    554         return android::NO_ERROR;
    555     }
    556 
    557     return ap->mAudioTrack->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
    558 }
    559 
    560 //-----------------------------------------------------------------------------
    561 android::status_t android_fx_setParam(android::sp<android::AudioEffect> pFx,
    562         int32_t param, uint32_t paramSizeMax, void *pValue, uint32_t valueSize)
    563 {
    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     memcpy(p->data + p->psize, pValue, p->vsize);
    573     status = pFx->setParameter(p);
    574     if (android::NO_ERROR == status) {
    575         status = p->status;
    576     }
    577     return status;
    578 }
    579 
    580 
    581 //-----------------------------------------------------------------------------
    582 android::status_t android_fx_getParam(android::sp<android::AudioEffect> pFx,
    583         int32_t param, uint32_t paramSizeMax, void *pValue, uint32_t valueSize)
    584 {
    585     android::status_t status;
    586     uint32_t buf32[(paramSizeMax - 1) / sizeof(uint32_t) + 1];
    587     effect_param_t *p = (effect_param_t *)buf32;
    588 
    589     p->psize = sizeof(int32_t);
    590     *(int32_t *)p->data = param;
    591     p->vsize = valueSize;
    592     status = pFx->getParameter(p);
    593     if (android::NO_ERROR == status) {
    594         status = p->status;
    595         if (android::NO_ERROR == status) {
    596             memcpy(pValue, p->data + p->psize, p->vsize);
    597         }
    598     }
    599 
    600     return status;
    601 }
    602 
    603 
    604 //-----------------------------------------------------------------------------
    605 SLresult android_fx_statusToResult(android::status_t status) {
    606 
    607     if ((android::INVALID_OPERATION == status) || (android::DEAD_OBJECT == status)) {
    608         return SL_RESULT_CONTROL_LOST;
    609     } else {
    610         return SL_RESULT_SUCCESS;
    611     }
    612 }
    613 
    614 
    615 //-----------------------------------------------------------------------------
    616 bool android_fx_initEffectObj(int sessionId, android::sp<android::AudioEffect>& effect,
    617         const effect_uuid_t *type) {
    618     //SL_LOGV("android_fx_initEffectObj on session %d", sessionId);
    619 
    620     effect = new android::AudioEffect(type, EFFECT_UUID_NULL,
    621             0,// priority
    622             0,// effect callback
    623             0,// callback data
    624             sessionId,// session ID
    625             0 );// output
    626 
    627     android::status_t status = effect->initCheck();
    628     if (android::NO_ERROR != status) {
    629         effect.clear();
    630         SL_LOGE("Effect initCheck() returned %d", status);
    631         return false;
    632     }
    633 
    634     return true;
    635 }
    636 
    637 
    638 //-----------------------------------------------------------------------------
    639 bool android_fx_initEffectDescriptor(const SLInterfaceID effectId,
    640         effect_descriptor_t* fxDescrLoc) {
    641     uint32_t numEffects = 0;
    642     effect_descriptor_t descriptor;
    643     bool foundEffect = false;
    644 
    645     // any effects?
    646     android::status_t res = android::AudioEffect::queryNumberEffects(&numEffects);
    647     if (android::NO_ERROR != res) {
    648         SL_LOGE("unable to find any effects.");
    649         goto effectError;
    650     }
    651 
    652     // request effect in the effects?
    653     for (uint32_t i=0 ; i < numEffects ; i++) {
    654         res = android::AudioEffect::queryEffect(i, &descriptor);
    655         if ((android::NO_ERROR == res) &&
    656                 (0 == memcmp(effectId, &descriptor.type, sizeof(effect_uuid_t)))) {
    657             SL_LOGV("found effect %d %s", i, descriptor.name);
    658             foundEffect = true;
    659             break;
    660         }
    661     }
    662     if (foundEffect) {
    663         memcpy(fxDescrLoc, &descriptor, sizeof(effect_descriptor_t));
    664     } else {
    665         SL_LOGE("unable to find an implementation for the requested effect.");
    666         goto effectError;
    667     }
    668 
    669     return true;
    670 
    671 effectError:
    672     // the requested effect wasn't found
    673     memset(fxDescrLoc, 0, sizeof(effect_descriptor_t));
    674 
    675     return false;
    676 }
    677 
    678 //-----------------------------------------------------------------------------
    679 SLresult android_genericFx_queryNumEffects(SLuint32 *pNumSupportedAudioEffects) {
    680 
    681     if (NULL == pNumSupportedAudioEffects) {
    682         return SL_RESULT_PARAMETER_INVALID;
    683     }
    684 
    685     android::status_t status =
    686             android::AudioEffect::queryNumberEffects((uint32_t*)pNumSupportedAudioEffects);
    687 
    688     SLresult result = SL_RESULT_SUCCESS;
    689     switch(status) {
    690         case android::NO_ERROR:
    691             result = SL_RESULT_SUCCESS;
    692             break;
    693         case android::PERMISSION_DENIED:
    694             result = SL_RESULT_PERMISSION_DENIED;
    695             break;
    696         case android::NO_INIT:
    697             result = SL_RESULT_RESOURCE_ERROR;
    698             break;
    699         case android::BAD_VALUE:
    700             result = SL_RESULT_PARAMETER_INVALID;
    701             break;
    702         default:
    703             result = SL_RESULT_INTERNAL_ERROR;
    704             SL_LOGE("received invalid status %d from AudioEffect::queryNumberEffects()", status);
    705             break;
    706     }
    707     return result;
    708 }
    709 
    710 
    711 //-----------------------------------------------------------------------------
    712 SLresult android_genericFx_queryEffect(SLuint32 index, effect_descriptor_t* pDescriptor) {
    713 
    714     if (NULL == pDescriptor) {
    715         return SL_RESULT_PARAMETER_INVALID;
    716     }
    717 
    718     android::status_t status =
    719                 android::AudioEffect::queryEffect(index, pDescriptor);
    720 
    721     SLresult result = SL_RESULT_SUCCESS;
    722     if (android::NO_ERROR != status) {
    723         switch(status) {
    724         case android::PERMISSION_DENIED:
    725             result = SL_RESULT_PERMISSION_DENIED;
    726             break;
    727         case android::NO_INIT:
    728         case android::INVALID_OPERATION:
    729             result = SL_RESULT_RESOURCE_ERROR;
    730             break;
    731         case android::BAD_VALUE:
    732             result = SL_RESULT_PARAMETER_INVALID;
    733             break;
    734         default:
    735             result = SL_RESULT_INTERNAL_ERROR;
    736             SL_LOGE("received invalid status %d from AudioEffect::queryNumberEffects()", status);
    737             break;
    738         }
    739         // an error occurred, reset the effect descriptor
    740         memset(pDescriptor, 0, sizeof(effect_descriptor_t));
    741     }
    742 
    743     return result;
    744 }
    745 
    746 
    747 //-----------------------------------------------------------------------------
    748 SLresult android_genericFx_createEffect(IAndroidEffect* iae, SLInterfaceID pUuid, int sessionId) {
    749 
    750     SLresult result = SL_RESULT_SUCCESS;
    751 
    752     // does this effect already exist?
    753     if (0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid))) {
    754         return result;
    755     }
    756 
    757     // create new effect
    758     android::AudioEffect* pFx = new android::AudioEffect(
    759             NULL, // not using type to create effect
    760             (const effect_uuid_t*)pUuid,
    761             0,// priority
    762             0,// effect callback
    763             0,// callback data
    764             sessionId,
    765             0 );// output
    766 
    767     // verify effect was successfully created before storing it
    768     android::status_t status = pFx->initCheck();
    769     if (android::NO_ERROR != status) {
    770         SL_LOGE("AudioEffect initCheck() returned %d, effect will not be stored", status);
    771         delete pFx;
    772         result = SL_RESULT_RESOURCE_ERROR;
    773     } else {
    774         SL_LOGV("AudioEffect successfully created on session %d", sessionId);
    775         iae->mEffects->add(KEY_FROM_GUID(pUuid), pFx);
    776     }
    777 
    778     return result;
    779 }
    780 
    781 
    782 //-----------------------------------------------------------------------------
    783 SLresult android_genericFx_releaseEffect(IAndroidEffect* iae, SLInterfaceID pUuid) {
    784 
    785     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
    786 
    787     if (0 > index) {
    788         return SL_RESULT_PARAMETER_INVALID;
    789     } else {
    790         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
    791         delete pFx;
    792         iae->mEffects->removeItem(index);
    793         return SL_RESULT_SUCCESS;
    794     }
    795 }
    796 
    797 
    798 //-----------------------------------------------------------------------------
    799 SLresult android_genericFx_setEnabled(IAndroidEffect* iae, SLInterfaceID pUuid, SLboolean enabled) {
    800 
    801     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
    802 
    803     if (0 > index) {
    804         return SL_RESULT_PARAMETER_INVALID;
    805     } else {
    806         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
    807         android::status_t status = pFx->setEnabled(SL_BOOLEAN_TRUE == enabled);
    808         return android_fx_statusToResult(status);
    809     }
    810 }
    811 
    812 
    813 //-----------------------------------------------------------------------------
    814 SLresult android_genericFx_isEnabled(IAndroidEffect* iae, SLInterfaceID pUuid, SLboolean *pEnabled)
    815 {
    816     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
    817 
    818     if (0 > index) {
    819         return SL_RESULT_PARAMETER_INVALID;
    820     } else {
    821         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
    822         *pEnabled = (SLboolean) pFx->getEnabled();
    823         return SL_RESULT_SUCCESS;
    824     }
    825 }
    826 
    827 
    828 //-----------------------------------------------------------------------------
    829 SLresult android_genericFx_sendCommand(IAndroidEffect* iae, SLInterfaceID pUuid,
    830         SLuint32 command, SLuint32 commandSize, void* pCommandData,
    831         SLuint32 *replySize, void *pReplyData) {
    832 
    833     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
    834 
    835     if (0 > index) {
    836         return SL_RESULT_PARAMETER_INVALID;
    837     } else {
    838         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
    839         android::status_t status = pFx->command(
    840                 (uint32_t) command,
    841                 (uint32_t) commandSize,
    842                 pCommandData,
    843                 (uint32_t*)replySize,
    844                 pReplyData);
    845         if (android::BAD_VALUE == status) {
    846                 return SL_RESULT_PARAMETER_INVALID;
    847         } else {
    848             return SL_RESULT_SUCCESS;
    849         }
    850     }
    851 }
    852 
    853 //-----------------------------------------------------------------------------
    854 /**
    855  * returns true if the given effect id is present in the AndroidEffect interface
    856  */
    857 bool android_genericFx_hasEffect(IAndroidEffect* iae, SLInterfaceID pUuid) {
    858     return( 0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid)));
    859 }
    860