• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
IAndroidEffectSend_EnableEffectSend(SLAndroidEffectSendItf self,SLInterfaceID effectImplementationId,SLboolean enable,SLmillibel initialLevel)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 
IAndroidEffectSend_IsEnabled(SLAndroidEffectSendItf self,SLInterfaceID effectImplementationId,SLboolean * pEnable)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 
IAndroidEffectSend_SetDirectLevel(SLAndroidEffectSendItf self,SLmillibel directLevel)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 
IAndroidEffectSend_GetDirectLevel(SLAndroidEffectSendItf self,SLmillibel * pDirectLevel)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 
IAndroidEffectSend_SetSendLevel(SLAndroidEffectSendItf self,SLInterfaceID effectImplementationId,SLmillibel sendLevel)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 
IAndroidEffectSend_GetSendLevel(SLAndroidEffectSendItf self,SLInterfaceID effectImplementationId,SLmillibel * pSendLevel)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 
IAndroidEffectSend_init(void * self)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