• 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 
18 #include "sles_allinclusive.h"
19 #include "math.h"
20 #include "utils/RefBase.h"
21 #include <audio_effects/effect_bassboost.h>
22 #include <audio_effects/effect_equalizer.h>
23 #include <audio_effects/effect_environmentalreverb.h>
24 #include <audio_effects/effect_presetreverb.h>
25 #include <audio_effects/effect_virtualizer.h>
26 
27 #include <audio_effects/effect_aec.h>
28 #include <audio_effects/effect_agc.h>
29 #include <audio_effects/effect_ns.h>
30 
31 #include <system/audio.h>
32 
33 static const int EQUALIZER_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t)
34         + EFFECT_STRING_LEN_MAX;
35 
36 static const int BASSBOOST_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t);
37 
38 static const int VIRTUALIZER_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t);
39 
40 static const int ENVREVERB_PARAM_SIZE_MAX_SINGLE = sizeof(effect_param_t) + 2 * sizeof(int32_t);
41 
42 static const int ENVREVERB_PARAM_SIZE_MAX_ALL = sizeof(effect_param_t) + sizeof(int32_t)
43         + sizeof(s_reverb_settings);
44 
45 static const int PRESETREVERB_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t);
46 
KEY_FROM_GUID(SLInterfaceID pUuid)47 static inline SLuint32 KEY_FROM_GUID(SLInterfaceID pUuid) {
48     return pUuid->time_low;
49 }
50 
51 
52 //-----------------------------------------------------------------------------
eq_paramSize(int32_t param)53 uint32_t eq_paramSize(int32_t param) {
54     uint32_t size;
55 
56     switch (param) {
57     case EQ_PARAM_NUM_BANDS:
58     case EQ_PARAM_LEVEL_RANGE:
59     case EQ_PARAM_CUR_PRESET:
60     case EQ_PARAM_GET_NUM_OF_PRESETS:
61         size = sizeof(int32_t);
62         break;
63     case EQ_PARAM_BAND_LEVEL:
64     case EQ_PARAM_CENTER_FREQ:
65     case EQ_PARAM_BAND_FREQ_RANGE:
66     case EQ_PARAM_GET_BAND:
67     case EQ_PARAM_GET_PRESET_NAME:
68         size = 2 * sizeof(int32_t);
69         break;
70     default:
71         size = 2 * sizeof(int32_t);
72         SL_LOGE("Trying to use an unknown EQ parameter %d", param);
73         break;
74     }
75     return size;
76 }
77 
eq_valueSize(int32_t param)78 uint32_t eq_valueSize(int32_t param) {
79     uint32_t size;
80 
81     switch (param) {
82     case EQ_PARAM_NUM_BANDS:
83     case EQ_PARAM_CUR_PRESET:
84     case EQ_PARAM_GET_NUM_OF_PRESETS:
85     case EQ_PARAM_BAND_LEVEL:
86     case EQ_PARAM_GET_BAND:
87         size = sizeof(int16_t);
88         break;
89     case EQ_PARAM_LEVEL_RANGE:
90         size = 2 * sizeof(int16_t);
91         break;
92     case EQ_PARAM_CENTER_FREQ:
93         size = sizeof(int32_t);
94         break;
95     case EQ_PARAM_BAND_FREQ_RANGE:
96         size = 2 * sizeof(int32_t);
97         break;
98     case EQ_PARAM_GET_PRESET_NAME:
99         size = EFFECT_STRING_LEN_MAX;
100         break;
101     default:
102         size = sizeof(int32_t);
103         SL_LOGE("Trying to access an unknown EQ parameter %d", param);
104         break;
105     }
106     return size;
107 }
108 
109 //-----------------------------------------------------------------------------
110 /**
111  * returns the size in bytes of the value of each bass boost parameter
112  */
bb_valueSize(int32_t param)113 uint32_t bb_valueSize(int32_t param) {
114     uint32_t size;
115 
116     switch (param) {
117     case BASSBOOST_PARAM_STRENGTH_SUPPORTED:
118         size = sizeof(int32_t);
119         break;
120     case BASSBOOST_PARAM_STRENGTH:
121         size = sizeof(int16_t);
122         break;
123     default:
124         size = sizeof(int32_t);
125         SL_LOGE("Trying to access an unknown BassBoost parameter %d", param);
126         break;
127     }
128 
129     return size;
130 }
131 
132 //-----------------------------------------------------------------------------
133 /**
134  * returns the size in bytes of the value of each virtualizer parameter
135  */
virt_valueSize(int32_t param)136 uint32_t virt_valueSize(int32_t param) {
137     uint32_t size;
138 
139     switch (param) {
140     case VIRTUALIZER_PARAM_STRENGTH_SUPPORTED:
141         size = sizeof(int32_t);
142         break;
143     case VIRTUALIZER_PARAM_STRENGTH:
144         size = sizeof(int16_t);
145         break;
146     default:
147         size = sizeof(int32_t);
148         SL_LOGE("Trying to access an unknown Virtualizer parameter %d", param);
149         break;
150     }
151 
152     return size;
153 }
154 
155 //-----------------------------------------------------------------------------
156 /**
157  * returns the size in bytes of the value of each environmental reverb parameter
158  */
erev_valueSize(int32_t param)159 uint32_t erev_valueSize(int32_t param) {
160     uint32_t size;
161 
162     switch (param) {
163     case REVERB_PARAM_ROOM_LEVEL:
164     case REVERB_PARAM_ROOM_HF_LEVEL:
165     case REVERB_PARAM_REFLECTIONS_LEVEL:
166     case REVERB_PARAM_REVERB_LEVEL:
167         size = sizeof(int16_t); // millibel
168         break;
169     case REVERB_PARAM_DECAY_TIME:
170     case REVERB_PARAM_REFLECTIONS_DELAY:
171     case REVERB_PARAM_REVERB_DELAY:
172         size = sizeof(uint32_t); // milliseconds
173         break;
174     case REVERB_PARAM_DECAY_HF_RATIO:
175     case REVERB_PARAM_DIFFUSION:
176     case REVERB_PARAM_DENSITY:
177         size = sizeof(int16_t); // permille
178         break;
179     case REVERB_PARAM_PROPERTIES:
180         size = sizeof(s_reverb_settings); // struct of all reverb properties
181         break;
182     default:
183         size = sizeof(int32_t);
184         SL_LOGE("Trying to access an unknown Environmental Reverb parameter %d", param);
185         break;
186     }
187 
188     return size;
189 }
190 
191 //-----------------------------------------------------------------------------
android_eq_getParam(android::sp<android::AudioEffect> pFx,int32_t param,int32_t param2,void * pValue)192 android::status_t android_eq_getParam(android::sp<android::AudioEffect> pFx,
193         int32_t param, int32_t param2, void *pValue)
194 {
195      android::status_t status;
196      uint32_t buf32[(EQUALIZER_PARAM_SIZE_MAX - 1) / sizeof(uint32_t) + 1];
197      effect_param_t *p = (effect_param_t *)buf32;
198 
199      p->psize = eq_paramSize(param);
200      *(int32_t *)p->data = param;
201      if (p->psize == 2 * sizeof(int32_t)) {
202          *((int32_t *)p->data + 1) = param2;
203      }
204      p->vsize = eq_valueSize(param);
205      status = pFx->getParameter(p);
206      if (android::NO_ERROR == status) {
207          status = p->status;
208          if (android::NO_ERROR == status) {
209              memcpy(pValue, p->data + p->psize, p->vsize);
210          }
211      }
212 
213      return status;
214  }
215 
216 
217 //-----------------------------------------------------------------------------
android_eq_setParam(android::sp<android::AudioEffect> pFx,int32_t param,int32_t param2,void * pValue)218 android::status_t android_eq_setParam(android::sp<android::AudioEffect> pFx,
219         int32_t param, int32_t param2, void *pValue)
220 {
221     android::status_t status;
222     uint32_t buf32[(EQUALIZER_PARAM_SIZE_MAX - 1) / sizeof(uint32_t) + 1];
223     effect_param_t *p = (effect_param_t *)buf32;
224 
225     p->psize = eq_paramSize(param);
226     *(int32_t *)p->data = param;
227     if (p->psize == 2 * sizeof(int32_t)) {
228         *((int32_t *)p->data + 1) = param2;
229     }
230     p->vsize = eq_valueSize(param);
231     memcpy(p->data + p->psize, pValue, p->vsize);
232     status = pFx->setParameter(p);
233     if (android::NO_ERROR == status) {
234         status = p->status;
235     }
236 
237     return status;
238 }
239 
240 //-----------------------------------------------------------------------------
android_bb_setParam(android::sp<android::AudioEffect> pFx,int32_t param,void * pValue)241 android::status_t android_bb_setParam(android::sp<android::AudioEffect> pFx,
242         int32_t param, void *pValue) {
243 
244     return android_fx_setParam(pFx, param, BASSBOOST_PARAM_SIZE_MAX,
245             pValue, bb_valueSize(param));
246 }
247 
248 //-----------------------------------------------------------------------------
android_bb_getParam(android::sp<android::AudioEffect> pFx,int32_t param,void * pValue)249 android::status_t android_bb_getParam(android::sp<android::AudioEffect> pFx,
250         int32_t param, void *pValue) {
251 
252     return android_fx_getParam(pFx, param, BASSBOOST_PARAM_SIZE_MAX,
253             pValue, bb_valueSize(param));
254 }
255 
256 //-----------------------------------------------------------------------------
android_bb_init(int sessionId,IBassBoost * ibb)257 void android_bb_init(int sessionId, IBassBoost* ibb) {
258     SL_LOGV("session %d", sessionId);
259 
260     if (!android_fx_initEffectObj(sessionId, ibb->mBassBoostEffect,
261             &ibb->mBassBoostDescriptor.type))
262     {
263         SL_LOGE("BassBoost effect initialization failed");
264         return;
265     }
266 
267     // initialize strength
268     int16_t strength;
269     if (android::NO_ERROR == android_bb_getParam(ibb->mBassBoostEffect,
270             BASSBOOST_PARAM_STRENGTH, &strength)) {
271         ibb->mStrength = (SLpermille) strength;
272     }
273 }
274 
275 
276 //-----------------------------------------------------------------------------
android_eq_init(int sessionId,IEqualizer * ieq)277 void android_eq_init(int sessionId, IEqualizer* ieq) {
278     SL_LOGV("android_eq_init on session %d", sessionId);
279 
280     if (!android_fx_initEffectObj(sessionId, ieq->mEqEffect, &ieq->mEqDescriptor.type)) {
281         SL_LOGE("Equalizer effect initialization failed");
282         return;
283     }
284 
285     // initialize number of bands, band level range, and number of presets
286     uint16_t num = 0;
287     if (android::NO_ERROR == android_eq_getParam(ieq->mEqEffect, EQ_PARAM_NUM_BANDS, 0, &num)) {
288         ieq->mNumBands = num;
289     }
290     int16_t range[2] = {0, 0};
291     if (android::NO_ERROR == android_eq_getParam(ieq->mEqEffect, EQ_PARAM_LEVEL_RANGE, 0, range)) {
292         ieq->mBandLevelRangeMin = range[0];
293         ieq->mBandLevelRangeMax = range[1];
294     }
295 
296     SL_LOGV(" EQ init: num bands = %u, band range=[%d %d]mB", num, range[0], range[1]);
297 
298     // FIXME don't store presets names, they can be queried each time they're needed
299     // initialize preset number and names, store in IEngine
300     uint16_t numPresets = 0;
301     if (android::NO_ERROR == android_eq_getParam(ieq->mEqEffect,
302             EQ_PARAM_GET_NUM_OF_PRESETS, 0, &numPresets)) {
303         ieq->mThis->mEngine->mEqNumPresets = numPresets;
304         ieq->mNumPresets = numPresets;
305     }
306 
307     object_lock_exclusive(&ieq->mThis->mEngine->mObject);
308     char name[EFFECT_STRING_LEN_MAX];
309     if ((0 < numPresets) && (NULL == ieq->mThis->mEngine->mEqPresetNames)) {
310         ieq->mThis->mEngine->mEqPresetNames = (char **)new char *[numPresets];
311         for(uint32_t i = 0 ; i < numPresets ; i++) {
312             if (android::NO_ERROR == android_eq_getParam(ieq->mEqEffect,
313                     EQ_PARAM_GET_PRESET_NAME, i, name)) {
314                 ieq->mThis->mEngine->mEqPresetNames[i] = new char[strlen(name) + 1];
315                 strcpy(ieq->mThis->mEngine->mEqPresetNames[i], name);
316                 SL_LOGV(" EQ init: presets = %u is %s", i, ieq->mThis->mEngine->mEqPresetNames[i]);
317             }
318         }
319     }
320     object_unlock_exclusive(&ieq->mThis->mEngine->mObject);
321 
322 }
323 
324 
325 //-----------------------------------------------------------------------------
android_virt_init(int sessionId,IVirtualizer * ivi)326 void android_virt_init(int sessionId, IVirtualizer* ivi) {
327     SL_LOGV("android_virt_init on session %d", sessionId);
328 
329     if (!android_fx_initEffectObj(sessionId, ivi->mVirtualizerEffect,
330             &ivi->mVirtualizerDescriptor.type)) {
331         SL_LOGE("Virtualizer effect initialization failed");
332         return;
333     }
334 
335     // initialize strength
336     int16_t strength;
337     if (android::NO_ERROR == android_virt_getParam(ivi->mVirtualizerEffect,
338             VIRTUALIZER_PARAM_STRENGTH, &strength)) {
339         ivi->mStrength = (SLpermille) strength;
340     }
341 }
342 
343 //-----------------------------------------------------------------------------
android_virt_setParam(android::sp<android::AudioEffect> pFx,int32_t param,void * pValue)344 android::status_t android_virt_setParam(android::sp<android::AudioEffect> pFx,
345         int32_t param, void *pValue) {
346 
347     return android_fx_setParam(pFx, param, VIRTUALIZER_PARAM_SIZE_MAX,
348             pValue, virt_valueSize(param));
349 }
350 
351 //-----------------------------------------------------------------------------
android_virt_getParam(android::sp<android::AudioEffect> pFx,int32_t param,void * pValue)352 android::status_t android_virt_getParam(android::sp<android::AudioEffect> pFx,
353         int32_t param, void *pValue) {
354 
355     return android_fx_getParam(pFx, param, VIRTUALIZER_PARAM_SIZE_MAX,
356             pValue, virt_valueSize(param));
357 }
358 
359 
360 //-----------------------------------------------------------------------------
android_prev_init(IPresetReverb * ipr)361 void android_prev_init(IPresetReverb* ipr) {
362     SL_LOGV("session is implicitly %d (aux effect)", AUDIO_SESSION_OUTPUT_MIX);
363 
364     if (!android_fx_initEffectObj(AUDIO_SESSION_OUTPUT_MIX /*sessionId*/,
365             ipr->mPresetReverbEffect, &ipr->mPresetReverbDescriptor.type)) {
366         SL_LOGE("PresetReverb effect initialization failed");
367         return;
368     }
369 
370     // initialize preset
371     uint16_t preset;
372     if (android::NO_ERROR == android_prev_getPreset(ipr->mPresetReverbEffect, &preset)) {
373         ipr->mPreset = preset;
374         // enable the effect if it has a preset loaded
375         ipr->mPresetReverbEffect->setEnabled(SL_REVERBPRESET_NONE != preset);
376     }
377 }
378 
379 //-----------------------------------------------------------------------------
android_prev_setPreset(android::sp<android::AudioEffect> pFx,uint16_t preset)380 android::status_t android_prev_setPreset(android::sp<android::AudioEffect> pFx, uint16_t preset) {
381     android::status_t status = android_fx_setParam(pFx, REVERB_PARAM_PRESET,
382             PRESETREVERB_PARAM_SIZE_MAX, &preset, sizeof(uint16_t));
383     // enable the effect if the preset is different from SL_REVERBPRESET_NONE
384     pFx->setEnabled(SL_REVERBPRESET_NONE != preset);
385     return status;
386 }
387 
388 //-----------------------------------------------------------------------------
android_prev_getPreset(android::sp<android::AudioEffect> pFx,uint16_t * preset)389 android::status_t android_prev_getPreset(android::sp<android::AudioEffect> pFx, uint16_t* preset) {
390     return android_fx_getParam(pFx, REVERB_PARAM_PRESET, PRESETREVERB_PARAM_SIZE_MAX, preset,
391             sizeof(uint16_t));
392 }
393 
394 
395 //-----------------------------------------------------------------------------
android_erev_init(IEnvironmentalReverb * ier)396 void android_erev_init(IEnvironmentalReverb* ier) {
397     SL_LOGV("session is implicitly %d (aux effect)", AUDIO_SESSION_OUTPUT_MIX);
398 
399     if (!android_fx_initEffectObj(AUDIO_SESSION_OUTPUT_MIX /*sessionId*/,
400             ier->mEnvironmentalReverbEffect, &ier->mEnvironmentalReverbDescriptor.type)) {
401         SL_LOGE("EnvironmentalReverb effect initialization failed");
402         return;
403     }
404 
405     // enable env reverb: other SL ES effects have an explicit SetEnabled() function, and the
406     //  preset reverb state depends on the selected preset.
407     ier->mEnvironmentalReverbEffect->setEnabled(true);
408 
409     // initialize reverb properties
410     SLEnvironmentalReverbSettings properties;
411     if (android::NO_ERROR == android_erev_getParam(ier->mEnvironmentalReverbEffect,
412             REVERB_PARAM_PROPERTIES, &properties)) {
413         ier->mProperties = properties;
414     }
415 }
416 
417 //-----------------------------------------------------------------------------
android_erev_setParam(android::sp<android::AudioEffect> pFx,int32_t param,void * pValue)418 android::status_t android_erev_setParam(android::sp<android::AudioEffect> pFx,
419         int32_t param, void *pValue) {
420 
421     // given the size difference between a single reverb property and the whole set of reverb
422     // properties, select which max size to pass to avoid allocating too much memory
423     if (param == REVERB_PARAM_PROPERTIES) {
424         return android_fx_setParam(pFx, param, ENVREVERB_PARAM_SIZE_MAX_ALL,
425                 pValue, erev_valueSize(param));
426     } else {
427         return android_fx_setParam(pFx, param, ENVREVERB_PARAM_SIZE_MAX_SINGLE,
428                 pValue, erev_valueSize(param));
429     }
430 }
431 
432 //-----------------------------------------------------------------------------
android_erev_getParam(android::sp<android::AudioEffect> pFx,int32_t param,void * pValue)433 android::status_t android_erev_getParam(android::sp<android::AudioEffect> pFx,
434         int32_t param, void *pValue) {
435 
436     // given the size difference between a single reverb property and the whole set of reverb
437     // properties, select which max size to pass to avoid allocating too much memory
438     if (param == REVERB_PARAM_PROPERTIES) {
439         return android_fx_getParam(pFx, param, ENVREVERB_PARAM_SIZE_MAX_ALL,
440                 pValue, erev_valueSize(param));
441     } else {
442         return android_fx_getParam(pFx, param, ENVREVERB_PARAM_SIZE_MAX_SINGLE,
443                 pValue, erev_valueSize(param));
444     }
445 }
446 
447 
448 //-----------------------------------------------------------------------------
449 /**
450  * pre-condition:
451  *    ap != NULL
452  *    for media players:
453  *      ap->mAPlayer != 0
454  *      ap->mAudioTrack == 0
455  *    for buffer queue players:
456  *      ap->mAPlayer == 0
457  *      ap->mAudioTrack != 0 is optional; if no track yet then the setting is deferred
458  */
android_fxSend_attach(CAudioPlayer * ap,bool attach,android::sp<android::AudioEffect> pFx,SLmillibel sendLevel)459 android::status_t android_fxSend_attach(CAudioPlayer* ap, bool attach,
460         android::sp<android::AudioEffect> pFx, SLmillibel sendLevel) {
461 
462     if (pFx == 0) {
463         return android::INVALID_OPERATION;
464     }
465 
466     // There are 3 cases:
467     //  mAPlayer != 0 && mAudioTrack == 0 means playing decoded audio
468     //  mAPlayer == 0 && mAudioTrack != 0 means playing PCM audio
469     //  mAPlayer == 0 && mAudioTrack == 0 means player not fully configured yet
470     // The asserts document and verify this.
471     if (ap->mAPlayer != 0) {
472         assert(ap->mAudioTrack == 0);
473         if (attach) {
474             ap->mAPlayer->attachAuxEffect(pFx->id());
475             ap->mAPlayer->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
476         } else {
477             ap->mAPlayer->attachAuxEffect(0);
478         }
479         return android::NO_ERROR;
480     }
481 
482     if (ap->mAudioTrack == 0) {
483         // the player doesn't have an AudioTrack at the moment, so store this info to use it
484         // when the AudioTrack becomes available
485         if (attach) {
486             ap->mAuxEffect = pFx;
487         } else {
488             ap->mAuxEffect.clear();
489         }
490         // we keep track of the send level, independently of the current audio player level
491         ap->mAuxSendLevel = sendLevel - ap->mVolume.mLevel;
492         return android::NO_ERROR;
493     }
494 
495     if (attach) {
496         android::status_t status = ap->mAudioTrack->attachAuxEffect(pFx->id());
497         //SL_LOGV("attachAuxEffect(%d) returned %d", pFx->id(), status);
498         if (android::NO_ERROR == status) {
499             status =
500                 ap->mAudioTrack->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
501         }
502         return status;
503     } else {
504         return ap->mAudioTrack->attachAuxEffect(0);
505     }
506 }
507 
508 //-----------------------------------------------------------------------------
509 /**
510  * pre-condition:
511  *    ap != NULL
512  *    ap->mOutputMix != NULL
513  */
android_fxSend_attachToAux(CAudioPlayer * ap,SLInterfaceID pUuid,SLboolean attach,SLmillibel sendLevel)514 SLresult android_fxSend_attachToAux(CAudioPlayer* ap, SLInterfaceID pUuid, SLboolean attach,
515         SLmillibel sendLevel) {
516     COutputMix *outputMix = CAudioPlayer_GetOutputMix(ap);
517     ssize_t index = outputMix->mAndroidEffect.mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
518 
519     if (0 > index) {
520         SL_LOGE("invalid effect ID: no such effect attached to the OutputMix");
521         return SL_RESULT_PARAMETER_INVALID;
522     }
523 
524     android::AudioEffect* pFx = outputMix->mAndroidEffect.mEffects->valueAt(index);
525     if (NULL == pFx) {
526         return SL_RESULT_RESOURCE_ERROR;
527     }
528     if (android::NO_ERROR == android_fxSend_attach( ap, (bool) attach, pFx, sendLevel) ) {
529         return SL_RESULT_SUCCESS;
530     } else {
531         return SL_RESULT_RESOURCE_ERROR;
532     }
533 
534 }
535 
536 //-----------------------------------------------------------------------------
537 /**
538  * pre-condition:
539  *    ap != NULL
540  *    for media players:
541  *      ap->mAPlayer != 0
542  *      ap->mAudioTrack == 0
543  *    for buffer queue players:
544  *      ap->mAPlayer == 0
545  *      ap->mAudioTrack != 0 is optional; if no track yet then the setting is deferred
546  */
android_fxSend_setSendLevel(CAudioPlayer * ap,SLmillibel sendLevel)547 android::status_t android_fxSend_setSendLevel(CAudioPlayer* ap, SLmillibel sendLevel) {
548     // we keep track of the send level, independently of the current audio player level
549     ap->mAuxSendLevel = sendLevel - ap->mVolume.mLevel;
550 
551     if (ap->mAPlayer != 0) {
552         assert(ap->mAudioTrack == 0);
553         ap->mAPlayer->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
554         return android::NO_ERROR;
555     }
556 
557     if (ap->mAudioTrack == 0) {
558         return android::NO_ERROR;
559     }
560 
561     return ap->mAudioTrack->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
562 }
563 
564 //-----------------------------------------------------------------------------
android_fx_setParam(android::sp<android::AudioEffect> pFx,int32_t param,uint32_t paramSizeMax,void * pValue,uint32_t valueSize)565 android::status_t android_fx_setParam(android::sp<android::AudioEffect> pFx,
566         int32_t param, uint32_t paramSizeMax, void *pValue, uint32_t valueSize)
567 {
568 
569     android::status_t status;
570     uint32_t buf32[(paramSizeMax - 1) / sizeof(uint32_t) + 1];
571     effect_param_t *p = (effect_param_t *)buf32;
572 
573     p->psize = sizeof(int32_t);
574     *(int32_t *)p->data = param;
575     p->vsize = valueSize;
576     memcpy(p->data + p->psize, pValue, p->vsize);
577     status = pFx->setParameter(p);
578     if (android::NO_ERROR == status) {
579         status = p->status;
580     }
581     return status;
582 }
583 
584 
585 //-----------------------------------------------------------------------------
android_fx_getParam(android::sp<android::AudioEffect> pFx,int32_t param,uint32_t paramSizeMax,void * pValue,uint32_t valueSize)586 android::status_t android_fx_getParam(android::sp<android::AudioEffect> pFx,
587         int32_t param, uint32_t paramSizeMax, void *pValue, uint32_t valueSize)
588 {
589     android::status_t status;
590     uint32_t buf32[(paramSizeMax - 1) / sizeof(uint32_t) + 1];
591     effect_param_t *p = (effect_param_t *)buf32;
592 
593     p->psize = sizeof(int32_t);
594     *(int32_t *)p->data = param;
595     p->vsize = valueSize;
596     status = pFx->getParameter(p);
597     if (android::NO_ERROR == status) {
598         status = p->status;
599         if (android::NO_ERROR == status) {
600             memcpy(pValue, p->data + p->psize, p->vsize);
601         }
602     }
603 
604     return status;
605 }
606 
607 
608 //-----------------------------------------------------------------------------
android_fx_statusToResult(android::status_t status)609 SLresult android_fx_statusToResult(android::status_t status) {
610 
611     if ((android::INVALID_OPERATION == status) || (android::DEAD_OBJECT == status)) {
612         return SL_RESULT_CONTROL_LOST;
613     } else {
614         return SL_RESULT_SUCCESS;
615     }
616 }
617 
618 
619 //-----------------------------------------------------------------------------
android_fx_initEffectObj(int sessionId,android::sp<android::AudioEffect> & effect,const effect_uuid_t * type)620 bool android_fx_initEffectObj(int sessionId, android::sp<android::AudioEffect>& effect,
621         const effect_uuid_t *type) {
622     //SL_LOGV("android_fx_initEffectObj on session %d", sessionId);
623 
624     effect = new android::AudioEffect(type, EFFECT_UUID_NULL,
625             0,// priority
626             0,// effect callback
627             0,// callback data
628             sessionId,// session ID
629             0 );// output
630 
631     android::status_t status = effect->initCheck();
632     if (android::NO_ERROR != status) {
633         effect.clear();
634         SL_LOGE("Effect initCheck() returned %d", status);
635         return false;
636     }
637 
638     return true;
639 }
640 
641 
642 //-----------------------------------------------------------------------------
android_fx_initEffectDescriptor(const SLInterfaceID effectId,effect_descriptor_t * fxDescrLoc)643 bool android_fx_initEffectDescriptor(const SLInterfaceID effectId,
644         effect_descriptor_t* fxDescrLoc) {
645     uint32_t numEffects = 0;
646     effect_descriptor_t descriptor;
647     bool foundEffect = false;
648 
649     // any effects?
650     android::status_t res = android::AudioEffect::queryNumberEffects(&numEffects);
651     if (android::NO_ERROR != res) {
652         SL_LOGE("unable to find any effects.");
653         goto effectError;
654     }
655 
656     // request effect in the effects?
657     for (uint32_t i=0 ; i < numEffects ; i++) {
658         res = android::AudioEffect::queryEffect(i, &descriptor);
659         if ((android::NO_ERROR == res) &&
660                 (0 == memcmp(effectId, &descriptor.type, sizeof(effect_uuid_t)))) {
661             SL_LOGV("found effect %d %s", i, descriptor.name);
662             foundEffect = true;
663             break;
664         }
665     }
666     if (foundEffect) {
667         memcpy(fxDescrLoc, &descriptor, sizeof(effect_descriptor_t));
668     } else {
669         SL_LOGE("unable to find an implementation for the requested effect.");
670         goto effectError;
671     }
672 
673     return true;
674 
675 effectError:
676     // the requested effect wasn't found
677     memset(fxDescrLoc, 0, sizeof(effect_descriptor_t));
678 
679     return false;
680 }
681 
682 //-----------------------------------------------------------------------------
android_genericFx_queryNumEffects(SLuint32 * pNumSupportedAudioEffects)683 SLresult android_genericFx_queryNumEffects(SLuint32 *pNumSupportedAudioEffects) {
684 
685     if (NULL == pNumSupportedAudioEffects) {
686         return SL_RESULT_PARAMETER_INVALID;
687     }
688 
689     android::status_t status =
690             android::AudioEffect::queryNumberEffects((uint32_t*)pNumSupportedAudioEffects);
691 
692     SLresult result = SL_RESULT_SUCCESS;
693     switch(status) {
694         case android::NO_ERROR:
695             result = SL_RESULT_SUCCESS;
696             break;
697         case android::PERMISSION_DENIED:
698             result = SL_RESULT_PERMISSION_DENIED;
699             break;
700         case android::NO_INIT:
701             result = SL_RESULT_RESOURCE_ERROR;
702             break;
703         case android::BAD_VALUE:
704             result = SL_RESULT_PARAMETER_INVALID;
705             break;
706         default:
707             result = SL_RESULT_INTERNAL_ERROR;
708             SL_LOGE("received invalid status %d from AudioEffect::queryNumberEffects()", status);
709             break;
710     }
711     return result;
712 }
713 
714 
715 //-----------------------------------------------------------------------------
android_genericFx_queryEffect(SLuint32 index,effect_descriptor_t * pDescriptor)716 SLresult android_genericFx_queryEffect(SLuint32 index, effect_descriptor_t* pDescriptor) {
717 
718     if (NULL == pDescriptor) {
719         return SL_RESULT_PARAMETER_INVALID;
720     }
721 
722     android::status_t status =
723                 android::AudioEffect::queryEffect(index, pDescriptor);
724 
725     SLresult result = SL_RESULT_SUCCESS;
726     if (android::NO_ERROR != status) {
727         switch(status) {
728         case android::PERMISSION_DENIED:
729             result = SL_RESULT_PERMISSION_DENIED;
730             break;
731         case android::NO_INIT:
732         case android::INVALID_OPERATION:
733             result = SL_RESULT_RESOURCE_ERROR;
734             break;
735         case android::BAD_VALUE:
736             result = SL_RESULT_PARAMETER_INVALID;
737             break;
738         default:
739             result = SL_RESULT_INTERNAL_ERROR;
740             SL_LOGE("received invalid status %d from AudioEffect::queryNumberEffects()", status);
741             break;
742         }
743         // an error occurred, reset the effect descriptor
744         memset(pDescriptor, 0, sizeof(effect_descriptor_t));
745     }
746 
747     return result;
748 }
749 
750 
751 //-----------------------------------------------------------------------------
android_genericFx_createEffect(IAndroidEffect * iae,SLInterfaceID pUuid,int sessionId)752 SLresult android_genericFx_createEffect(IAndroidEffect* iae, SLInterfaceID pUuid, int sessionId) {
753 
754     SLresult result = SL_RESULT_SUCCESS;
755 
756     // does this effect already exist?
757     if (0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid))) {
758         return result;
759     }
760 
761     // create new effect
762     android::AudioEffect* pFx = new android::AudioEffect(
763             NULL, // not using type to create effect
764             (const effect_uuid_t*)pUuid,
765             0,// priority
766             0,// effect callback
767             0,// callback data
768             sessionId,
769             0 );// output
770 
771     // verify effect was successfully created before storing it
772     android::status_t status = pFx->initCheck();
773     if (android::NO_ERROR != status) {
774         SL_LOGE("AudioEffect initCheck() returned %d, effect will not be stored", status);
775         delete pFx;
776         result = SL_RESULT_RESOURCE_ERROR;
777     } else {
778         SL_LOGV("AudioEffect successfully created on session %d", sessionId);
779         iae->mEffects->add(KEY_FROM_GUID(pUuid), pFx);
780     }
781 
782     return result;
783 }
784 
785 
786 //-----------------------------------------------------------------------------
android_genericFx_releaseEffect(IAndroidEffect * iae,SLInterfaceID pUuid)787 SLresult android_genericFx_releaseEffect(IAndroidEffect* iae, SLInterfaceID pUuid) {
788 
789     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
790 
791     if (0 > index) {
792         return SL_RESULT_PARAMETER_INVALID;
793     } else {
794         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
795         delete pFx;
796         iae->mEffects->removeItem(index);
797         return SL_RESULT_SUCCESS;
798     }
799 }
800 
801 
802 //-----------------------------------------------------------------------------
android_genericFx_setEnabled(IAndroidEffect * iae,SLInterfaceID pUuid,SLboolean enabled)803 SLresult android_genericFx_setEnabled(IAndroidEffect* iae, SLInterfaceID pUuid, SLboolean enabled) {
804 
805     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
806 
807     if (0 > index) {
808         return SL_RESULT_PARAMETER_INVALID;
809     } else {
810         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
811         android::status_t status = pFx->setEnabled(SL_BOOLEAN_TRUE == enabled);
812         return android_fx_statusToResult(status);
813     }
814 }
815 
816 
817 //-----------------------------------------------------------------------------
android_genericFx_isEnabled(IAndroidEffect * iae,SLInterfaceID pUuid,SLboolean * pEnabled)818 SLresult android_genericFx_isEnabled(IAndroidEffect* iae, SLInterfaceID pUuid, SLboolean *pEnabled)
819 {
820     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
821 
822     if (0 > index) {
823         return SL_RESULT_PARAMETER_INVALID;
824     } else {
825         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
826         *pEnabled = (SLboolean) pFx->getEnabled();
827         return SL_RESULT_SUCCESS;
828     }
829 }
830 
831 
832 //-----------------------------------------------------------------------------
android_genericFx_sendCommand(IAndroidEffect * iae,SLInterfaceID pUuid,SLuint32 command,SLuint32 commandSize,void * pCommandData,SLuint32 * replySize,void * pReplyData)833 SLresult android_genericFx_sendCommand(IAndroidEffect* iae, SLInterfaceID pUuid,
834         SLuint32 command, SLuint32 commandSize, void* pCommandData,
835         SLuint32 *replySize, void *pReplyData) {
836 
837     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
838 
839     if (0 > index) {
840         return SL_RESULT_PARAMETER_INVALID;
841     } else {
842         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
843         android::status_t status = pFx->command(
844                 (uint32_t) command,
845                 (uint32_t) commandSize,
846                 pCommandData,
847                 (uint32_t*)replySize,
848                 pReplyData);
849         if (android::BAD_VALUE == status) {
850                 return SL_RESULT_PARAMETER_INVALID;
851         } else {
852             return SL_RESULT_SUCCESS;
853         }
854     }
855 }
856 
857 //-----------------------------------------------------------------------------
858 /**
859  * returns true if the given effect id is present in the AndroidEffect interface
860  */
android_genericFx_hasEffect(IAndroidEffect * iae,SLInterfaceID pUuid)861 bool android_genericFx_hasEffect(IAndroidEffect* iae, SLInterfaceID pUuid) {
862     return( 0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid)));
863 }
864 
865 //-----------------------------------------------------------------------------
866 static const int AEC_PARAM_SIZE_MAX = sizeof(effect_param_t) + (2 * sizeof(int32_t));
867 /**
868  * returns the size in bytes of the value of each acoustic echo cancellation parameter
869  */
aec_valueSize(int32_t param)870 uint32_t aec_valueSize(int32_t param) {
871     uint32_t size;
872     switch (param) {
873     case AEC_PARAM_ECHO_DELAY:
874         size = sizeof(int32_t);
875         break;
876     default:
877         size = sizeof(int32_t);
878         SL_LOGE("Trying to access an unknown Acoustic Echo Cancellation parameter %d", param);
879         break;
880     }
881 
882     return size;
883 }
884 
android_aec_setParam(android::sp<android::AudioEffect> pFx,int32_t param,void * pValue)885 android::status_t android_aec_setParam(android::sp<android::AudioEffect> pFx,
886         int32_t param, void *pValue) {
887     return android_fx_setParam(pFx, param, AEC_PARAM_SIZE_MAX,
888             pValue, aec_valueSize(param));
889 }
890 
android_aec_getParam(android::sp<android::AudioEffect> pFx,int32_t param,void * pValue)891 android::status_t android_aec_getParam(android::sp<android::AudioEffect> pFx,
892         int32_t param, void *pValue) {
893     return android_fx_getParam(pFx, param, AEC_PARAM_SIZE_MAX,
894             pValue, aec_valueSize(param));
895 }
896 
897 //-----------------------------------------------------------------------------
898 static const int AGC_PARAM_SIZE_MAX = sizeof(effect_param_t) + (2 * sizeof(int16_t)) + sizeof(bool);
899 /**
900  * returns the size in bytes of the value of each automatic gain control parameter
901  */
agc_valueSize(int32_t param)902 uint32_t agc_valueSize(int32_t param) {
903     uint32_t size;
904     switch (param) {
905     case AGC_PARAM_TARGET_LEVEL:
906     case AGC_PARAM_COMP_GAIN:
907         size = sizeof(int16_t);
908         break;
909     case AGC_PARAM_LIMITER_ENA:
910         size = sizeof(bool);
911         break;
912     default:
913         size = sizeof(int32_t);
914         SL_LOGE("Trying to access an unknown Automatic Gain Control parameter %d", param);
915         break;
916     }
917 
918     return size;
919 }
920 
android_agc_setParam(android::sp<android::AudioEffect> pFx,int32_t param,void * pValue)921 android::status_t android_agc_setParam(android::sp<android::AudioEffect> pFx,
922         int32_t param, void *pValue) {
923     return android_fx_setParam(pFx, param, AGC_PARAM_SIZE_MAX,
924             pValue, agc_valueSize(param));
925 }
926 
android_agc_getParam(android::sp<android::AudioEffect> pFx,int32_t param,void * pValue)927 android::status_t android_agc_getParam(android::sp<android::AudioEffect> pFx,
928         int32_t param, void *pValue) {
929     return android_fx_getParam(pFx, param, AGC_PARAM_SIZE_MAX,
930             pValue, agc_valueSize(param));
931 }
932 
933 //-----------------------------------------------------------------------------
934 static const int NS_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t);
935 /**
936  * returns the size in bytes of the value of each noise suppression parameter
937  */
ns_valueSize(int32_t param)938 uint32_t ns_valueSize(int32_t param) {
939     uint32_t size;
940     switch (param) {
941     case NS_PARAM_LEVEL:
942         size = sizeof(int32_t);
943         break;
944     default:
945         size = sizeof(int32_t);
946         SL_LOGE("Trying to access an unknown Noise suppression parameter %d", param);
947         break;
948     }
949 
950     return size;
951 }
952 
android_ns_setParam(android::sp<android::AudioEffect> pFx,int32_t param,void * pValue)953 android::status_t android_ns_setParam(android::sp<android::AudioEffect> pFx,
954         int32_t param, void *pValue)
955 {
956     return android_fx_setParam(pFx, param, NS_PARAM_SIZE_MAX,
957             pValue, ns_valueSize(param));
958 }
959 
android_ns_getParam(android::sp<android::AudioEffect> pFx,int32_t param,void * pValue)960 android::status_t android_ns_getParam(android::sp<android::AudioEffect> pFx,
961         int32_t param, void *pValue)
962 {
963     return android_fx_getParam(pFx, param, NS_PARAM_SIZE_MAX,
964             pValue, ns_valueSize(param));
965 }
966