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