• 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             nullptr,// effect callback
681             sessionId,// session ID
682             0); // output
683 
684     android::status_t status = effect->initCheck();
685     if (android::NO_ERROR != status) {
686         effect.clear();
687         SL_LOGE("Effect initCheck() returned %d", status);
688         return false;
689     }
690 
691     return true;
692 }
693 
694 
695 //-----------------------------------------------------------------------------
android_fx_initEffectDescriptor(const SLInterfaceID effectId,effect_descriptor_t * fxDescrLoc)696 bool android_fx_initEffectDescriptor(const SLInterfaceID effectId,
697         effect_descriptor_t* fxDescrLoc) {
698     uint32_t numEffects = 0;
699     effect_descriptor_t descriptor;
700     bool foundEffect = false;
701 
702     // any effects?
703     android::status_t res = android::AudioEffect::queryNumberEffects(&numEffects);
704     if (android::NO_ERROR != res) {
705         SL_LOGE("unable to find any effects.");
706         goto effectError;
707     }
708 
709     // request effect in the effects?
710     for (uint32_t i=0 ; i < numEffects ; i++) {
711         res = android::AudioEffect::queryEffect(i, &descriptor);
712         if ((android::NO_ERROR == res) &&
713                 (0 == memcmp(effectId, &descriptor.type, sizeof(effect_uuid_t)))) {
714             SL_LOGV("found effect %d %s", i, descriptor.name);
715             foundEffect = true;
716             break;
717         }
718     }
719     if (foundEffect) {
720         memcpy(fxDescrLoc, &descriptor, sizeof(effect_descriptor_t));
721     } else {
722         SL_LOGE("unable to find an implementation for the requested effect.");
723         goto effectError;
724     }
725 
726     return true;
727 
728 effectError:
729     // the requested effect wasn't found
730     memset(fxDescrLoc, 0, sizeof(effect_descriptor_t));
731 
732     return false;
733 }
734 
735 //-----------------------------------------------------------------------------
android_genericFx_queryNumEffects(SLuint32 * pNumSupportedAudioEffects)736 SLresult android_genericFx_queryNumEffects(SLuint32 *pNumSupportedAudioEffects) {
737 
738     if (NULL == pNumSupportedAudioEffects) {
739         return SL_RESULT_PARAMETER_INVALID;
740     }
741 
742     android::status_t status =
743             android::AudioEffect::queryNumberEffects((uint32_t*)pNumSupportedAudioEffects);
744 
745     SLresult result = SL_RESULT_SUCCESS;
746     switch (status) {
747         case android::NO_ERROR:
748             result = SL_RESULT_SUCCESS;
749             break;
750         case android::PERMISSION_DENIED:
751             result = SL_RESULT_PERMISSION_DENIED;
752             break;
753         case android::NO_INIT:
754             result = SL_RESULT_RESOURCE_ERROR;
755             break;
756         case android::BAD_VALUE:
757             result = SL_RESULT_PARAMETER_INVALID;
758             break;
759         default:
760             result = SL_RESULT_INTERNAL_ERROR;
761             SL_LOGE("received invalid status %d from AudioEffect::queryNumberEffects()", status);
762             break;
763     }
764     return result;
765 }
766 
767 
768 //-----------------------------------------------------------------------------
android_genericFx_queryEffect(SLuint32 index,effect_descriptor_t * pDescriptor)769 SLresult android_genericFx_queryEffect(SLuint32 index, effect_descriptor_t* pDescriptor) {
770 
771     if (NULL == pDescriptor) {
772         return SL_RESULT_PARAMETER_INVALID;
773     }
774 
775     android::status_t status =
776                 android::AudioEffect::queryEffect(index, pDescriptor);
777 
778     SLresult result = SL_RESULT_SUCCESS;
779     if (android::NO_ERROR != status) {
780         switch (status) {
781         case android::PERMISSION_DENIED:
782             result = SL_RESULT_PERMISSION_DENIED;
783             break;
784         case android::NO_INIT:
785         case android::INVALID_OPERATION:
786             result = SL_RESULT_RESOURCE_ERROR;
787             break;
788         case android::BAD_VALUE:
789             result = SL_RESULT_PARAMETER_INVALID;
790             break;
791         default:
792             result = SL_RESULT_INTERNAL_ERROR;
793             SL_LOGE("received invalid status %d from AudioEffect::queryNumberEffects()", status);
794             break;
795         }
796         // an error occurred, reset the effect descriptor
797         memset(pDescriptor, 0, sizeof(effect_descriptor_t));
798     }
799 
800     return result;
801 }
802 
803 
804 //-----------------------------------------------------------------------------
android_genericFx_createEffect(IAndroidEffect * iae,SLInterfaceID pUuid,audio_session_t sessionId)805 SLresult android_genericFx_createEffect(IAndroidEffect* iae, SLInterfaceID pUuid,
806         audio_session_t sessionId)
807 {
808 
809     SLresult result = SL_RESULT_SUCCESS;
810 
811     // does this effect already exist?
812     if (0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid))) {
813         return result;
814     }
815 
816     // create new effect
817     // TODO b/182392769: use attribution source util
818     AttributionSourceState attributionSource;
819     attributionSource.uid = VALUE_OR_FATAL(android::legacy2aidl_uid_t_int32_t(getuid()));
820     attributionSource.pid = VALUE_OR_FATAL(android::legacy2aidl_pid_t_int32_t(getpid()));
821     attributionSource.token = android::sp<android::BBinder>::make();
822 
823     const auto pFx = android::sp<android::AudioEffect>::make(attributionSource);
824 
825     pFx->set(NULL, // not using type to create effect
826             (const effect_uuid_t*)pUuid,
827             0,// priority
828             nullptr,// effect callback
829             sessionId,
830             0 );// output
831 
832     // verify effect was successfully created before storing it
833     android::status_t status = pFx->initCheck();
834     if (android::NO_ERROR != status) {
835         SL_LOGE("AudioEffect initCheck() returned %d, effect will not be stored", status);
836         result = SL_RESULT_RESOURCE_ERROR;
837     } else {
838         SL_LOGV("AudioEffect successfully created on session %d", sessionId);
839         iae->mEffects->add(KEY_FROM_GUID(pUuid), pFx);
840     }
841 
842     return result;
843 }
844 
845 
846 //-----------------------------------------------------------------------------
android_genericFx_releaseEffect(IAndroidEffect * iae,SLInterfaceID pUuid)847 SLresult android_genericFx_releaseEffect(IAndroidEffect* iae, SLInterfaceID pUuid) {
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         iae->mEffects->removeItem(index);
855         return SL_RESULT_SUCCESS;
856     }
857 }
858 
859 
860 //-----------------------------------------------------------------------------
android_genericFx_setEnabled(IAndroidEffect * iae,SLInterfaceID pUuid,SLboolean enabled)861 SLresult android_genericFx_setEnabled(IAndroidEffect* iae, SLInterfaceID pUuid, SLboolean enabled) {
862 
863     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
864 
865     if (0 > index) {
866         return SL_RESULT_PARAMETER_INVALID;
867     } else {
868         android::sp<android::AudioEffect> pFx = iae->mEffects->valueAt(index);
869         android::status_t status = pFx->setEnabled(SL_BOOLEAN_TRUE == enabled);
870         return android_fx_statusToResult(status);
871     }
872 }
873 
874 
875 //-----------------------------------------------------------------------------
android_genericFx_isEnabled(IAndroidEffect * iae,SLInterfaceID pUuid,SLboolean * pEnabled)876 SLresult android_genericFx_isEnabled(IAndroidEffect* iae, SLInterfaceID pUuid, SLboolean *pEnabled)
877 {
878     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
879 
880     if (0 > index) {
881         return SL_RESULT_PARAMETER_INVALID;
882     } else {
883         android::sp<android::AudioEffect> pFx = iae->mEffects->valueAt(index);
884         *pEnabled = (SLboolean) pFx->getEnabled();
885         return SL_RESULT_SUCCESS;
886     }
887 }
888 
889 
890 //-----------------------------------------------------------------------------
android_genericFx_sendCommand(IAndroidEffect * iae,SLInterfaceID pUuid,SLuint32 command,SLuint32 commandSize,void * pCommandData,SLuint32 * replySize,void * pReplyData)891 SLresult android_genericFx_sendCommand(IAndroidEffect* iae, SLInterfaceID pUuid,
892         SLuint32 command, SLuint32 commandSize, void* pCommandData,
893         SLuint32 *replySize, void *pReplyData) {
894 
895     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
896 
897     if (0 > index) {
898         return SL_RESULT_PARAMETER_INVALID;
899     } else {
900         android::sp<android::AudioEffect> pFx = iae->mEffects->valueAt(index);
901         android::status_t status = pFx->command(
902                 (uint32_t) command,
903                 (uint32_t) commandSize,
904                 pCommandData,
905                 (uint32_t*)replySize,
906                 pReplyData);
907         if (android::BAD_VALUE == status) {
908                 return SL_RESULT_PARAMETER_INVALID;
909         } else {
910             return SL_RESULT_SUCCESS;
911         }
912     }
913 }
914 
915 //-----------------------------------------------------------------------------
916 /**
917  * returns true if the given effect id is present in the AndroidEffect interface
918  */
android_genericFx_hasEffect(IAndroidEffect * iae,SLInterfaceID pUuid)919 bool android_genericFx_hasEffect(IAndroidEffect* iae, SLInterfaceID pUuid) {
920     return( 0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid)));
921 }
922 
923 //-----------------------------------------------------------------------------
924 static const int AEC_PARAM_SIZE_MAX = sizeof(effect_param_t) + (2 * sizeof(int32_t));
925 /**
926  * returns the size in bytes of the value of each acoustic echo cancellation parameter
927  */
aec_valueSize(int32_t param)928 uint32_t aec_valueSize(int32_t param) {
929     uint32_t size;
930     switch (param) {
931     case AEC_PARAM_ECHO_DELAY:
932         size = sizeof(int32_t);
933         break;
934     default:
935         size = sizeof(int32_t);
936         SL_LOGE("Trying to access an unknown Acoustic Echo Cancellation parameter %d", param);
937         break;
938     }
939 
940     return size;
941 }
942 
android_aec_setParam(const android::sp<android::AudioEffect> & pFx,int32_t param,void * pValue)943 android::status_t android_aec_setParam(const android::sp<android::AudioEffect>& pFx,
944         int32_t param, void *pValue) {
945     return android_fx_setParam(pFx, param, AEC_PARAM_SIZE_MAX,
946             pValue, aec_valueSize(param));
947 }
948 
android_aec_getParam(const android::sp<android::AudioEffect> & pFx,int32_t param,void * pValue)949 android::status_t android_aec_getParam(const android::sp<android::AudioEffect>& pFx,
950         int32_t param, void *pValue) {
951     return android_fx_getParam(pFx, param, AEC_PARAM_SIZE_MAX,
952             pValue, aec_valueSize(param));
953 }
954 
955 //-----------------------------------------------------------------------------
956 static const int AGC_PARAM_SIZE_MAX = sizeof(effect_param_t) + (2 * sizeof(int16_t)) + sizeof(bool);
957 /**
958  * returns the size in bytes of the value of each automatic gain control parameter
959  */
agc_valueSize(int32_t param)960 uint32_t agc_valueSize(int32_t param) {
961     uint32_t size;
962     switch (param) {
963     case AGC_PARAM_TARGET_LEVEL:
964     case AGC_PARAM_COMP_GAIN:
965         size = sizeof(int16_t);
966         break;
967     case AGC_PARAM_LIMITER_ENA:
968         size = sizeof(bool);
969         break;
970     default:
971         size = sizeof(int32_t);
972         SL_LOGE("Trying to access an unknown Automatic Gain Control parameter %d", param);
973         break;
974     }
975 
976     return size;
977 }
978 
android_agc_setParam(const android::sp<android::AudioEffect> & pFx,int32_t param,void * pValue)979 android::status_t android_agc_setParam(const android::sp<android::AudioEffect>& pFx,
980         int32_t param, void *pValue) {
981     return android_fx_setParam(pFx, param, AGC_PARAM_SIZE_MAX,
982             pValue, agc_valueSize(param));
983 }
984 
android_agc_getParam(const android::sp<android::AudioEffect> & pFx,int32_t param,void * pValue)985 android::status_t android_agc_getParam(const android::sp<android::AudioEffect>& pFx,
986         int32_t param, void *pValue) {
987     return android_fx_getParam(pFx, param, AGC_PARAM_SIZE_MAX,
988             pValue, agc_valueSize(param));
989 }
990 
991 //-----------------------------------------------------------------------------
992 static const int NS_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t);
993 /**
994  * returns the size in bytes of the value of each noise suppression parameter
995  */
ns_valueSize(int32_t param)996 uint32_t ns_valueSize(int32_t param) {
997     uint32_t size;
998     switch (param) {
999     case NS_PARAM_LEVEL:
1000         size = sizeof(int32_t);
1001         break;
1002     default:
1003         size = sizeof(int32_t);
1004         SL_LOGE("Trying to access an unknown Noise suppression parameter %d", param);
1005         break;
1006     }
1007 
1008     return size;
1009 }
1010 
android_ns_setParam(const android::sp<android::AudioEffect> & pFx,int32_t param,void * pValue)1011 android::status_t android_ns_setParam(const android::sp<android::AudioEffect>& pFx,
1012         int32_t param, void *pValue)
1013 {
1014     return android_fx_setParam(pFx, param, NS_PARAM_SIZE_MAX,
1015             pValue, ns_valueSize(param));
1016 }
1017 
android_ns_getParam(const android::sp<android::AudioEffect> & pFx,int32_t param,void * pValue)1018 android::status_t android_ns_getParam(const android::sp<android::AudioEffect>& pFx,
1019         int32_t param, void *pValue)
1020 {
1021     return android_fx_getParam(pFx, param, NS_PARAM_SIZE_MAX,
1022             pValue, ns_valueSize(param));
1023 }
1024