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