Home | History | Annotate | Download | only in itf
      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 /* EnvironmentalReverb implementation */
     18 
     19 #include "sles_allinclusive.h"
     20 #ifdef ANDROID
     21 #include <audio_effects/effect_environmentalreverb.h>
     22 #endif
     23 
     24 // Note: all Set operations use exclusive not poke,
     25 // because SetEnvironmentalReverbProperties is exclusive.
     26 // It is safe for the Get operations to use peek,
     27 // on the assumption that the block copy will atomically
     28 // replace each word of the block.
     29 
     30 
     31 #if defined(ANDROID)
     32 /**
     33  * returns true if this interface is not associated with an initialized EnvironmentalReverb effect
     34  */
     35 static inline bool NO_ENVREVERB(IEnvironmentalReverb* ier) {
     36     return (ier->mEnvironmentalReverbEffect == 0);
     37 }
     38 #endif
     39 
     40 
     41 static SLresult IEnvironmentalReverb_SetRoomLevel(SLEnvironmentalReverbItf self, SLmillibel room)
     42 {
     43     SL_ENTER_INTERFACE
     44 
     45     //if (!(SL_MILLIBEL_MIN <= room && room <= 0)) {
     46     // comparison (SL_MILLIBEL_MIN <= room) is always true due to range of SLmillibel
     47     if (!(room <= 0)) {
     48         result = SL_RESULT_PARAMETER_INVALID;
     49     } else {
     50         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
     51         interface_lock_exclusive(thiz);
     52         thiz->mProperties.roomLevel = room;
     53 #if !defined(ANDROID)
     54         result = SL_RESULT_SUCCESS;
     55 #else
     56         if (NO_ENVREVERB(thiz)) {
     57             result = SL_RESULT_CONTROL_LOST;
     58         } else {
     59             android::status_t status = android_erev_setParam(thiz->mEnvironmentalReverbEffect,
     60                     REVERB_PARAM_ROOM_LEVEL, &room);
     61             result = android_fx_statusToResult(status);
     62         }
     63 #endif
     64         interface_unlock_exclusive(thiz);
     65     }
     66 
     67     SL_LEAVE_INTERFACE
     68 }
     69 
     70 
     71 static SLresult IEnvironmentalReverb_GetRoomLevel(SLEnvironmentalReverbItf self, SLmillibel *pRoom)
     72 {
     73     SL_ENTER_INTERFACE
     74 
     75     if (NULL == pRoom) {
     76         result = SL_RESULT_PARAMETER_INVALID;
     77     } else {
     78         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
     79         interface_lock_shared(thiz);
     80 #if 1 // !defined(ANDROID)
     81         result = SL_RESULT_SUCCESS;
     82 #else
     83         if (NO_ENVREVERB(thiz)) {
     84             result = SL_RESULT_CONTROL_LOST;
     85         } else {
     86             android::status_t status = android_erev_getParam(thiz->mEnvironmentalReverbEffect,
     87                     REVERB_PARAM_ROOM_LEVEL, &thiz->mProperties.roomLevel);
     88             result = android_fx_statusToResult(status);
     89         }
     90 #endif
     91         *pRoom = thiz->mProperties.roomLevel;
     92 
     93         interface_unlock_shared(thiz);
     94 
     95     }
     96 
     97     SL_LEAVE_INTERFACE
     98 }
     99 
    100 
    101 static SLresult IEnvironmentalReverb_SetRoomHFLevel(
    102     SLEnvironmentalReverbItf self, SLmillibel roomHF)
    103 {
    104     SL_ENTER_INTERFACE
    105 
    106     //if (!(SL_MILLIBEL_MIN <= roomHF && roomHF <= 0)) {
    107     // comparison (SL_MILLIBEL_MIN <= roomHF) is always true due to range of SLmillibel
    108     if (!(roomHF <= 0)) {
    109         result = SL_RESULT_PARAMETER_INVALID;
    110     } else {
    111         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    112         interface_lock_exclusive(thiz);
    113         thiz->mProperties.roomHFLevel = roomHF;
    114 #if !defined(ANDROID)
    115         result = SL_RESULT_SUCCESS;
    116 #else
    117         if (NO_ENVREVERB(thiz)) {
    118             result = SL_RESULT_CONTROL_LOST;
    119         } else {
    120             android::status_t status = android_erev_setParam(thiz->mEnvironmentalReverbEffect,
    121                     REVERB_PARAM_ROOM_HF_LEVEL, &roomHF);
    122             result = android_fx_statusToResult(status);
    123         }
    124 #endif
    125         interface_unlock_exclusive(thiz);
    126     }
    127 
    128     SL_LEAVE_INTERFACE
    129 }
    130 
    131 
    132 static SLresult IEnvironmentalReverb_GetRoomHFLevel(
    133     SLEnvironmentalReverbItf self, SLmillibel *pRoomHF)
    134 {
    135     SL_ENTER_INTERFACE
    136 
    137     if (NULL == pRoomHF) {
    138         result = SL_RESULT_PARAMETER_INVALID;
    139     } else {
    140         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    141         interface_lock_shared(thiz);
    142 #if 1 // !defined(ANDROID)
    143         result = SL_RESULT_SUCCESS;
    144 #else
    145         if (NO_ENVREVERB(thiz)) {
    146             result = SL_RESULT_CONTROL_LOST;
    147         } else {
    148             android::status_t status = android_erev_getParam(thiz->mEnvironmentalReverbEffect,
    149                     REVERB_PARAM_ROOM_HF_LEVEL, &thiz->mProperties.roomHFLevel);
    150             result = android_fx_statusToResult(status);
    151         }
    152 #endif
    153         *pRoomHF = thiz->mProperties.roomHFLevel;
    154 
    155         interface_unlock_shared(thiz);
    156     }
    157 
    158     SL_LEAVE_INTERFACE
    159 }
    160 
    161 
    162 static SLresult IEnvironmentalReverb_SetDecayTime(
    163     SLEnvironmentalReverbItf self, SLmillisecond decayTime)
    164 {
    165     SL_ENTER_INTERFACE
    166 
    167     if (!(100 <= decayTime && decayTime <= 20000)) {
    168         result = SL_RESULT_PARAMETER_INVALID;
    169     } else {
    170         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    171         interface_lock_exclusive(thiz);
    172         thiz->mProperties.decayTime = decayTime;
    173 #if 1 // !defined(ANDROID)
    174         result = SL_RESULT_SUCCESS;
    175 #else
    176         if (NO_ENVREVERB(thiz)) {
    177             result = SL_RESULT_CONTROL_LOST;
    178         } else {
    179             android::status_t status = android_erev_setParam(thiz->mEnvironmentalReverbEffect,
    180                     REVERB_PARAM_DECAY_TIME, &decayTime);
    181             result = android_fx_statusToResult(status);
    182         }
    183 #endif
    184         interface_unlock_exclusive(thiz);
    185     }
    186 
    187     SL_LEAVE_INTERFACE
    188 }
    189 
    190 
    191 static SLresult IEnvironmentalReverb_GetDecayTime(
    192     SLEnvironmentalReverbItf self, SLmillisecond *pDecayTime)
    193 {
    194     SL_ENTER_INTERFACE
    195 
    196     if (NULL == pDecayTime) {
    197         result = SL_RESULT_PARAMETER_INVALID;
    198     } else {
    199         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    200         interface_lock_shared(thiz);
    201 #if 1 // !defined(ANDROID)
    202         result = SL_RESULT_SUCCESS;
    203 #else
    204         if (NO_ENVREVERB(thiz)) {
    205             result = SL_RESULT_CONTROL_LOST;
    206         } else {
    207             android::status_t status = android_erev_getParam(thiz->mEnvironmentalReverbEffect,
    208                     REVERB_PARAM_DECAY_TIME, &thiz->mProperties.decayTime);
    209             result = android_fx_statusToResult(status);
    210         }
    211 #endif
    212         *pDecayTime = thiz->mProperties.decayTime;
    213 
    214         interface_unlock_shared(thiz);
    215     }
    216 
    217     SL_LEAVE_INTERFACE
    218 }
    219 
    220 
    221 static SLresult IEnvironmentalReverb_SetDecayHFRatio(
    222     SLEnvironmentalReverbItf self, SLpermille decayHFRatio)
    223 {
    224     SL_ENTER_INTERFACE
    225 
    226     if (!(100 <= decayHFRatio && decayHFRatio <= 2000)) {
    227         result = SL_RESULT_PARAMETER_INVALID;
    228     } else {
    229         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    230         interface_lock_exclusive(thiz);
    231         thiz->mProperties.decayHFRatio = decayHFRatio;
    232 #if !defined(ANDROID)
    233         result = SL_RESULT_SUCCESS;
    234 #else
    235         if (NO_ENVREVERB(thiz)) {
    236             result = SL_RESULT_CONTROL_LOST;
    237         } else {
    238             android::status_t status = android_erev_setParam(thiz->mEnvironmentalReverbEffect,
    239                     REVERB_PARAM_DECAY_HF_RATIO, &decayHFRatio);
    240             result = android_fx_statusToResult(status);
    241         }
    242 #endif
    243         interface_unlock_exclusive(thiz);
    244     }
    245 
    246     SL_LEAVE_INTERFACE
    247 }
    248 
    249 
    250 static SLresult IEnvironmentalReverb_GetDecayHFRatio(
    251     SLEnvironmentalReverbItf self, SLpermille *pDecayHFRatio)
    252 {
    253     SL_ENTER_INTERFACE
    254 
    255     if (NULL == pDecayHFRatio) {
    256         result = SL_RESULT_PARAMETER_INVALID;
    257     } else {
    258         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    259         interface_lock_shared(thiz);
    260 #if 1 // !defined(ANDROID)
    261         result = SL_RESULT_SUCCESS;
    262 #else
    263         if (NO_ENVREVERB(thiz)) {
    264             result = SL_RESULT_CONTROL_LOST;
    265         } else {
    266             android::status_t status = android_erev_getParam(thiz->mEnvironmentalReverbEffect,
    267                     REVERB_PARAM_DECAY_HF_RATIO, &thiz->mProperties.decayHFRatio);
    268             result = android_fx_statusToResult(status);
    269         }
    270 #endif
    271         *pDecayHFRatio = thiz->mProperties.decayHFRatio;
    272 
    273         interface_unlock_shared(thiz);
    274     }
    275 
    276     SL_LEAVE_INTERFACE
    277 }
    278 
    279 
    280 static SLresult IEnvironmentalReverb_SetReflectionsLevel(
    281     SLEnvironmentalReverbItf self, SLmillibel reflectionsLevel)
    282 {
    283     SL_ENTER_INTERFACE
    284 
    285     //if (!(SL_MILLIBEL_MIN <= reflectionsLevel && reflectionsLevel <= 1000)) {
    286     // comparison (SL_MILLIBEL_MIN <= reflectionsLevel) is always true due to range of SLmillibel
    287     if (!(reflectionsLevel <= 1000)) {
    288         result = SL_RESULT_PARAMETER_INVALID;
    289     } else {
    290         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    291         interface_lock_exclusive(thiz);
    292         thiz->mProperties.reflectionsLevel = reflectionsLevel;
    293 #if !defined(ANDROID)
    294         result = SL_RESULT_SUCCESS;
    295 #else
    296         if (NO_ENVREVERB(thiz)) {
    297             result = SL_RESULT_CONTROL_LOST;
    298         } else {
    299             android::status_t status = android_erev_setParam(thiz->mEnvironmentalReverbEffect,
    300                     REVERB_PARAM_REFLECTIONS_LEVEL, &reflectionsLevel);
    301             result = android_fx_statusToResult(status);
    302         }
    303 #endif
    304         interface_unlock_exclusive(thiz);
    305     }
    306 
    307     SL_LEAVE_INTERFACE
    308 }
    309 
    310 
    311 static SLresult IEnvironmentalReverb_GetReflectionsLevel(
    312     SLEnvironmentalReverbItf self, SLmillibel *pReflectionsLevel)
    313 {
    314     SL_ENTER_INTERFACE
    315 
    316     if (NULL == pReflectionsLevel) {
    317         result = SL_RESULT_PARAMETER_INVALID;
    318     } else {
    319         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    320         interface_lock_shared(thiz);
    321 #if 1 // !defined(ANDROID)
    322         result = SL_RESULT_SUCCESS;
    323 #else
    324         if (NO_ENVREVERB(thiz)) {
    325             result = SL_RESULT_CONTROL_LOST;
    326         } else {
    327             android::status_t status = android_erev_getParam(thiz->mEnvironmentalReverbEffect,
    328                     REVERB_PARAM_REFLECTIONS_LEVEL, &thiz->mProperties.reflectionsLevel);
    329             result = android_fx_statusToResult(status);
    330         }
    331 #endif
    332         *pReflectionsLevel = thiz->mProperties.reflectionsLevel;
    333 
    334         interface_unlock_shared(thiz);
    335     }
    336 
    337     SL_LEAVE_INTERFACE
    338 }
    339 
    340 
    341 static SLresult IEnvironmentalReverb_SetReflectionsDelay(
    342     SLEnvironmentalReverbItf self, SLmillisecond reflectionsDelay)
    343 {
    344     SL_ENTER_INTERFACE
    345 
    346     if (!(/* 0 <= reflectionsDelay && */ reflectionsDelay <= 300)) {
    347         result = SL_RESULT_PARAMETER_INVALID;
    348     } else {
    349         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    350         interface_lock_exclusive(thiz);
    351         thiz->mProperties.reflectionsDelay = reflectionsDelay;
    352 #if !defined(ANDROID)
    353         result = SL_RESULT_SUCCESS;
    354 #else
    355         if (NO_ENVREVERB(thiz)) {
    356             result = SL_RESULT_CONTROL_LOST;
    357         } else {
    358             android::status_t status = android_erev_setParam(thiz->mEnvironmentalReverbEffect,
    359                     REVERB_PARAM_REFLECTIONS_DELAY, &reflectionsDelay);
    360             result = android_fx_statusToResult(status);
    361         }
    362 #endif
    363         interface_unlock_exclusive(thiz);
    364     }
    365 
    366     SL_LEAVE_INTERFACE
    367 }
    368 
    369 
    370 static SLresult IEnvironmentalReverb_GetReflectionsDelay(
    371     SLEnvironmentalReverbItf self, SLmillisecond *pReflectionsDelay)
    372 {
    373     SL_ENTER_INTERFACE
    374 
    375     if (NULL == pReflectionsDelay) {
    376         result = SL_RESULT_PARAMETER_INVALID;
    377     } else {
    378         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    379         interface_lock_shared(thiz);
    380 #if 1 // !defined(ANDROID)
    381         result = SL_RESULT_SUCCESS;
    382 #else
    383         if (NO_ENVREVERB(thiz)) {
    384             result = SL_RESULT_CONTROL_LOST;
    385         } else {
    386             android::status_t status = android_erev_getParam(thiz->mEnvironmentalReverbEffect,
    387                     REVERB_PARAM_REFLECTIONS_DELAY, &thiz->mProperties.reflectionsDelay);
    388             result = android_fx_statusToResult(status);
    389         }
    390 #endif
    391         *pReflectionsDelay = thiz->mProperties.reflectionsDelay;
    392 
    393         interface_unlock_shared(thiz);
    394     }
    395 
    396     SL_LEAVE_INTERFACE
    397 }
    398 
    399 
    400 static SLresult IEnvironmentalReverb_SetReverbLevel(
    401     SLEnvironmentalReverbItf self, SLmillibel reverbLevel)
    402 {
    403     SL_ENTER_INTERFACE
    404 
    405     //if (!(SL_MILLIBEL_MIN <= reverbLevel && reverbLevel <= 2000)) {
    406     // comparison (SL_MILLIBEL_MIN <= reverbLevel) is always true due to range of SLmillibel
    407     if (!(reverbLevel <= 2000)) {
    408         result = SL_RESULT_PARAMETER_INVALID;
    409     } else {
    410         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    411         interface_lock_exclusive(thiz);
    412         thiz->mProperties.reverbLevel = reverbLevel;
    413 #if !defined(ANDROID)
    414         result = SL_RESULT_SUCCESS;
    415 #else
    416         if (NO_ENVREVERB(thiz)) {
    417             result = SL_RESULT_CONTROL_LOST;
    418         } else {
    419             android::status_t status = android_erev_setParam(thiz->mEnvironmentalReverbEffect,
    420                     REVERB_PARAM_REVERB_LEVEL, &reverbLevel);
    421             result = android_fx_statusToResult(status);
    422         }
    423 #endif
    424         interface_unlock_exclusive(thiz);
    425     }
    426 
    427     SL_LEAVE_INTERFACE
    428 }
    429 
    430 
    431 static SLresult IEnvironmentalReverb_GetReverbLevel(
    432     SLEnvironmentalReverbItf self, SLmillibel *pReverbLevel)
    433 {
    434     SL_ENTER_INTERFACE
    435 
    436     if (NULL == pReverbLevel) {
    437         result = SL_RESULT_PARAMETER_INVALID;
    438     } else {
    439         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    440         interface_lock_shared(thiz);
    441 #if 1 // !defined(ANDROID)
    442         result = SL_RESULT_SUCCESS;
    443 #else
    444         if (NO_ENVREVERB(thiz)) {
    445             result = SL_RESULT_CONTROL_LOST;
    446         } else {
    447             android::status_t status = android_erev_getParam(thiz->mEnvironmentalReverbEffect,
    448                     REVERB_PARAM_REVERB_LEVEL, &thiz->mProperties.reverbLevel);
    449             result = android_fx_statusToResult(status);
    450         }
    451 #endif
    452         *pReverbLevel = thiz->mProperties.reverbLevel;
    453 
    454         interface_unlock_shared(thiz);
    455     }
    456 
    457     SL_LEAVE_INTERFACE
    458 }
    459 
    460 
    461 static SLresult IEnvironmentalReverb_SetReverbDelay(
    462     SLEnvironmentalReverbItf self, SLmillisecond reverbDelay)
    463 {
    464     SL_ENTER_INTERFACE
    465 
    466     if (!(/* 0 <= reverbDelay && */ reverbDelay <= 100)) {
    467         result = SL_RESULT_PARAMETER_INVALID;
    468     } else {
    469         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    470         interface_lock_exclusive(thiz);
    471         thiz->mProperties.reverbDelay = reverbDelay;
    472 #if !defined(ANDROID)
    473         result = SL_RESULT_SUCCESS;
    474 #else
    475         if (NO_ENVREVERB(thiz)) {
    476             result = SL_RESULT_CONTROL_LOST;
    477         } else {
    478             android::status_t status = android_erev_setParam(thiz->mEnvironmentalReverbEffect,
    479                     REVERB_PARAM_REVERB_DELAY, &reverbDelay);
    480             result = android_fx_statusToResult(status);
    481         }
    482 #endif
    483         interface_unlock_exclusive(thiz);
    484     }
    485 
    486     SL_LEAVE_INTERFACE
    487 }
    488 
    489 
    490 static SLresult IEnvironmentalReverb_GetReverbDelay(
    491     SLEnvironmentalReverbItf self, SLmillisecond *pReverbDelay)
    492 {
    493     SL_ENTER_INTERFACE
    494 
    495     if (NULL == pReverbDelay) {
    496         result = SL_RESULT_PARAMETER_INVALID;
    497     } else {
    498         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    499         interface_lock_shared(thiz);
    500 #if 1 // !defined(ANDROID)
    501         result = SL_RESULT_SUCCESS;
    502 #else
    503         if (NO_ENVREVERB(thiz)) {
    504             result = SL_RESULT_CONTROL_LOST;
    505         } else {
    506             android::status_t status = android_erev_getParam(thiz->mEnvironmentalReverbEffect,
    507                     REVERB_PARAM_REVERB_DELAY, &thiz->mProperties.reverbDelay);
    508             result = android_fx_statusToResult(status);
    509         }
    510 #endif
    511         *pReverbDelay = thiz->mProperties.reverbDelay;
    512 
    513         interface_unlock_shared(thiz);
    514     }
    515 
    516     SL_LEAVE_INTERFACE
    517 }
    518 
    519 
    520 static SLresult IEnvironmentalReverb_SetDiffusion(
    521     SLEnvironmentalReverbItf self, SLpermille diffusion)
    522 {
    523     SL_ENTER_INTERFACE
    524 
    525     if (!(0 <= diffusion && diffusion <= 1000)) {
    526         result = SL_RESULT_PARAMETER_INVALID;
    527     } else {
    528         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    529         interface_lock_exclusive(thiz);
    530         thiz->mProperties.diffusion = diffusion;
    531 #if !defined(ANDROID)
    532         result = SL_RESULT_SUCCESS;
    533 #else
    534         if (NO_ENVREVERB(thiz)) {
    535             result = SL_RESULT_CONTROL_LOST;
    536         } else {
    537             android::status_t status = android_erev_setParam(thiz->mEnvironmentalReverbEffect,
    538                     REVERB_PARAM_DIFFUSION, &diffusion);
    539             result = android_fx_statusToResult(status);
    540         }
    541 #endif
    542         interface_unlock_exclusive(thiz);
    543     }
    544 
    545     SL_LEAVE_INTERFACE
    546 }
    547 
    548 
    549 static SLresult IEnvironmentalReverb_GetDiffusion(SLEnvironmentalReverbItf self,
    550      SLpermille *pDiffusion)
    551 {
    552     SL_ENTER_INTERFACE
    553 
    554     if (NULL == pDiffusion) {
    555         result = SL_RESULT_PARAMETER_INVALID;
    556     } else {
    557         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    558         interface_lock_shared(thiz);
    559 #if 1 // !defined(ANDROID)
    560         result = SL_RESULT_SUCCESS;
    561 #else
    562         if (NO_ENVREVERB(thiz)) {
    563             result = SL_RESULT_CONTROL_LOST;
    564         } else {
    565             android::status_t status = android_erev_getParam(thiz->mEnvironmentalReverbEffect,
    566                     REVERB_PARAM_DIFFUSION, &thiz->mProperties.diffusion);
    567             result = android_fx_statusToResult(status);
    568         }
    569 #endif
    570         *pDiffusion = thiz->mProperties.diffusion;
    571 
    572         interface_unlock_shared(thiz);
    573     }
    574 
    575     SL_LEAVE_INTERFACE
    576 }
    577 
    578 
    579 static SLresult IEnvironmentalReverb_SetDensity(SLEnvironmentalReverbItf self,
    580     SLpermille density)
    581 {
    582     SL_ENTER_INTERFACE
    583 
    584     if (!(0 <= density && density <= 1000)) {
    585         result = SL_RESULT_PARAMETER_INVALID;
    586     } else {
    587         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    588         interface_lock_exclusive(thiz);
    589         thiz->mProperties.density = density;
    590 #if !defined(ANDROID)
    591         result = SL_RESULT_SUCCESS;
    592 #else
    593         if (NO_ENVREVERB(thiz)) {
    594             result = SL_RESULT_CONTROL_LOST;
    595         } else {
    596             android::status_t status = android_erev_setParam(thiz->mEnvironmentalReverbEffect,
    597                     REVERB_PARAM_DENSITY, &density);
    598             result = android_fx_statusToResult(status);
    599         }
    600 #endif
    601         interface_unlock_exclusive(thiz);
    602     }
    603 
    604     SL_LEAVE_INTERFACE
    605 }
    606 
    607 
    608 static SLresult IEnvironmentalReverb_GetDensity(SLEnvironmentalReverbItf self,
    609     SLpermille *pDensity)
    610 {
    611     SL_ENTER_INTERFACE
    612 
    613     if (NULL == pDensity) {
    614         result = SL_RESULT_PARAMETER_INVALID;
    615     } else {
    616         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    617         interface_lock_shared(thiz);
    618 #if 1 // !defined(ANDROID)
    619         result = SL_RESULT_SUCCESS;
    620 #else
    621         if (NO_ENVREVERB(thiz)) {
    622             result = SL_RESULT_CONTROL_LOST;
    623         } else {
    624             android::status_t status = android_erev_getParam(thiz->mEnvironmentalReverbEffect,
    625                     REVERB_PARAM_DENSITY, &thiz->mProperties.density);
    626             result = android_fx_statusToResult(status);
    627         }
    628 #endif
    629         *pDensity = thiz->mProperties.density;
    630 
    631         interface_unlock_shared(thiz);
    632     }
    633 
    634     SL_LEAVE_INTERFACE
    635 }
    636 
    637 
    638 static SLresult IEnvironmentalReverb_SetEnvironmentalReverbProperties(SLEnvironmentalReverbItf self,
    639     const SLEnvironmentalReverbSettings *pProperties)
    640 {
    641     SL_ENTER_INTERFACE
    642 
    643     // note that it's unnecessary to verify that any level stored inside the "properties" struct
    644     //  is >= SL_MILLIBEL_MIN before using it, due to range of SLmillibel
    645 
    646     result = SL_RESULT_PARAMETER_INVALID;
    647     do {
    648         if (NULL == pProperties)
    649             break;
    650         SLEnvironmentalReverbSettings properties = *pProperties;
    651         if (!(properties.roomLevel <= 0))
    652             break;
    653         if (!(properties.roomHFLevel <= 0))
    654             break;
    655         if (!(100 <= properties.decayTime && properties.decayTime <= 20000))
    656             break;
    657         if (!(100 <= properties.decayHFRatio && properties.decayHFRatio <= 2000))
    658             break;
    659         if (!(properties.reflectionsLevel <= 1000))
    660             break;
    661         if (!(/* 0 <= properties.reflectionsDelay && */ properties.reflectionsDelay <= 300))
    662             break;
    663         if (!(properties.reverbLevel <= 2000))
    664             break;
    665         if (!(/* 0 <= properties.reverbDelay && */ properties.reverbDelay <= 100))
    666             break;
    667         if (!(0 <= properties.diffusion && properties.diffusion <= 1000))
    668             break;
    669         if (!(0 <= properties.density && properties.density <= 1000))
    670             break;
    671         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    672         interface_lock_exclusive(thiz);
    673         thiz->mProperties = properties;
    674 #if !defined(ANDROID)
    675         result = SL_RESULT_SUCCESS;
    676 #else
    677         if (NO_ENVREVERB(thiz)) {
    678             result = SL_RESULT_CONTROL_LOST;
    679         } else {
    680             android::status_t status = android_erev_setParam(thiz->mEnvironmentalReverbEffect,
    681                     REVERB_PARAM_PROPERTIES, &properties);
    682             result = android_fx_statusToResult(status);
    683         }
    684 #endif
    685         interface_unlock_exclusive(thiz);
    686     } while (0);
    687 
    688     SL_LEAVE_INTERFACE
    689 }
    690 
    691 
    692 static SLresult IEnvironmentalReverb_GetEnvironmentalReverbProperties(
    693     SLEnvironmentalReverbItf self, SLEnvironmentalReverbSettings *pProperties)
    694 {
    695     SL_ENTER_INTERFACE
    696 
    697     if (NULL == pProperties) {
    698         result = SL_RESULT_PARAMETER_INVALID;
    699     } else {
    700         IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    701         interface_lock_shared(thiz);
    702 #if 1 // !defined(ANDROID)
    703         result = SL_RESULT_SUCCESS;
    704 #else
    705         if (NO_ENVREVERB(thiz)) {
    706             result = SL_RESULT_CONTROL_LOST;
    707         } else {
    708             android::status_t status = android_erev_getParam(thiz->mEnvironmentalReverbEffect,
    709                     REVERB_PARAM_PROPERTIES, &thiz->mProperties);
    710             result = android_fx_statusToResult(status);
    711         }
    712 #endif
    713         *pProperties = thiz->mProperties;
    714 
    715         interface_unlock_shared(thiz);
    716     }
    717 
    718     SL_LEAVE_INTERFACE
    719 }
    720 
    721 
    722 static const struct SLEnvironmentalReverbItf_ IEnvironmentalReverb_Itf = {
    723     IEnvironmentalReverb_SetRoomLevel,
    724     IEnvironmentalReverb_GetRoomLevel,
    725     IEnvironmentalReverb_SetRoomHFLevel,
    726     IEnvironmentalReverb_GetRoomHFLevel,
    727     IEnvironmentalReverb_SetDecayTime,
    728     IEnvironmentalReverb_GetDecayTime,
    729     IEnvironmentalReverb_SetDecayHFRatio,
    730     IEnvironmentalReverb_GetDecayHFRatio,
    731     IEnvironmentalReverb_SetReflectionsLevel,
    732     IEnvironmentalReverb_GetReflectionsLevel,
    733     IEnvironmentalReverb_SetReflectionsDelay,
    734     IEnvironmentalReverb_GetReflectionsDelay,
    735     IEnvironmentalReverb_SetReverbLevel,
    736     IEnvironmentalReverb_GetReverbLevel,
    737     IEnvironmentalReverb_SetReverbDelay,
    738     IEnvironmentalReverb_GetReverbDelay,
    739     IEnvironmentalReverb_SetDiffusion,
    740     IEnvironmentalReverb_GetDiffusion,
    741     IEnvironmentalReverb_SetDensity,
    742     IEnvironmentalReverb_GetDensity,
    743     IEnvironmentalReverb_SetEnvironmentalReverbProperties,
    744     IEnvironmentalReverb_GetEnvironmentalReverbProperties
    745 };
    746 
    747 static const SLEnvironmentalReverbSettings IEnvironmentalReverb_default = {
    748     SL_MILLIBEL_MIN, // roomLevel
    749     0,               // roomHFLevel
    750     1000,            // decayTime
    751     500,             // decayHFRatio
    752     SL_MILLIBEL_MIN, // reflectionsLevel
    753     20,              // reflectionsDelay
    754     SL_MILLIBEL_MIN, // reverbLevel
    755     40,              // reverbDelay
    756     1000,            // diffusion
    757     1000             // density
    758 };
    759 
    760 void IEnvironmentalReverb_init(void *self)
    761 {
    762     IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    763     thiz->mItf = &IEnvironmentalReverb_Itf;
    764     thiz->mProperties = IEnvironmentalReverb_default;
    765 #if defined(ANDROID)
    766     memset(&thiz->mEnvironmentalReverbDescriptor, 0, sizeof(effect_descriptor_t));
    767     // placement new (explicit constructor)
    768     (void) new (&thiz->mEnvironmentalReverbEffect) android::sp<android::AudioEffect>();
    769 #endif
    770 }
    771 
    772 void IEnvironmentalReverb_deinit(void *self)
    773 {
    774 #if defined(ANDROID)
    775     IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    776     // explicit destructor
    777     thiz->mEnvironmentalReverbEffect.~sp();
    778 #endif
    779 }
    780 
    781 bool IEnvironmentalReverb_Expose(void *self)
    782 {
    783 #if defined(ANDROID)
    784     IEnvironmentalReverb *thiz = (IEnvironmentalReverb *) self;
    785     if (!android_fx_initEffectDescriptor(SL_IID_ENVIRONMENTALREVERB,
    786             &thiz->mEnvironmentalReverbDescriptor)) {
    787         SL_LOGE("EnvironmentalReverb initialization failed.");
    788         return false;
    789     }
    790 #endif
    791     return true;
    792 }
    793