xref: /aosp_15_r20/frameworks/wilhelm/src/itf/IEqualizer.cpp (revision bebae9c0e76121f8312ccb50385c080b3a0b023c)
1*bebae9c0SAndroid Build Coastguard Worker /*
2*bebae9c0SAndroid Build Coastguard Worker  * Copyright (C) 2010 The Android Open Source Project
3*bebae9c0SAndroid Build Coastguard Worker  *
4*bebae9c0SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*bebae9c0SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*bebae9c0SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*bebae9c0SAndroid Build Coastguard Worker  *
8*bebae9c0SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*bebae9c0SAndroid Build Coastguard Worker  *
10*bebae9c0SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*bebae9c0SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*bebae9c0SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*bebae9c0SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*bebae9c0SAndroid Build Coastguard Worker  * limitations under the License.
15*bebae9c0SAndroid Build Coastguard Worker  */
16*bebae9c0SAndroid Build Coastguard Worker 
17*bebae9c0SAndroid Build Coastguard Worker /* Equalizer implementation */
18*bebae9c0SAndroid Build Coastguard Worker 
19*bebae9c0SAndroid Build Coastguard Worker #include "sles_allinclusive.h"
20*bebae9c0SAndroid Build Coastguard Worker #ifdef ANDROID
21*bebae9c0SAndroid Build Coastguard Worker #include <system/audio_effects/effect_equalizer.h>
22*bebae9c0SAndroid Build Coastguard Worker #endif
23*bebae9c0SAndroid Build Coastguard Worker 
24*bebae9c0SAndroid Build Coastguard Worker #define MAX_EQ_PRESETS 3
25*bebae9c0SAndroid Build Coastguard Worker 
26*bebae9c0SAndroid Build Coastguard Worker #if !defined(ANDROID)
27*bebae9c0SAndroid Build Coastguard Worker static const struct EqualizerBand EqualizerBands[MAX_EQ_BANDS] = {
28*bebae9c0SAndroid Build Coastguard Worker     {1000, 1500, 2000},
29*bebae9c0SAndroid Build Coastguard Worker     {2000, 3000, 4000},
30*bebae9c0SAndroid Build Coastguard Worker     {4000, 5500, 7000},
31*bebae9c0SAndroid Build Coastguard Worker     {7000, 8000, 9000}
32*bebae9c0SAndroid Build Coastguard Worker };
33*bebae9c0SAndroid Build Coastguard Worker 
34*bebae9c0SAndroid Build Coastguard Worker static const struct EqualizerPreset {
35*bebae9c0SAndroid Build Coastguard Worker     const char *mName;
36*bebae9c0SAndroid Build Coastguard Worker     SLmillibel mLevels[MAX_EQ_BANDS];
37*bebae9c0SAndroid Build Coastguard Worker } EqualizerPresets[MAX_EQ_PRESETS] = {
38*bebae9c0SAndroid Build Coastguard Worker     {"Default", {0, 0, 0, 0}},
39*bebae9c0SAndroid Build Coastguard Worker     {"Bass", {500, 200, 100, 0}},
40*bebae9c0SAndroid Build Coastguard Worker     {"Treble", {0, 100, 200, 500}}
41*bebae9c0SAndroid Build Coastguard Worker };
42*bebae9c0SAndroid Build Coastguard Worker #endif
43*bebae9c0SAndroid Build Coastguard Worker 
44*bebae9c0SAndroid Build Coastguard Worker 
45*bebae9c0SAndroid Build Coastguard Worker #if defined(ANDROID)
46*bebae9c0SAndroid Build Coastguard Worker /**
47*bebae9c0SAndroid Build Coastguard Worker  * returns true if this interface is not associated with an initialized Equalizer effect
48*bebae9c0SAndroid Build Coastguard Worker  */
NO_EQ(IEqualizer * v)49*bebae9c0SAndroid Build Coastguard Worker static inline bool NO_EQ(IEqualizer* v) {
50*bebae9c0SAndroid Build Coastguard Worker     return (v->mEqEffect == 0);
51*bebae9c0SAndroid Build Coastguard Worker }
52*bebae9c0SAndroid Build Coastguard Worker #endif
53*bebae9c0SAndroid Build Coastguard Worker 
54*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_SetEnabled(SLEqualizerItf self,SLboolean enabled)55*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_SetEnabled(SLEqualizerItf self, SLboolean enabled)
56*bebae9c0SAndroid Build Coastguard Worker {
57*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
58*bebae9c0SAndroid Build Coastguard Worker 
59*bebae9c0SAndroid Build Coastguard Worker     IEqualizer *thiz = (IEqualizer *) self;
60*bebae9c0SAndroid Build Coastguard Worker     interface_lock_exclusive(thiz);
61*bebae9c0SAndroid Build Coastguard Worker     thiz->mEnabled = (SLboolean) enabled;
62*bebae9c0SAndroid Build Coastguard Worker #if !defined(ANDROID)
63*bebae9c0SAndroid Build Coastguard Worker     result = SL_RESULT_SUCCESS;
64*bebae9c0SAndroid Build Coastguard Worker #else
65*bebae9c0SAndroid Build Coastguard Worker     if (NO_EQ(thiz)) {
66*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_CONTROL_LOST;
67*bebae9c0SAndroid Build Coastguard Worker     } else {
68*bebae9c0SAndroid Build Coastguard Worker         android::status_t status =
69*bebae9c0SAndroid Build Coastguard Worker                 thiz->mEqEffect->setEnabled((bool) thiz->mEnabled);
70*bebae9c0SAndroid Build Coastguard Worker         result = android_fx_statusToResult(status);
71*bebae9c0SAndroid Build Coastguard Worker     }
72*bebae9c0SAndroid Build Coastguard Worker #endif
73*bebae9c0SAndroid Build Coastguard Worker     interface_unlock_exclusive(thiz);
74*bebae9c0SAndroid Build Coastguard Worker 
75*bebae9c0SAndroid Build Coastguard Worker     SL_LEAVE_INTERFACE
76*bebae9c0SAndroid Build Coastguard Worker }
77*bebae9c0SAndroid Build Coastguard Worker 
78*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_IsEnabled(SLEqualizerItf self,SLboolean * pEnabled)79*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_IsEnabled(SLEqualizerItf self, SLboolean *pEnabled)
80*bebae9c0SAndroid Build Coastguard Worker {
81*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
82*bebae9c0SAndroid Build Coastguard Worker 
83*bebae9c0SAndroid Build Coastguard Worker     if (NULL == pEnabled) {
84*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_PARAMETER_INVALID;
85*bebae9c0SAndroid Build Coastguard Worker     } else {
86*bebae9c0SAndroid Build Coastguard Worker         IEqualizer *thiz = (IEqualizer *) self;
87*bebae9c0SAndroid Build Coastguard Worker         interface_lock_exclusive(thiz);
88*bebae9c0SAndroid Build Coastguard Worker  #if !defined(ANDROID)
89*bebae9c0SAndroid Build Coastguard Worker         SLboolean enabled = thiz->mEnabled;
90*bebae9c0SAndroid Build Coastguard Worker         *pEnabled = enabled;
91*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_SUCCESS;
92*bebae9c0SAndroid Build Coastguard Worker  #else
93*bebae9c0SAndroid Build Coastguard Worker         if (NO_EQ(thiz)) {
94*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_CONTROL_LOST;
95*bebae9c0SAndroid Build Coastguard Worker         } else {
96*bebae9c0SAndroid Build Coastguard Worker             *pEnabled = (SLboolean) thiz->mEqEffect->getEnabled();
97*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_SUCCESS;
98*bebae9c0SAndroid Build Coastguard Worker         }
99*bebae9c0SAndroid Build Coastguard Worker  #endif
100*bebae9c0SAndroid Build Coastguard Worker         interface_unlock_exclusive(thiz);
101*bebae9c0SAndroid Build Coastguard Worker     }
102*bebae9c0SAndroid Build Coastguard Worker 
103*bebae9c0SAndroid Build Coastguard Worker       SL_LEAVE_INTERFACE
104*bebae9c0SAndroid Build Coastguard Worker }
105*bebae9c0SAndroid Build Coastguard Worker 
106*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_GetNumberOfBands(SLEqualizerItf self,SLuint16 * pNumBands)107*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_GetNumberOfBands(SLEqualizerItf self, SLuint16 *pNumBands)
108*bebae9c0SAndroid Build Coastguard Worker {
109*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
110*bebae9c0SAndroid Build Coastguard Worker 
111*bebae9c0SAndroid Build Coastguard Worker     if (NULL == pNumBands) {
112*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_PARAMETER_INVALID;
113*bebae9c0SAndroid Build Coastguard Worker     } else {
114*bebae9c0SAndroid Build Coastguard Worker         IEqualizer *thiz = (IEqualizer *) self;
115*bebae9c0SAndroid Build Coastguard Worker         // Note: no lock, but OK because it is const
116*bebae9c0SAndroid Build Coastguard Worker         *pNumBands = thiz->mNumBands;
117*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_SUCCESS;
118*bebae9c0SAndroid Build Coastguard Worker     }
119*bebae9c0SAndroid Build Coastguard Worker 
120*bebae9c0SAndroid Build Coastguard Worker     SL_LEAVE_INTERFACE
121*bebae9c0SAndroid Build Coastguard Worker }
122*bebae9c0SAndroid Build Coastguard Worker 
123*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_GetBandLevelRange(SLEqualizerItf self,SLmillibel * pMin,SLmillibel * pMax)124*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_GetBandLevelRange(SLEqualizerItf self, SLmillibel *pMin,
125*bebae9c0SAndroid Build Coastguard Worker     SLmillibel *pMax)
126*bebae9c0SAndroid Build Coastguard Worker {
127*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
128*bebae9c0SAndroid Build Coastguard Worker 
129*bebae9c0SAndroid Build Coastguard Worker     if (NULL == pMin && NULL == pMax) {
130*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_PARAMETER_INVALID;
131*bebae9c0SAndroid Build Coastguard Worker     } else {
132*bebae9c0SAndroid Build Coastguard Worker         IEqualizer *thiz = (IEqualizer *) self;
133*bebae9c0SAndroid Build Coastguard Worker         // Note: no lock, but OK because it is const
134*bebae9c0SAndroid Build Coastguard Worker         if (NULL != pMin)
135*bebae9c0SAndroid Build Coastguard Worker             *pMin = thiz->mBandLevelRangeMin;
136*bebae9c0SAndroid Build Coastguard Worker         if (NULL != pMax)
137*bebae9c0SAndroid Build Coastguard Worker             *pMax = thiz->mBandLevelRangeMax;
138*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_SUCCESS;
139*bebae9c0SAndroid Build Coastguard Worker     }
140*bebae9c0SAndroid Build Coastguard Worker 
141*bebae9c0SAndroid Build Coastguard Worker     SL_LEAVE_INTERFACE
142*bebae9c0SAndroid Build Coastguard Worker }
143*bebae9c0SAndroid Build Coastguard Worker 
144*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_SetBandLevel(SLEqualizerItf self,SLuint16 band,SLmillibel level)145*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_SetBandLevel(SLEqualizerItf self, SLuint16 band, SLmillibel level)
146*bebae9c0SAndroid Build Coastguard Worker {
147*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
148*bebae9c0SAndroid Build Coastguard Worker 
149*bebae9c0SAndroid Build Coastguard Worker     IEqualizer *thiz = (IEqualizer *) self;
150*bebae9c0SAndroid Build Coastguard Worker     if (!(thiz->mBandLevelRangeMin <= level && level <= thiz->mBandLevelRangeMax) ||
151*bebae9c0SAndroid Build Coastguard Worker             (band >= thiz->mNumBands)) {
152*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_PARAMETER_INVALID;
153*bebae9c0SAndroid Build Coastguard Worker     } else {
154*bebae9c0SAndroid Build Coastguard Worker         interface_lock_exclusive(thiz);
155*bebae9c0SAndroid Build Coastguard Worker #if !defined(ANDROID)
156*bebae9c0SAndroid Build Coastguard Worker         thiz->mLevels[band] = level;
157*bebae9c0SAndroid Build Coastguard Worker         thiz->mPreset = SL_EQUALIZER_UNDEFINED;
158*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_SUCCESS;
159*bebae9c0SAndroid Build Coastguard Worker #else
160*bebae9c0SAndroid Build Coastguard Worker         if (NO_EQ(thiz)) {
161*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_CONTROL_LOST;
162*bebae9c0SAndroid Build Coastguard Worker         } else {
163*bebae9c0SAndroid Build Coastguard Worker             android::status_t status =
164*bebae9c0SAndroid Build Coastguard Worker                 android_eq_setParam(thiz->mEqEffect, EQ_PARAM_BAND_LEVEL, band, &level);
165*bebae9c0SAndroid Build Coastguard Worker             result = android_fx_statusToResult(status);
166*bebae9c0SAndroid Build Coastguard Worker         }
167*bebae9c0SAndroid Build Coastguard Worker #endif
168*bebae9c0SAndroid Build Coastguard Worker         interface_unlock_exclusive(thiz);
169*bebae9c0SAndroid Build Coastguard Worker     }
170*bebae9c0SAndroid Build Coastguard Worker 
171*bebae9c0SAndroid Build Coastguard Worker     SL_LEAVE_INTERFACE
172*bebae9c0SAndroid Build Coastguard Worker }
173*bebae9c0SAndroid Build Coastguard Worker 
174*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_GetBandLevel(SLEqualizerItf self,SLuint16 band,SLmillibel * pLevel)175*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_GetBandLevel(SLEqualizerItf self, SLuint16 band, SLmillibel *pLevel)
176*bebae9c0SAndroid Build Coastguard Worker {
177*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
178*bebae9c0SAndroid Build Coastguard Worker 
179*bebae9c0SAndroid Build Coastguard Worker     if (NULL == pLevel) {
180*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_PARAMETER_INVALID;
181*bebae9c0SAndroid Build Coastguard Worker     } else {
182*bebae9c0SAndroid Build Coastguard Worker         IEqualizer *thiz = (IEqualizer *) self;
183*bebae9c0SAndroid Build Coastguard Worker         // const, no lock needed
184*bebae9c0SAndroid Build Coastguard Worker         if (band >= thiz->mNumBands) {
185*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_PARAMETER_INVALID;
186*bebae9c0SAndroid Build Coastguard Worker         } else {
187*bebae9c0SAndroid Build Coastguard Worker             SLmillibel level = 0;
188*bebae9c0SAndroid Build Coastguard Worker             interface_lock_shared(thiz);
189*bebae9c0SAndroid Build Coastguard Worker #if !defined(ANDROID)
190*bebae9c0SAndroid Build Coastguard Worker             level = thiz->mLevels[band];
191*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_SUCCESS;
192*bebae9c0SAndroid Build Coastguard Worker #else
193*bebae9c0SAndroid Build Coastguard Worker             if (NO_EQ(thiz)) {
194*bebae9c0SAndroid Build Coastguard Worker                 result = SL_RESULT_CONTROL_LOST;
195*bebae9c0SAndroid Build Coastguard Worker             } else {
196*bebae9c0SAndroid Build Coastguard Worker                 android::status_t status =
197*bebae9c0SAndroid Build Coastguard Worker                     android_eq_getParam(thiz->mEqEffect, EQ_PARAM_BAND_LEVEL, band, &level);
198*bebae9c0SAndroid Build Coastguard Worker                 result = android_fx_statusToResult(status);
199*bebae9c0SAndroid Build Coastguard Worker             }
200*bebae9c0SAndroid Build Coastguard Worker #endif
201*bebae9c0SAndroid Build Coastguard Worker             interface_unlock_shared(thiz);
202*bebae9c0SAndroid Build Coastguard Worker             *pLevel = level;
203*bebae9c0SAndroid Build Coastguard Worker         }
204*bebae9c0SAndroid Build Coastguard Worker     }
205*bebae9c0SAndroid Build Coastguard Worker 
206*bebae9c0SAndroid Build Coastguard Worker     SL_LEAVE_INTERFACE
207*bebae9c0SAndroid Build Coastguard Worker }
208*bebae9c0SAndroid Build Coastguard Worker 
209*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_GetCenterFreq(SLEqualizerItf self,SLuint16 band,SLmilliHertz * pCenter)210*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_GetCenterFreq(SLEqualizerItf self, SLuint16 band, SLmilliHertz *pCenter)
211*bebae9c0SAndroid Build Coastguard Worker {
212*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
213*bebae9c0SAndroid Build Coastguard Worker 
214*bebae9c0SAndroid Build Coastguard Worker     if (NULL == pCenter) {
215*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_PARAMETER_INVALID;
216*bebae9c0SAndroid Build Coastguard Worker     } else {
217*bebae9c0SAndroid Build Coastguard Worker         IEqualizer *thiz = (IEqualizer *) self;
218*bebae9c0SAndroid Build Coastguard Worker         if (band >= thiz->mNumBands) {
219*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_PARAMETER_INVALID;
220*bebae9c0SAndroid Build Coastguard Worker         } else {
221*bebae9c0SAndroid Build Coastguard Worker #if !defined(ANDROID)
222*bebae9c0SAndroid Build Coastguard Worker             // Note: no lock, but OK because it is const
223*bebae9c0SAndroid Build Coastguard Worker             *pCenter = thiz->mBands[band].mCenter;
224*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_SUCCESS;
225*bebae9c0SAndroid Build Coastguard Worker #else
226*bebae9c0SAndroid Build Coastguard Worker             SLmilliHertz center = 0;
227*bebae9c0SAndroid Build Coastguard Worker             interface_lock_shared(thiz);
228*bebae9c0SAndroid Build Coastguard Worker             if (NO_EQ(thiz)) {
229*bebae9c0SAndroid Build Coastguard Worker                 result = SL_RESULT_CONTROL_LOST;
230*bebae9c0SAndroid Build Coastguard Worker             } else {
231*bebae9c0SAndroid Build Coastguard Worker                 android::status_t status =
232*bebae9c0SAndroid Build Coastguard Worker                     android_eq_getParam(thiz->mEqEffect, EQ_PARAM_CENTER_FREQ, band, &center);
233*bebae9c0SAndroid Build Coastguard Worker                 result = android_fx_statusToResult(status);
234*bebae9c0SAndroid Build Coastguard Worker             }
235*bebae9c0SAndroid Build Coastguard Worker             interface_unlock_shared(thiz);
236*bebae9c0SAndroid Build Coastguard Worker             *pCenter = center;
237*bebae9c0SAndroid Build Coastguard Worker #endif
238*bebae9c0SAndroid Build Coastguard Worker         }
239*bebae9c0SAndroid Build Coastguard Worker     }
240*bebae9c0SAndroid Build Coastguard Worker 
241*bebae9c0SAndroid Build Coastguard Worker     SL_LEAVE_INTERFACE
242*bebae9c0SAndroid Build Coastguard Worker }
243*bebae9c0SAndroid Build Coastguard Worker 
244*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_GetBandFreqRange(SLEqualizerItf self,SLuint16 band,SLmilliHertz * pMin,SLmilliHertz * pMax)245*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_GetBandFreqRange(SLEqualizerItf self, SLuint16 band,
246*bebae9c0SAndroid Build Coastguard Worker     SLmilliHertz *pMin, SLmilliHertz *pMax)
247*bebae9c0SAndroid Build Coastguard Worker {
248*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
249*bebae9c0SAndroid Build Coastguard Worker 
250*bebae9c0SAndroid Build Coastguard Worker     if (NULL == pMin && NULL == pMax) {
251*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_PARAMETER_INVALID;
252*bebae9c0SAndroid Build Coastguard Worker     } else {
253*bebae9c0SAndroid Build Coastguard Worker         IEqualizer *thiz = (IEqualizer *) self;
254*bebae9c0SAndroid Build Coastguard Worker         if (band >= thiz->mNumBands) {
255*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_PARAMETER_INVALID;
256*bebae9c0SAndroid Build Coastguard Worker         } else {
257*bebae9c0SAndroid Build Coastguard Worker #if !defined(ANDROID)
258*bebae9c0SAndroid Build Coastguard Worker             // Note: no lock, but OK because it is const
259*bebae9c0SAndroid Build Coastguard Worker             if (NULL != pMin)
260*bebae9c0SAndroid Build Coastguard Worker                 *pMin = thiz->mBands[band].mMin;
261*bebae9c0SAndroid Build Coastguard Worker             if (NULL != pMax)
262*bebae9c0SAndroid Build Coastguard Worker                 *pMax = thiz->mBands[band].mMax;
263*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_SUCCESS;
264*bebae9c0SAndroid Build Coastguard Worker #else
265*bebae9c0SAndroid Build Coastguard Worker             SLmilliHertz range[2] = {0, 0}; // SLmilliHertz is SLuint32
266*bebae9c0SAndroid Build Coastguard Worker             interface_lock_shared(thiz);
267*bebae9c0SAndroid Build Coastguard Worker             if (NO_EQ(thiz)) {
268*bebae9c0SAndroid Build Coastguard Worker                 result = SL_RESULT_CONTROL_LOST;
269*bebae9c0SAndroid Build Coastguard Worker             } else {
270*bebae9c0SAndroid Build Coastguard Worker                 android::status_t status =
271*bebae9c0SAndroid Build Coastguard Worker                     android_eq_getParam(thiz->mEqEffect, EQ_PARAM_BAND_FREQ_RANGE, band, range);
272*bebae9c0SAndroid Build Coastguard Worker                 result = android_fx_statusToResult(status);
273*bebae9c0SAndroid Build Coastguard Worker             }
274*bebae9c0SAndroid Build Coastguard Worker             interface_unlock_shared(thiz);
275*bebae9c0SAndroid Build Coastguard Worker             if (NULL != pMin) {
276*bebae9c0SAndroid Build Coastguard Worker                 *pMin = range[0];
277*bebae9c0SAndroid Build Coastguard Worker             }
278*bebae9c0SAndroid Build Coastguard Worker             if (NULL != pMax) {
279*bebae9c0SAndroid Build Coastguard Worker                 *pMax = range[1];
280*bebae9c0SAndroid Build Coastguard Worker             }
281*bebae9c0SAndroid Build Coastguard Worker #endif
282*bebae9c0SAndroid Build Coastguard Worker         }
283*bebae9c0SAndroid Build Coastguard Worker     }
284*bebae9c0SAndroid Build Coastguard Worker 
285*bebae9c0SAndroid Build Coastguard Worker     SL_LEAVE_INTERFACE
286*bebae9c0SAndroid Build Coastguard Worker }
287*bebae9c0SAndroid Build Coastguard Worker 
288*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_GetBand(SLEqualizerItf self,SLmilliHertz frequency,SLuint16 * pBand)289*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_GetBand(SLEqualizerItf self, SLmilliHertz frequency, SLuint16 *pBand)
290*bebae9c0SAndroid Build Coastguard Worker {
291*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
292*bebae9c0SAndroid Build Coastguard Worker 
293*bebae9c0SAndroid Build Coastguard Worker     if (NULL == pBand) {
294*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_PARAMETER_INVALID;
295*bebae9c0SAndroid Build Coastguard Worker     } else {
296*bebae9c0SAndroid Build Coastguard Worker         IEqualizer *thiz = (IEqualizer *) self;
297*bebae9c0SAndroid Build Coastguard Worker #if !defined(ANDROID)
298*bebae9c0SAndroid Build Coastguard Worker         // search for band whose center frequency has the closest ratio to 1.0
299*bebae9c0SAndroid Build Coastguard Worker         // assumes bands are unsorted (a pessimistic assumption)
300*bebae9c0SAndroid Build Coastguard Worker         // assumes bands can overlap (a pessimistic assumption)
301*bebae9c0SAndroid Build Coastguard Worker         // assumes a small number of bands, so no need for a fancier algorithm
302*bebae9c0SAndroid Build Coastguard Worker         const struct EqualizerBand *band;
303*bebae9c0SAndroid Build Coastguard Worker         float floatFreq = (float) frequency;
304*bebae9c0SAndroid Build Coastguard Worker         float bestRatio = 0.0;
305*bebae9c0SAndroid Build Coastguard Worker         SLuint16 bestBand = SL_EQUALIZER_UNDEFINED;
306*bebae9c0SAndroid Build Coastguard Worker         for (band = thiz->mBands; band < &thiz->mBands[thiz->mNumBands]; ++band) {
307*bebae9c0SAndroid Build Coastguard Worker             if (!(band->mMin <= frequency && frequency <= band->mMax))
308*bebae9c0SAndroid Build Coastguard Worker                 continue;
309*bebae9c0SAndroid Build Coastguard Worker             assert(band->mMin <= band->mCenter && band->mCenter <= band->mMax);
310*bebae9c0SAndroid Build Coastguard Worker             assert(band->mCenter != 0);
311*bebae9c0SAndroid Build Coastguard Worker             float ratio = frequency <= band->mCenter ?
312*bebae9c0SAndroid Build Coastguard Worker                 floatFreq / band->mCenter : band->mCenter / floatFreq;
313*bebae9c0SAndroid Build Coastguard Worker             if (ratio > bestRatio) {
314*bebae9c0SAndroid Build Coastguard Worker                 bestRatio = ratio;
315*bebae9c0SAndroid Build Coastguard Worker                 bestBand = band - thiz->mBands;
316*bebae9c0SAndroid Build Coastguard Worker             }
317*bebae9c0SAndroid Build Coastguard Worker         }
318*bebae9c0SAndroid Build Coastguard Worker         *pBand = bestBand;
319*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_SUCCESS;
320*bebae9c0SAndroid Build Coastguard Worker #else
321*bebae9c0SAndroid Build Coastguard Worker         uint16_t band = 0;
322*bebae9c0SAndroid Build Coastguard Worker         interface_lock_shared(thiz);
323*bebae9c0SAndroid Build Coastguard Worker         if (NO_EQ(thiz)) {
324*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_CONTROL_LOST;
325*bebae9c0SAndroid Build Coastguard Worker         } else {
326*bebae9c0SAndroid Build Coastguard Worker             android::status_t status =
327*bebae9c0SAndroid Build Coastguard Worker                 android_eq_getParam(thiz->mEqEffect, EQ_PARAM_GET_BAND, frequency, &band);
328*bebae9c0SAndroid Build Coastguard Worker             result = android_fx_statusToResult(status);
329*bebae9c0SAndroid Build Coastguard Worker         }
330*bebae9c0SAndroid Build Coastguard Worker         interface_unlock_shared(thiz);
331*bebae9c0SAndroid Build Coastguard Worker         *pBand = (SLuint16)band;
332*bebae9c0SAndroid Build Coastguard Worker #endif
333*bebae9c0SAndroid Build Coastguard Worker     }
334*bebae9c0SAndroid Build Coastguard Worker 
335*bebae9c0SAndroid Build Coastguard Worker     SL_LEAVE_INTERFACE
336*bebae9c0SAndroid Build Coastguard Worker }
337*bebae9c0SAndroid Build Coastguard Worker 
338*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_GetCurrentPreset(SLEqualizerItf self,SLuint16 * pPreset)339*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_GetCurrentPreset(SLEqualizerItf self, SLuint16 *pPreset)
340*bebae9c0SAndroid Build Coastguard Worker {
341*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
342*bebae9c0SAndroid Build Coastguard Worker 
343*bebae9c0SAndroid Build Coastguard Worker     if (NULL == pPreset) {
344*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_PARAMETER_INVALID;
345*bebae9c0SAndroid Build Coastguard Worker     } else {
346*bebae9c0SAndroid Build Coastguard Worker         IEqualizer *thiz = (IEqualizer *) self;
347*bebae9c0SAndroid Build Coastguard Worker         interface_lock_shared(thiz);
348*bebae9c0SAndroid Build Coastguard Worker #if !defined(ANDROID)
349*bebae9c0SAndroid Build Coastguard Worker         SLuint16 preset = thiz->mPreset;
350*bebae9c0SAndroid Build Coastguard Worker         interface_unlock_shared(thiz);
351*bebae9c0SAndroid Build Coastguard Worker         *pPreset = preset;
352*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_SUCCESS;
353*bebae9c0SAndroid Build Coastguard Worker #else
354*bebae9c0SAndroid Build Coastguard Worker         uint16_t preset = 0;
355*bebae9c0SAndroid Build Coastguard Worker         if (NO_EQ(thiz)) {
356*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_CONTROL_LOST;
357*bebae9c0SAndroid Build Coastguard Worker         } else {
358*bebae9c0SAndroid Build Coastguard Worker             android::status_t status =
359*bebae9c0SAndroid Build Coastguard Worker                     android_eq_getParam(thiz->mEqEffect, EQ_PARAM_CUR_PRESET, 0, &preset);
360*bebae9c0SAndroid Build Coastguard Worker             result = android_fx_statusToResult(status);
361*bebae9c0SAndroid Build Coastguard Worker         }
362*bebae9c0SAndroid Build Coastguard Worker         interface_unlock_shared(thiz);
363*bebae9c0SAndroid Build Coastguard Worker 
364*bebae9c0SAndroid Build Coastguard Worker         *pPreset = (SLuint16) preset;
365*bebae9c0SAndroid Build Coastguard Worker #endif
366*bebae9c0SAndroid Build Coastguard Worker 
367*bebae9c0SAndroid Build Coastguard Worker     }
368*bebae9c0SAndroid Build Coastguard Worker 
369*bebae9c0SAndroid Build Coastguard Worker     SL_LEAVE_INTERFACE
370*bebae9c0SAndroid Build Coastguard Worker }
371*bebae9c0SAndroid Build Coastguard Worker 
372*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_UsePreset(SLEqualizerItf self,SLuint16 index)373*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_UsePreset(SLEqualizerItf self, SLuint16 index)
374*bebae9c0SAndroid Build Coastguard Worker {
375*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
376*bebae9c0SAndroid Build Coastguard Worker     SL_LOGV("Equalizer::UsePreset index=%u", index);
377*bebae9c0SAndroid Build Coastguard Worker 
378*bebae9c0SAndroid Build Coastguard Worker     IEqualizer *thiz = (IEqualizer *) self;
379*bebae9c0SAndroid Build Coastguard Worker     if (index >= thiz->mNumPresets) {
380*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_PARAMETER_INVALID;
381*bebae9c0SAndroid Build Coastguard Worker     } else {
382*bebae9c0SAndroid Build Coastguard Worker         interface_lock_exclusive(thiz);
383*bebae9c0SAndroid Build Coastguard Worker #if !defined(ANDROID)
384*bebae9c0SAndroid Build Coastguard Worker         SLuint16 band;
385*bebae9c0SAndroid Build Coastguard Worker         for (band = 0; band < thiz->mNumBands; ++band)
386*bebae9c0SAndroid Build Coastguard Worker             thiz->mLevels[band] = EqualizerPresets[index].mLevels[band];
387*bebae9c0SAndroid Build Coastguard Worker         thiz->mPreset = index;
388*bebae9c0SAndroid Build Coastguard Worker         interface_unlock_exclusive(thiz);
389*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_SUCCESS;
390*bebae9c0SAndroid Build Coastguard Worker #else
391*bebae9c0SAndroid Build Coastguard Worker         if (NO_EQ(thiz)) {
392*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_CONTROL_LOST;
393*bebae9c0SAndroid Build Coastguard Worker         } else {
394*bebae9c0SAndroid Build Coastguard Worker             android::status_t status =
395*bebae9c0SAndroid Build Coastguard Worker                 android_eq_setParam(thiz->mEqEffect, EQ_PARAM_CUR_PRESET, 0, &index);
396*bebae9c0SAndroid Build Coastguard Worker             result = android_fx_statusToResult(status);
397*bebae9c0SAndroid Build Coastguard Worker         }
398*bebae9c0SAndroid Build Coastguard Worker         interface_unlock_shared(thiz);
399*bebae9c0SAndroid Build Coastguard Worker #endif
400*bebae9c0SAndroid Build Coastguard Worker     }
401*bebae9c0SAndroid Build Coastguard Worker 
402*bebae9c0SAndroid Build Coastguard Worker     SL_LEAVE_INTERFACE
403*bebae9c0SAndroid Build Coastguard Worker }
404*bebae9c0SAndroid Build Coastguard Worker 
405*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_GetNumberOfPresets(SLEqualizerItf self,SLuint16 * pNumPresets)406*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_GetNumberOfPresets(SLEqualizerItf self, SLuint16 *pNumPresets)
407*bebae9c0SAndroid Build Coastguard Worker {
408*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
409*bebae9c0SAndroid Build Coastguard Worker 
410*bebae9c0SAndroid Build Coastguard Worker     if (NULL == pNumPresets) {
411*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_PARAMETER_INVALID;
412*bebae9c0SAndroid Build Coastguard Worker     } else {
413*bebae9c0SAndroid Build Coastguard Worker         IEqualizer *thiz = (IEqualizer *) self;
414*bebae9c0SAndroid Build Coastguard Worker         // Note: no lock, but OK because it is const
415*bebae9c0SAndroid Build Coastguard Worker         *pNumPresets = thiz->mNumPresets;
416*bebae9c0SAndroid Build Coastguard Worker 
417*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_SUCCESS;
418*bebae9c0SAndroid Build Coastguard Worker     }
419*bebae9c0SAndroid Build Coastguard Worker 
420*bebae9c0SAndroid Build Coastguard Worker     SL_LEAVE_INTERFACE
421*bebae9c0SAndroid Build Coastguard Worker }
422*bebae9c0SAndroid Build Coastguard Worker 
423*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_GetPresetName(SLEqualizerItf self,SLuint16 index,const SLchar ** ppName)424*bebae9c0SAndroid Build Coastguard Worker static SLresult IEqualizer_GetPresetName(SLEqualizerItf self, SLuint16 index, const SLchar **ppName)
425*bebae9c0SAndroid Build Coastguard Worker {
426*bebae9c0SAndroid Build Coastguard Worker     SL_ENTER_INTERFACE
427*bebae9c0SAndroid Build Coastguard Worker 
428*bebae9c0SAndroid Build Coastguard Worker     if (NULL == ppName) {
429*bebae9c0SAndroid Build Coastguard Worker         result = SL_RESULT_PARAMETER_INVALID;
430*bebae9c0SAndroid Build Coastguard Worker     } else {
431*bebae9c0SAndroid Build Coastguard Worker         IEqualizer *thiz = (IEqualizer *) self;
432*bebae9c0SAndroid Build Coastguard Worker #if !defined(ANDROID)
433*bebae9c0SAndroid Build Coastguard Worker         if (index >= thiz->mNumPresets) {
434*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_PARAMETER_INVALID;
435*bebae9c0SAndroid Build Coastguard Worker         } else {
436*bebae9c0SAndroid Build Coastguard Worker             *ppName = (SLchar *) thiz->mPresets[index].mName;
437*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_SUCCESS;
438*bebae9c0SAndroid Build Coastguard Worker         }
439*bebae9c0SAndroid Build Coastguard Worker #else
440*bebae9c0SAndroid Build Coastguard Worker         if (index >= thiz->mNumPresets) {
441*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_PARAMETER_INVALID;
442*bebae9c0SAndroid Build Coastguard Worker         } else {
443*bebae9c0SAndroid Build Coastguard Worker             // FIXME query preset name rather than retrieve it from the engine.
444*bebae9c0SAndroid Build Coastguard Worker             //       In SL ES 1.0.1, the strings must exist for the lifetime of the engine.
445*bebae9c0SAndroid Build Coastguard Worker             //       Starting in 1.1, this will change and we don't need to hold onto the strings
446*bebae9c0SAndroid Build Coastguard Worker             //       for so long as they will copied into application space.
447*bebae9c0SAndroid Build Coastguard Worker             *ppName = (SLchar *) thiz->mThis->mEngine->mEqPresetNames[index];
448*bebae9c0SAndroid Build Coastguard Worker             result = SL_RESULT_SUCCESS;
449*bebae9c0SAndroid Build Coastguard Worker         }
450*bebae9c0SAndroid Build Coastguard Worker #endif
451*bebae9c0SAndroid Build Coastguard Worker     }
452*bebae9c0SAndroid Build Coastguard Worker 
453*bebae9c0SAndroid Build Coastguard Worker     SL_LEAVE_INTERFACE
454*bebae9c0SAndroid Build Coastguard Worker }
455*bebae9c0SAndroid Build Coastguard Worker 
456*bebae9c0SAndroid Build Coastguard Worker 
457*bebae9c0SAndroid Build Coastguard Worker static const struct SLEqualizerItf_ IEqualizer_Itf = {
458*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_SetEnabled,
459*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_IsEnabled,
460*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_GetNumberOfBands,
461*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_GetBandLevelRange,
462*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_SetBandLevel,
463*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_GetBandLevel,
464*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_GetCenterFreq,
465*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_GetBandFreqRange,
466*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_GetBand,
467*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_GetCurrentPreset,
468*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_UsePreset,
469*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_GetNumberOfPresets,
470*bebae9c0SAndroid Build Coastguard Worker     IEqualizer_GetPresetName
471*bebae9c0SAndroid Build Coastguard Worker };
472*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_init(void * self)473*bebae9c0SAndroid Build Coastguard Worker void IEqualizer_init(void *self)
474*bebae9c0SAndroid Build Coastguard Worker {
475*bebae9c0SAndroid Build Coastguard Worker     IEqualizer *thiz = (IEqualizer *) self;
476*bebae9c0SAndroid Build Coastguard Worker     thiz->mItf = &IEqualizer_Itf;
477*bebae9c0SAndroid Build Coastguard Worker     thiz->mEnabled = SL_BOOLEAN_FALSE;
478*bebae9c0SAndroid Build Coastguard Worker     thiz->mPreset = SL_EQUALIZER_UNDEFINED;
479*bebae9c0SAndroid Build Coastguard Worker #if 0 < MAX_EQ_BANDS
480*bebae9c0SAndroid Build Coastguard Worker     unsigned band;
481*bebae9c0SAndroid Build Coastguard Worker     for (band = 0; band < MAX_EQ_BANDS; ++band)
482*bebae9c0SAndroid Build Coastguard Worker         thiz->mLevels[band] = 0;
483*bebae9c0SAndroid Build Coastguard Worker #endif
484*bebae9c0SAndroid Build Coastguard Worker     // const fields
485*bebae9c0SAndroid Build Coastguard Worker     thiz->mNumPresets = 0;
486*bebae9c0SAndroid Build Coastguard Worker     thiz->mNumBands = 0;
487*bebae9c0SAndroid Build Coastguard Worker #if !defined(ANDROID)
488*bebae9c0SAndroid Build Coastguard Worker     thiz->mBands = EqualizerBands;
489*bebae9c0SAndroid Build Coastguard Worker     thiz->mPresets = EqualizerPresets;
490*bebae9c0SAndroid Build Coastguard Worker #endif
491*bebae9c0SAndroid Build Coastguard Worker     thiz->mBandLevelRangeMin = 0;
492*bebae9c0SAndroid Build Coastguard Worker     thiz->mBandLevelRangeMax = 0;
493*bebae9c0SAndroid Build Coastguard Worker #if defined(ANDROID)
494*bebae9c0SAndroid Build Coastguard Worker     memset(&thiz->mEqDescriptor, 0, sizeof(effect_descriptor_t));
495*bebae9c0SAndroid Build Coastguard Worker     // placement new (explicit constructor)
496*bebae9c0SAndroid Build Coastguard Worker     (void) new (&thiz->mEqEffect) android::sp<android::AudioEffect>();
497*bebae9c0SAndroid Build Coastguard Worker #endif
498*bebae9c0SAndroid Build Coastguard Worker }
499*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_deinit(void * self)500*bebae9c0SAndroid Build Coastguard Worker void IEqualizer_deinit(void *self)
501*bebae9c0SAndroid Build Coastguard Worker {
502*bebae9c0SAndroid Build Coastguard Worker #if defined(ANDROID)
503*bebae9c0SAndroid Build Coastguard Worker     IEqualizer *thiz = (IEqualizer *) self;
504*bebae9c0SAndroid Build Coastguard Worker     // explicit destructor
505*bebae9c0SAndroid Build Coastguard Worker     thiz->mEqEffect.~sp();
506*bebae9c0SAndroid Build Coastguard Worker #endif
507*bebae9c0SAndroid Build Coastguard Worker }
508*bebae9c0SAndroid Build Coastguard Worker 
IEqualizer_Expose(void * self)509*bebae9c0SAndroid Build Coastguard Worker bool IEqualizer_Expose(void *self)
510*bebae9c0SAndroid Build Coastguard Worker {
511*bebae9c0SAndroid Build Coastguard Worker #if defined(ANDROID)
512*bebae9c0SAndroid Build Coastguard Worker     IEqualizer *thiz = (IEqualizer *) self;
513*bebae9c0SAndroid Build Coastguard Worker     if (!android_fx_initEffectDescriptor(SL_IID_EQUALIZER, &thiz->mEqDescriptor)) {
514*bebae9c0SAndroid Build Coastguard Worker         SL_LOGE("Equalizer initialization failed");
515*bebae9c0SAndroid Build Coastguard Worker         thiz->mNumPresets = 0;
516*bebae9c0SAndroid Build Coastguard Worker         thiz->mNumBands = 0;
517*bebae9c0SAndroid Build Coastguard Worker         thiz->mBandLevelRangeMin = 0;
518*bebae9c0SAndroid Build Coastguard Worker         thiz->mBandLevelRangeMax = 0;
519*bebae9c0SAndroid Build Coastguard Worker         return false;
520*bebae9c0SAndroid Build Coastguard Worker     }
521*bebae9c0SAndroid Build Coastguard Worker #endif
522*bebae9c0SAndroid Build Coastguard Worker     return true;
523*bebae9c0SAndroid Build Coastguard Worker }
524