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