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 /* AndroidEffectSend implementation */
     18 
     19 #include "sles_allinclusive.h"
     20 
     21 
     22 static SLresult IAndroidEffectSend_EnableEffectSend(SLAndroidEffectSendItf self,
     23     SLInterfaceID effectImplementationId, SLboolean enable, SLmillibel initialLevel)
     24 {
     25     SL_ENTER_INTERFACE
     26 
     27     //if (!((SL_MILLIBEL_MIN <= initialLevel) && (initialLevel <= 0))) {
     28     // comparison (SL_MILLIBEL_MIN <= initialLevel) is always true due to range of SLmillibel
     29     if (!(initialLevel <= 0)) {
     30         result = SL_RESULT_PARAMETER_INVALID;
     31     } else {
     32         IAndroidEffectSend *thiz = (IAndroidEffectSend *) self;
     33         interface_lock_exclusive(thiz);
     34         // is SLAndroidEffectSendItf on an AudioPlayer?
     35         CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) ?
     36                 (CAudioPlayer *) thiz->mThis : NULL;
     37         if (NULL == ap) {
     38             SL_LOGE("invalid interface: not attached to an AudioPlayer");
     39             result = SL_RESULT_PARAMETER_INVALID;
     40         } else {
     41             // the initial send level set here is the total energy on the aux bus,
     42             //  so it must take into account the player volume level
     43             result = android_fxSend_attachToAux(ap, effectImplementationId, enable,
     44                     initialLevel + ap->mVolume.mLevel);
     45             if (SL_RESULT_SUCCESS == result) {
     46                 // there currently is support for only one send bus, so there is a single send
     47                 // level and a single enable flag
     48                 thiz->mSendLevel = initialLevel;
     49                 thiz->mEnabled = enable;
     50             }
     51         }
     52         interface_unlock_exclusive(thiz);
     53     }
     54 
     55     SL_LEAVE_INTERFACE
     56 }
     57 
     58 
     59 static SLresult IAndroidEffectSend_IsEnabled(SLAndroidEffectSendItf self,
     60     SLInterfaceID effectImplementationId, SLboolean *pEnable)
     61 {
     62     SL_ENTER_INTERFACE
     63 
     64     if (NULL == pEnable) {
     65         result = SL_RESULT_PARAMETER_INVALID;
     66     } else {
     67         IAndroidEffectSend *thiz = (IAndroidEffectSend *) self;
     68         interface_lock_shared(thiz);
     69         // there currently is support for only one send bus, so there is a single enable flag
     70         SLboolean enable = thiz->mEnabled;
     71         interface_unlock_shared(thiz);
     72         *pEnable = enable;
     73         result = SL_RESULT_SUCCESS;
     74     }
     75 
     76     SL_LEAVE_INTERFACE
     77 }
     78 
     79 
     80 static SLresult IAndroidEffectSend_SetDirectLevel(SLAndroidEffectSendItf self,
     81         SLmillibel directLevel)
     82 {
     83     SL_ENTER_INTERFACE
     84 
     85     //if (!((SL_MILLIBEL_MIN <= directLevel) && (directLevel <= 0))) {
     86     // comparison (SL_MILLIBEL_MIN <= directLevel) is always true due to range of SLmillibel
     87     if (!(directLevel <= 0)) {
     88         result = SL_RESULT_PARAMETER_INVALID;
     89     } else {
     90         IAndroidEffectSend *thiz = (IAndroidEffectSend *) self;
     91         interface_lock_exclusive(thiz);
     92         CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) ?
     93                 (CAudioPlayer *) thiz->mThis : NULL;
     94         if (NULL != ap) {
     95             SLmillibel oldDirectLevel = ap->mDirectLevel;
     96             if (oldDirectLevel != directLevel) {
     97                 ap->mDirectLevel = directLevel;
     98                 ap->mAmplFromDirectLevel = sles_to_android_amplification(directLevel);
     99                 interface_unlock_exclusive_attributes(thiz, ATTR_GAIN);
    100             } else {
    101                 interface_unlock_exclusive(thiz);
    102             }
    103             result = SL_RESULT_SUCCESS;
    104         } else {
    105             interface_unlock_exclusive(thiz);
    106             SL_LOGE("invalid interface: not attached to an AudioPlayer");
    107             result = SL_RESULT_PARAMETER_INVALID;
    108         }
    109     }
    110 
    111      SL_LEAVE_INTERFACE
    112 }
    113 
    114 
    115 static SLresult IAndroidEffectSend_GetDirectLevel(SLAndroidEffectSendItf self,
    116         SLmillibel *pDirectLevel)
    117 {
    118     SL_ENTER_INTERFACE
    119 
    120     if (NULL == pDirectLevel) {
    121         result = SL_RESULT_PARAMETER_INVALID;
    122     } else {
    123         IAndroidEffectSend *thiz = (IAndroidEffectSend *) self;
    124         interface_lock_shared(thiz);
    125         CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) ?
    126                 (CAudioPlayer *) thiz->mThis : NULL;
    127         if (NULL != ap) {
    128             *pDirectLevel = ap->mDirectLevel;
    129             result = SL_RESULT_SUCCESS;
    130         } else {
    131             SL_LOGE("invalid interface: not attached to an AudioPlayer");
    132             result = SL_RESULT_PARAMETER_INVALID;
    133         }
    134         interface_unlock_shared(thiz);
    135     }
    136 
    137     SL_LEAVE_INTERFACE
    138 }
    139 
    140 
    141 static SLresult IAndroidEffectSend_SetSendLevel(SLAndroidEffectSendItf self,
    142         SLInterfaceID effectImplementationId, SLmillibel sendLevel)
    143 {
    144     SL_ENTER_INTERFACE
    145 
    146     //if (!((SL_MILLIBEL_MIN <= sendLevel) && (sendLevel <= 0))) {
    147     // comparison (SL_MILLIBEL_MIN <= sendLevel) is always true due to range of SLmillibel
    148     if (!(sendLevel <= 0)) {
    149         result = SL_RESULT_PARAMETER_INVALID;
    150     } else {
    151         IAndroidEffectSend *thiz = (IAndroidEffectSend *) self;
    152         interface_lock_exclusive(thiz);
    153         // is SLAndroidEffectSendItf on an AudioPlayer?
    154         CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) ?
    155                  (CAudioPlayer *) thiz->mThis : NULL;
    156         if (NULL == ap) {
    157             SL_LOGE("invalid interface: not attached to an AudioPlayer");
    158             result = SL_RESULT_PARAMETER_INVALID;
    159         } else {
    160             COutputMix *outputMix = CAudioPlayer_GetOutputMix(ap);
    161             if (android_genericFx_hasEffect(&outputMix->mAndroidEffect, effectImplementationId)) {
    162                 // the send level set here is the total energy on the aux bus, so it must take
    163                 // into account the player volume level
    164                 result = android_fxSend_setSendLevel(ap, sendLevel + ap->mVolume.mLevel);
    165             } else {
    166                  SL_LOGE("trying to send to an effect not on this AudioPlayer's OutputMix");
    167                  result = SL_RESULT_PARAMETER_INVALID;
    168             }
    169             if (SL_RESULT_SUCCESS == result) {
    170                 // there currently is support for only one send bus, so there is a single send
    171                 // level
    172                 thiz->mSendLevel = sendLevel;
    173             }
    174         }
    175         interface_unlock_exclusive(thiz);
    176     }
    177 
    178     SL_LEAVE_INTERFACE
    179 }
    180 
    181 
    182 static SLresult IAndroidEffectSend_GetSendLevel(SLAndroidEffectSendItf self,
    183         SLInterfaceID effectImplementationId, SLmillibel *pSendLevel)
    184 {
    185     SL_ENTER_INTERFACE
    186 
    187     if (NULL == pSendLevel) {
    188         result = SL_RESULT_PARAMETER_INVALID;
    189     } else {
    190         IAndroidEffectSend *thiz = (IAndroidEffectSend *) self;
    191         interface_lock_exclusive(thiz);
    192         // is SLAndroidEffectSendItf on an AudioPlayer?
    193         CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) ?
    194                 (CAudioPlayer *) thiz->mThis : NULL;
    195         if (NULL == ap) {
    196             SL_LOGE("invalid interface: not attached to an AudioPlayer");
    197             result = SL_RESULT_PARAMETER_INVALID;
    198         } else {
    199             COutputMix *outputMix = CAudioPlayer_GetOutputMix(ap);
    200             if (android_genericFx_hasEffect(&outputMix->mAndroidEffect, effectImplementationId)) {
    201                 result = SL_RESULT_SUCCESS;
    202             } else {
    203                 SL_LOGE("trying to retrieve send level on an effect not on this AudioPlayer's \
    204 OutputMix");
    205                 result = SL_RESULT_PARAMETER_INVALID;
    206                 }
    207             if (SL_RESULT_SUCCESS == result) {
    208                 // there currently is support for only one send bus, so there is a single send
    209                 // level
    210                 *pSendLevel = thiz->mSendLevel;
    211             }
    212         }
    213         interface_unlock_exclusive(thiz);
    214     }
    215 
    216     SL_LEAVE_INTERFACE
    217 }
    218 
    219 
    220 static const struct SLAndroidEffectSendItf_ IAndroidEffectSend_Itf = {
    221     IAndroidEffectSend_EnableEffectSend,
    222     IAndroidEffectSend_IsEnabled,
    223     IAndroidEffectSend_SetDirectLevel,
    224     IAndroidEffectSend_GetDirectLevel,
    225     IAndroidEffectSend_SetSendLevel,
    226     IAndroidEffectSend_GetSendLevel
    227 };
    228 
    229 void IAndroidEffectSend_init(void *self)
    230 {
    231     IAndroidEffectSend *thiz = (IAndroidEffectSend *) self;
    232     thiz->mItf = &IAndroidEffectSend_Itf;
    233     thiz->mEnabled =  SL_BOOLEAN_FALSE;
    234     thiz->mSendLevel = SL_MILLIBEL_MIN;
    235 }
    236