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 /* 3DSource implementation */
18 
19 #include "sles_allinclusive.h"
20 
21 
I3DSource_SetHeadRelative(SL3DSourceItf self,SLboolean headRelative)22 static SLresult I3DSource_SetHeadRelative(SL3DSourceItf self, SLboolean headRelative)
23 {
24     SL_ENTER_INTERFACE
25 
26     I3DSource *thiz = (I3DSource *) self;
27     interface_lock_poke(thiz);
28     thiz->mHeadRelative = SL_BOOLEAN_FALSE != headRelative; // normalize
29     interface_unlock_poke(thiz);
30     result = SL_RESULT_SUCCESS;
31 
32     SL_LEAVE_INTERFACE
33 }
34 
35 
I3DSource_GetHeadRelative(SL3DSourceItf self,SLboolean * pHeadRelative)36 static SLresult I3DSource_GetHeadRelative(SL3DSourceItf self, SLboolean *pHeadRelative)
37 {
38     SL_ENTER_INTERFACE
39 
40     if (NULL == pHeadRelative) {
41         result = SL_RESULT_PARAMETER_INVALID;
42     } else {
43         I3DSource *thiz = (I3DSource *) self;
44         interface_lock_peek(thiz);
45         SLboolean headRelative = thiz->mHeadRelative;
46         interface_unlock_peek(thiz);
47         *pHeadRelative = headRelative;
48         result = SL_RESULT_SUCCESS;
49     }
50 
51     SL_LEAVE_INTERFACE
52 }
53 
54 
I3DSource_SetRolloffDistances(SL3DSourceItf self,SLmillimeter minDistance,SLmillimeter maxDistance)55 static SLresult I3DSource_SetRolloffDistances(SL3DSourceItf self,
56     SLmillimeter minDistance, SLmillimeter maxDistance)
57 {
58     SL_ENTER_INTERFACE
59 
60     if (!((0 < minDistance) && (minDistance <= SL_MILLIMETER_MAX) &&
61         (minDistance <= maxDistance) && (maxDistance <= SL_MILLIMETER_MAX))) {
62         result = SL_RESULT_PARAMETER_INVALID;
63     } else {
64         I3DSource *thiz = (I3DSource *) self;
65         interface_lock_exclusive(thiz);
66         thiz->mMinDistance = minDistance;
67         thiz->mMaxDistance = maxDistance;
68         interface_unlock_exclusive(thiz);
69         result = SL_RESULT_SUCCESS;
70     }
71 
72     SL_LEAVE_INTERFACE
73 }
74 
75 
I3DSource_GetRolloffDistances(SL3DSourceItf self,SLmillimeter * pMinDistance,SLmillimeter * pMaxDistance)76 static SLresult I3DSource_GetRolloffDistances(SL3DSourceItf self,
77     SLmillimeter *pMinDistance, SLmillimeter *pMaxDistance)
78 {
79     SL_ENTER_INTERFACE
80 
81     if (NULL == pMinDistance || NULL == pMaxDistance) {
82         result = SL_RESULT_PARAMETER_INVALID;
83     } else {
84         I3DSource *thiz = (I3DSource *) self; interface_lock_shared(thiz);
85         SLmillimeter minDistance = thiz->mMinDistance;
86         SLmillimeter maxDistance = thiz->mMaxDistance;
87         interface_unlock_shared(thiz);
88         *pMinDistance = minDistance;
89         *pMaxDistance = maxDistance;
90         result = SL_RESULT_SUCCESS;
91     }
92 
93     SL_LEAVE_INTERFACE
94 }
95 
96 
I3DSource_SetRolloffMaxDistanceMute(SL3DSourceItf self,SLboolean mute)97 static SLresult I3DSource_SetRolloffMaxDistanceMute(SL3DSourceItf self, SLboolean mute)
98 {
99     SL_ENTER_INTERFACE
100 
101     I3DSource *thiz = (I3DSource *) self;
102     interface_lock_poke(thiz);
103     thiz->mRolloffMaxDistanceMute = SL_BOOLEAN_FALSE != mute; // normalize
104     interface_unlock_poke(thiz);
105     result = SL_RESULT_SUCCESS;
106 
107     SL_LEAVE_INTERFACE
108 }
109 
110 
I3DSource_GetRolloffMaxDistanceMute(SL3DSourceItf self,SLboolean * pMute)111 static SLresult I3DSource_GetRolloffMaxDistanceMute(SL3DSourceItf self, SLboolean *pMute)
112 {
113     SL_ENTER_INTERFACE
114 
115     if (NULL == pMute) {
116         result = SL_RESULT_PARAMETER_INVALID;
117     } else {
118         I3DSource *thiz = (I3DSource *) self;
119         interface_lock_peek(thiz);
120         SLboolean mute = thiz->mRolloffMaxDistanceMute;
121         interface_unlock_peek(thiz);
122         *pMute = mute;
123         result = SL_RESULT_SUCCESS;
124     }
125 
126     SL_LEAVE_INTERFACE
127 }
128 
129 
I3DSource_SetRolloffFactor(SL3DSourceItf self,SLpermille rolloffFactor)130 static SLresult I3DSource_SetRolloffFactor(SL3DSourceItf self, SLpermille rolloffFactor)
131 {
132     SL_ENTER_INTERFACE
133 
134     if (!((0 <= rolloffFactor) && (rolloffFactor <= 10000))) {
135         result = SL_RESULT_PARAMETER_INVALID;
136     } else {
137         I3DSource *thiz = (I3DSource *) self;
138         interface_lock_poke(thiz);
139         thiz->mRolloffFactor = rolloffFactor;
140         interface_unlock_poke(thiz);
141         result = SL_RESULT_SUCCESS;
142     }
143 
144     SL_LEAVE_INTERFACE
145 }
146 
147 
I3DSource_GetRolloffFactor(SL3DSourceItf self,SLpermille * pRolloffFactor)148 static SLresult I3DSource_GetRolloffFactor(SL3DSourceItf self, SLpermille *pRolloffFactor)
149 {
150     SL_ENTER_INTERFACE
151 
152     I3DSource *thiz = (I3DSource *) self;
153     interface_lock_peek(thiz);
154     SLpermille rolloffFactor = thiz->mRolloffFactor;
155     interface_unlock_peek(thiz);
156     *pRolloffFactor = rolloffFactor;
157     result = SL_RESULT_SUCCESS;
158 
159     SL_LEAVE_INTERFACE
160 }
161 
162 
I3DSource_SetRoomRolloffFactor(SL3DSourceItf self,SLpermille roomRolloffFactor)163 static SLresult I3DSource_SetRoomRolloffFactor(SL3DSourceItf self, SLpermille roomRolloffFactor)
164 {
165     SL_ENTER_INTERFACE
166 
167     if (!((0 <= roomRolloffFactor) && (roomRolloffFactor <= 10000))) {
168         result = SL_RESULT_PARAMETER_INVALID;
169     } else {
170         I3DSource *thiz = (I3DSource *) self;
171         interface_lock_poke(thiz);
172         thiz->mRoomRolloffFactor = roomRolloffFactor;
173         interface_unlock_poke(thiz);
174         result = SL_RESULT_SUCCESS;
175     }
176 
177     SL_LEAVE_INTERFACE
178 }
179 
180 
I3DSource_GetRoomRolloffFactor(SL3DSourceItf self,SLpermille * pRoomRolloffFactor)181 static SLresult I3DSource_GetRoomRolloffFactor(SL3DSourceItf self, SLpermille *pRoomRolloffFactor)
182 {
183     SL_ENTER_INTERFACE
184 
185     I3DSource *thiz = (I3DSource *) self;
186     interface_lock_peek(thiz);
187     SLpermille roomRolloffFactor = thiz->mRoomRolloffFactor;
188     interface_unlock_peek(thiz);
189     *pRoomRolloffFactor = roomRolloffFactor;
190     result = SL_RESULT_SUCCESS;
191 
192     SL_LEAVE_INTERFACE
193 }
194 
195 
I3DSource_SetRolloffModel(SL3DSourceItf self,SLuint8 model)196 static SLresult I3DSource_SetRolloffModel(SL3DSourceItf self, SLuint8 model)
197 {
198     SL_ENTER_INTERFACE
199 
200     switch (model) {
201     case SL_ROLLOFFMODEL_LINEAR:
202     case SL_ROLLOFFMODEL_EXPONENTIAL:
203         {
204         I3DSource *thiz = (I3DSource *) self;
205         interface_lock_poke(thiz);
206         thiz->mDistanceModel = model;
207         interface_unlock_poke(thiz);
208         result = SL_RESULT_SUCCESS;
209         }
210         break;
211     default:
212         result = SL_RESULT_PARAMETER_INVALID;
213         break;
214     }
215 
216     SL_LEAVE_INTERFACE
217 }
218 
219 
I3DSource_GetRolloffModel(SL3DSourceItf self,SLuint8 * pModel)220 static SLresult I3DSource_GetRolloffModel(SL3DSourceItf self, SLuint8 *pModel)
221 {
222     SL_ENTER_INTERFACE
223 
224     I3DSource *thiz = (I3DSource *) self;
225     interface_lock_peek(thiz);
226     SLuint8 model = thiz->mDistanceModel;
227     interface_unlock_peek(thiz);
228     *pModel = model;
229     result = SL_RESULT_SUCCESS;
230 
231     SL_LEAVE_INTERFACE
232 }
233 
234 
I3DSource_SetCone(SL3DSourceItf self,SLmillidegree innerAngle,SLmillidegree outerAngle,SLmillibel outerLevel)235 static SLresult I3DSource_SetCone(SL3DSourceItf self, SLmillidegree innerAngle,
236     SLmillidegree outerAngle, SLmillibel outerLevel)
237 {
238     SL_ENTER_INTERFACE
239 
240     if (!((0 <= innerAngle) && (innerAngle <= 360000) &&
241         (0 <= outerAngle) && (outerAngle <= 360000) &&
242         (SL_MILLIBEL_MIN <= outerLevel) && (outerLevel <= 0))) {
243         result = SL_RESULT_PARAMETER_INVALID;
244     } else {
245         I3DSource *thiz = (I3DSource *) self;
246         interface_lock_exclusive(thiz);
247         thiz->mConeInnerAngle = innerAngle;
248         thiz->mConeOuterAngle = outerAngle;
249         thiz->mConeOuterLevel = outerLevel;
250         interface_unlock_exclusive(thiz);
251         result = SL_RESULT_SUCCESS;
252     }
253 
254     SL_LEAVE_INTERFACE
255 }
256 
257 
I3DSource_GetCone(SL3DSourceItf self,SLmillidegree * pInnerAngle,SLmillidegree * pOuterAngle,SLmillibel * pOuterLevel)258 static SLresult I3DSource_GetCone(SL3DSourceItf self, SLmillidegree *pInnerAngle,
259     SLmillidegree *pOuterAngle, SLmillibel *pOuterLevel)
260 {
261     SL_ENTER_INTERFACE
262 
263     if (NULL == pInnerAngle || NULL == pOuterAngle || NULL == pOuterLevel) {
264         result = SL_RESULT_PARAMETER_INVALID;
265     } else {
266         I3DSource *thiz = (I3DSource *) self;
267         interface_lock_shared(thiz);
268         SLmillidegree innerAngle = thiz->mConeInnerAngle;
269         SLmillidegree outerAngle = thiz->mConeOuterAngle;
270         SLmillibel outerLevel = thiz->mConeOuterLevel;
271         interface_unlock_shared(thiz);
272         *pInnerAngle = innerAngle;
273         *pOuterAngle = outerAngle;
274         *pOuterLevel = outerLevel;
275         result = SL_RESULT_SUCCESS;
276     }
277 
278     SL_LEAVE_INTERFACE
279 }
280 
281 
282 static const struct SL3DSourceItf_ I3DSource_Itf = {
283     I3DSource_SetHeadRelative,
284     I3DSource_GetHeadRelative,
285     I3DSource_SetRolloffDistances,
286     I3DSource_GetRolloffDistances,
287     I3DSource_SetRolloffMaxDistanceMute,
288     I3DSource_GetRolloffMaxDistanceMute,
289     I3DSource_SetRolloffFactor,
290     I3DSource_GetRolloffFactor,
291     I3DSource_SetRoomRolloffFactor,
292     I3DSource_GetRoomRolloffFactor,
293     I3DSource_SetRolloffModel,
294     I3DSource_GetRolloffModel,
295     I3DSource_SetCone,
296     I3DSource_GetCone
297 };
298 
I3DSource_init(void * self)299 void I3DSource_init(void *self)
300 {
301     I3DSource *thiz = (I3DSource *) self;
302     thiz->mItf = &I3DSource_Itf;
303     thiz->mHeadRelative = SL_BOOLEAN_FALSE;
304     thiz->mRolloffMaxDistanceMute = SL_BOOLEAN_FALSE;
305     thiz->mMaxDistance = SL_MILLIMETER_MAX;
306     thiz->mMinDistance = 1000;
307     thiz->mConeInnerAngle = 360000;
308     thiz->mConeOuterAngle = 360000;
309     thiz->mConeOuterLevel = 0;
310     thiz->mRolloffFactor = 1000;
311     thiz->mRoomRolloffFactor = 0;
312     thiz->mDistanceModel = SL_ROLLOFFMODEL_EXPONENTIAL;
313 }
314