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