• Home
  • History
  • Annotate
  • 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  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