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 <system/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  */
NO_ENVREVERB(IEnvironmentalReverb * ier)35 static inline bool NO_ENVREVERB(IEnvironmentalReverb* ier) {
36     return (ier->mEnvironmentalReverbEffect == 0);
37 }
38 #endif
39 
40 
IEnvironmentalReverb_SetRoomLevel(SLEnvironmentalReverbItf self,SLmillibel room)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 
IEnvironmentalReverb_GetRoomLevel(SLEnvironmentalReverbItf self,SLmillibel * pRoom)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 
IEnvironmentalReverb_SetRoomHFLevel(SLEnvironmentalReverbItf self,SLmillibel roomHF)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 
IEnvironmentalReverb_GetRoomHFLevel(SLEnvironmentalReverbItf self,SLmillibel * pRoomHF)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 
IEnvironmentalReverb_SetDecayTime(SLEnvironmentalReverbItf self,SLmillisecond decayTime)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 
IEnvironmentalReverb_GetDecayTime(SLEnvironmentalReverbItf self,SLmillisecond * pDecayTime)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 
IEnvironmentalReverb_SetDecayHFRatio(SLEnvironmentalReverbItf self,SLpermille decayHFRatio)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 
IEnvironmentalReverb_GetDecayHFRatio(SLEnvironmentalReverbItf self,SLpermille * pDecayHFRatio)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 
IEnvironmentalReverb_SetReflectionsLevel(SLEnvironmentalReverbItf self,SLmillibel reflectionsLevel)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 
IEnvironmentalReverb_GetReflectionsLevel(SLEnvironmentalReverbItf self,SLmillibel * pReflectionsLevel)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 
IEnvironmentalReverb_SetReflectionsDelay(SLEnvironmentalReverbItf self,SLmillisecond reflectionsDelay)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 
IEnvironmentalReverb_GetReflectionsDelay(SLEnvironmentalReverbItf self,SLmillisecond * pReflectionsDelay)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 
IEnvironmentalReverb_SetReverbLevel(SLEnvironmentalReverbItf self,SLmillibel reverbLevel)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 
IEnvironmentalReverb_GetReverbLevel(SLEnvironmentalReverbItf self,SLmillibel * pReverbLevel)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 
IEnvironmentalReverb_SetReverbDelay(SLEnvironmentalReverbItf self,SLmillisecond reverbDelay)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 
IEnvironmentalReverb_GetReverbDelay(SLEnvironmentalReverbItf self,SLmillisecond * pReverbDelay)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 
IEnvironmentalReverb_SetDiffusion(SLEnvironmentalReverbItf self,SLpermille diffusion)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 
IEnvironmentalReverb_GetDiffusion(SLEnvironmentalReverbItf self,SLpermille * pDiffusion)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 
IEnvironmentalReverb_SetDensity(SLEnvironmentalReverbItf self,SLpermille density)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 
IEnvironmentalReverb_GetDensity(SLEnvironmentalReverbItf self,SLpermille * pDensity)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 
IEnvironmentalReverb_SetEnvironmentalReverbProperties(SLEnvironmentalReverbItf self,const SLEnvironmentalReverbSettings * pProperties)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 
IEnvironmentalReverb_GetEnvironmentalReverbProperties(SLEnvironmentalReverbItf self,SLEnvironmentalReverbSettings * pProperties)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 
IEnvironmentalReverb_init(void * self)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 
IEnvironmentalReverb_deinit(void * self)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 
IEnvironmentalReverb_Expose(void * self)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