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