• 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 is it has a effective 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 //-----------------------------------------------------------------------------
android_fxSend_attach(CAudioPlayer * ap,bool attach,android::sp<android::AudioEffect> pFx,SLmillibel sendLevel)445 android::status_t android_fxSend_attach(CAudioPlayer* ap, bool attach,
446         android::sp<android::AudioEffect> pFx, SLmillibel sendLevel) {
447 
448     if (pFx == 0) {
449         return android::INVALID_OPERATION;
450     }
451 
452     // There are 3 cases:
453     //  mAPlayer != 0 && mAudioTrack == 0 means playing decoded audio
454     //  mAPlayer == 0 && mAudioTrack != 0 means playing PCM audio
455     //  mAPlayer == 0 && mAudioTrack == 0 means player not fully configured yet
456     // The asserts document and verify this.
457     if (ap->mAPlayer != 0) {
458         assert(ap->mAudioTrack == 0);
459         if (attach) {
460             ap->mAPlayer->attachAuxEffect(pFx->id());
461             ap->mAPlayer->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
462         } else {
463             ap->mAPlayer->attachAuxEffect(0);
464         }
465         return android::NO_ERROR;
466     }
467 
468     if (ap->mAudioTrack == 0) {
469         // the player doesn't have an AudioTrack at the moment, so store this info to use it
470         // when the AudioTrack becomes available
471         if (attach) {
472             ap->mAuxEffect = pFx;
473         } else {
474             ap->mAuxEffect.clear();
475         }
476         // we keep track of the send level, independently of the current audio player level
477         ap->mAuxSendLevel = sendLevel - ap->mVolume.mLevel;
478         return android::NO_ERROR;
479     }
480 
481     if (attach) {
482         android::status_t status = ap->mAudioTrack->attachAuxEffect(pFx->id());
483         //SL_LOGV("attachAuxEffect(%d) returned %d", pFx->id(), status);
484         if (android::NO_ERROR == status) {
485             status =
486                 ap->mAudioTrack->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
487         }
488         return status;
489     } else {
490         return ap->mAudioTrack->attachAuxEffect(0);
491     }
492 }
493 
494 //-----------------------------------------------------------------------------
495 /**
496  * pre-condition:
497  *    ap != NULL
498  *    ap->mOutputMix != NULL
499  */
android_fxSend_attachToAux(CAudioPlayer * ap,SLInterfaceID pUuid,SLboolean attach,SLmillibel sendLevel)500 SLresult android_fxSend_attachToAux(CAudioPlayer* ap, SLInterfaceID pUuid, SLboolean attach,
501         SLmillibel sendLevel) {
502     COutputMix *outputMix = CAudioPlayer_GetOutputMix(ap);
503     ssize_t index = outputMix->mAndroidEffect.mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
504 
505     if (0 > index) {
506         SL_LOGE("invalid effect ID: no such effect attached to the OutputMix");
507         return SL_RESULT_PARAMETER_INVALID;
508     }
509 
510     android::AudioEffect* pFx = outputMix->mAndroidEffect.mEffects->valueAt(index);
511     if (NULL == pFx) {
512         return SL_RESULT_RESOURCE_ERROR;
513     }
514     if (android::NO_ERROR == android_fxSend_attach( ap, (bool) attach, pFx, sendLevel) ) {
515         return SL_RESULT_SUCCESS;
516     } else {
517         return SL_RESULT_RESOURCE_ERROR;
518     }
519 
520 }
521 
522 //-----------------------------------------------------------------------------
android_fxSend_setSendLevel(CAudioPlayer * ap,SLmillibel sendLevel)523 android::status_t android_fxSend_setSendLevel(CAudioPlayer* ap, SLmillibel sendLevel) {
524     // we keep track of the send level, independently of the current audio player level
525     ap->mAuxSendLevel = sendLevel - ap->mVolume.mLevel;
526 
527     if (ap->mAPlayer != 0) {
528         assert(ap->mAudioTrack == 0);
529         ap->mAPlayer->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
530         return android::NO_ERROR;
531     }
532 
533     if (ap->mAudioTrack == 0) {
534         return android::NO_ERROR;
535     }
536 
537     return ap->mAudioTrack->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) );
538 }
539 
540 //-----------------------------------------------------------------------------
android_fx_setParam(android::sp<android::AudioEffect> pFx,int32_t param,uint32_t paramSizeMax,void * pValue,uint32_t valueSize)541 android::status_t android_fx_setParam(android::sp<android::AudioEffect> pFx,
542         int32_t param, uint32_t paramSizeMax, void *pValue, uint32_t valueSize)
543 {
544 
545     android::status_t status;
546     uint32_t buf32[(paramSizeMax - 1) / sizeof(uint32_t) + 1];
547     effect_param_t *p = (effect_param_t *)buf32;
548 
549     p->psize = sizeof(int32_t);
550     *(int32_t *)p->data = param;
551     p->vsize = valueSize;
552     memcpy(p->data + p->psize, pValue, p->vsize);
553     status = pFx->setParameter(p);
554     if (android::NO_ERROR == status) {
555         status = p->status;
556     }
557     return status;
558 }
559 
560 
561 //-----------------------------------------------------------------------------
android_fx_getParam(android::sp<android::AudioEffect> pFx,int32_t param,uint32_t paramSizeMax,void * pValue,uint32_t valueSize)562 android::status_t android_fx_getParam(android::sp<android::AudioEffect> pFx,
563         int32_t param, uint32_t paramSizeMax, void *pValue, uint32_t valueSize)
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     status = pFx->getParameter(p);
573     if (android::NO_ERROR == status) {
574         status = p->status;
575         if (android::NO_ERROR == status) {
576             memcpy(pValue, p->data + p->psize, p->vsize);
577         }
578     }
579 
580     return status;
581 }
582 
583 
584 //-----------------------------------------------------------------------------
android_fx_statusToResult(android::status_t status)585 SLresult android_fx_statusToResult(android::status_t status) {
586 
587     if ((android::INVALID_OPERATION == status) || (android::DEAD_OBJECT == status)) {
588         return SL_RESULT_CONTROL_LOST;
589     } else {
590         return SL_RESULT_SUCCESS;
591     }
592 }
593 
594 
595 //-----------------------------------------------------------------------------
android_fx_initEffectObj(int sessionId,android::sp<android::AudioEffect> & effect,const effect_uuid_t * type)596 bool android_fx_initEffectObj(int sessionId, android::sp<android::AudioEffect>& effect,
597         const effect_uuid_t *type) {
598     //SL_LOGV("android_fx_initEffectObj on session %d", sessionId);
599 
600     effect = new android::AudioEffect(type, EFFECT_UUID_NULL,
601             0,// priority
602             0,// effect callback
603             0,// callback data
604             sessionId,// session ID
605             0 );// output
606 
607     android::status_t status = effect->initCheck();
608     if (android::NO_ERROR != status) {
609         effect.clear();
610         SL_LOGE("Effect initCheck() returned %d", status);
611         return false;
612     }
613 
614     return true;
615 }
616 
617 
618 //-----------------------------------------------------------------------------
android_fx_initEffectDescriptor(const SLInterfaceID effectId,effect_descriptor_t * fxDescrLoc)619 bool android_fx_initEffectDescriptor(const SLInterfaceID effectId,
620         effect_descriptor_t* fxDescrLoc) {
621     uint32_t numEffects = 0;
622     effect_descriptor_t descriptor;
623     bool foundEffect = false;
624 
625     // any effects?
626     android::status_t res = android::AudioEffect::queryNumberEffects(&numEffects);
627     if (android::NO_ERROR != res) {
628         SL_LOGE("unable to find any effects.");
629         goto effectError;
630     }
631 
632     // request effect in the effects?
633     for (uint32_t i=0 ; i < numEffects ; i++) {
634         res = android::AudioEffect::queryEffect(i, &descriptor);
635         if ((android::NO_ERROR == res) &&
636                 (0 == memcmp(effectId, &descriptor.type, sizeof(effect_uuid_t)))) {
637             SL_LOGV("found effect %d %s", i, descriptor.name);
638             foundEffect = true;
639             break;
640         }
641     }
642     if (foundEffect) {
643         memcpy(fxDescrLoc, &descriptor, sizeof(effect_descriptor_t));
644     } else {
645         SL_LOGE("unable to find an implementation for the requested effect.");
646         goto effectError;
647     }
648 
649     return true;
650 
651 effectError:
652     // the requested effect wasn't found
653     memset(fxDescrLoc, 0, sizeof(effect_descriptor_t));
654 
655     return false;
656 }
657 
658 //-----------------------------------------------------------------------------
android_genericFx_queryNumEffects(SLuint32 * pNumSupportedAudioEffects)659 SLresult android_genericFx_queryNumEffects(SLuint32 *pNumSupportedAudioEffects) {
660 
661     if (NULL == pNumSupportedAudioEffects) {
662         return SL_RESULT_PARAMETER_INVALID;
663     }
664 
665     android::status_t status =
666             android::AudioEffect::queryNumberEffects((uint32_t*)pNumSupportedAudioEffects);
667 
668     SLresult result = SL_RESULT_SUCCESS;
669     switch(status) {
670         case android::NO_ERROR:
671             result = SL_RESULT_SUCCESS;
672             break;
673         case android::PERMISSION_DENIED:
674             result = SL_RESULT_PERMISSION_DENIED;
675             break;
676         case android::NO_INIT:
677             result = SL_RESULT_RESOURCE_ERROR;
678             break;
679         case android::BAD_VALUE:
680             result = SL_RESULT_PARAMETER_INVALID;
681             break;
682         default:
683             result = SL_RESULT_INTERNAL_ERROR;
684             SL_LOGE("received invalid status %d from AudioEffect::queryNumberEffects()", status);
685             break;
686     }
687     return result;
688 }
689 
690 
691 //-----------------------------------------------------------------------------
android_genericFx_queryEffect(SLuint32 index,effect_descriptor_t * pDescriptor)692 SLresult android_genericFx_queryEffect(SLuint32 index, effect_descriptor_t* pDescriptor) {
693 
694     if (NULL == pDescriptor) {
695         return SL_RESULT_PARAMETER_INVALID;
696     }
697 
698     android::status_t status =
699                 android::AudioEffect::queryEffect(index, pDescriptor);
700 
701     SLresult result = SL_RESULT_SUCCESS;
702     if (android::NO_ERROR != status) {
703         switch(status) {
704         case android::PERMISSION_DENIED:
705             result = SL_RESULT_PERMISSION_DENIED;
706             break;
707         case android::NO_INIT:
708         case android::INVALID_OPERATION:
709             result = SL_RESULT_RESOURCE_ERROR;
710             break;
711         case android::BAD_VALUE:
712             result = SL_RESULT_PARAMETER_INVALID;
713             break;
714         default:
715             result = SL_RESULT_INTERNAL_ERROR;
716             SL_LOGE("received invalid status %d from AudioEffect::queryNumberEffects()", status);
717             break;
718         }
719         // an error occurred, reset the effect descriptor
720         memset(pDescriptor, 0, sizeof(effect_descriptor_t));
721     }
722 
723     return result;
724 }
725 
726 
727 //-----------------------------------------------------------------------------
android_genericFx_createEffect(IAndroidEffect * iae,SLInterfaceID pUuid,int sessionId)728 SLresult android_genericFx_createEffect(IAndroidEffect* iae, SLInterfaceID pUuid, int sessionId) {
729 
730     SLresult result = SL_RESULT_SUCCESS;
731 
732     // does this effect already exist?
733     if (0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid))) {
734         return result;
735     }
736 
737     // create new effect
738     android::AudioEffect* pFx = new android::AudioEffect(
739             NULL, // not using type to create effect
740             (const effect_uuid_t*)pUuid,
741             0,// priority
742             0,// effect callback
743             0,// callback data
744             sessionId,
745             0 );// output
746 
747     // verify effect was successfully created before storing it
748     android::status_t status = pFx->initCheck();
749     if (android::NO_ERROR != status) {
750         SL_LOGE("AudioEffect initCheck() returned %d, effect will not be stored", status);
751         delete pFx;
752         result = SL_RESULT_RESOURCE_ERROR;
753     } else {
754         SL_LOGV("AudioEffect successfully created on session %d", sessionId);
755         iae->mEffects->add(KEY_FROM_GUID(pUuid), pFx);
756     }
757 
758     return result;
759 }
760 
761 
762 //-----------------------------------------------------------------------------
android_genericFx_releaseEffect(IAndroidEffect * iae,SLInterfaceID pUuid)763 SLresult android_genericFx_releaseEffect(IAndroidEffect* iae, SLInterfaceID pUuid) {
764 
765     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
766 
767     if (0 > index) {
768         return SL_RESULT_PARAMETER_INVALID;
769     } else {
770         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
771         delete pFx;
772         iae->mEffects->removeItem(index);
773         return SL_RESULT_SUCCESS;
774     }
775 }
776 
777 
778 //-----------------------------------------------------------------------------
android_genericFx_setEnabled(IAndroidEffect * iae,SLInterfaceID pUuid,SLboolean enabled)779 SLresult android_genericFx_setEnabled(IAndroidEffect* iae, SLInterfaceID pUuid, SLboolean enabled) {
780 
781     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
782 
783     if (0 > index) {
784         return SL_RESULT_PARAMETER_INVALID;
785     } else {
786         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
787         android::status_t status = pFx->setEnabled(SL_BOOLEAN_TRUE == enabled);
788         return android_fx_statusToResult(status);
789     }
790 }
791 
792 
793 //-----------------------------------------------------------------------------
android_genericFx_isEnabled(IAndroidEffect * iae,SLInterfaceID pUuid,SLboolean * pEnabled)794 SLresult android_genericFx_isEnabled(IAndroidEffect* iae, SLInterfaceID pUuid, SLboolean *pEnabled)
795 {
796     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
797 
798     if (0 > index) {
799         return SL_RESULT_PARAMETER_INVALID;
800     } else {
801         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
802         *pEnabled = (SLboolean) pFx->getEnabled();
803         return SL_RESULT_SUCCESS;
804     }
805 }
806 
807 
808 //-----------------------------------------------------------------------------
android_genericFx_sendCommand(IAndroidEffect * iae,SLInterfaceID pUuid,SLuint32 command,SLuint32 commandSize,void * pCommandData,SLuint32 * replySize,void * pReplyData)809 SLresult android_genericFx_sendCommand(IAndroidEffect* iae, SLInterfaceID pUuid,
810         SLuint32 command, SLuint32 commandSize, void* pCommandData,
811         SLuint32 *replySize, void *pReplyData) {
812 
813     ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid));
814 
815     if (0 > index) {
816         return SL_RESULT_PARAMETER_INVALID;
817     } else {
818         android::AudioEffect* pFx = iae->mEffects->valueAt(index);
819         android::status_t status = pFx->command(
820                 (uint32_t) command,
821                 (uint32_t) commandSize,
822                 pCommandData,
823                 (uint32_t*)replySize,
824                 pReplyData);
825         if (android::BAD_VALUE == status) {
826                 return SL_RESULT_PARAMETER_INVALID;
827         } else {
828             return SL_RESULT_SUCCESS;
829         }
830     }
831 }
832 
833 //-----------------------------------------------------------------------------
834 /**
835  * returns true if the given effect id is present in the AndroidEffect interface
836  */
android_genericFx_hasEffect(IAndroidEffect * iae,SLInterfaceID pUuid)837 bool android_genericFx_hasEffect(IAndroidEffect* iae, SLInterfaceID pUuid) {
838     return( 0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid)));
839 }
840