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