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