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