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