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