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