summaryrefslogtreecommitdiff
path: root/tvapi/libtv/audio/audio_android_effect.cpp (plain)
blob: e29a7111d61af1d5c31b2137cb797920322b94bc
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <fcntl.h>
5#include <malloc.h>
6#include <unistd.h>
7#include <pthread.h>
8#include <sys/stat.h>
9#include <android/log.h>
10#include <sys/prctl.h>
11
12#include "audio_android_effect.h"
13
14#define msleep(x) usleep(x*1000)
15
16#define INVALID_EQ_FORCED_GAIN (0x7FFFFFFF)
17
18#define LOG_TAG "CAndroidEffect"
19#include "CTvLog.h"
20
21using namespace android;
22
23// For some special cases, we want some band of the EQ to be forced to a specific
24// gain. When the value in this array is not invalid, the gain of the corresponding
25// band will be forced to this value.
26CAndroidEffect::CAndroidEffect()
27{
28 mplpAudioEffectSrs = NULL;
29 mplpAudioEffectEq = NULL;
30 mTrackerSessionId = 0;
31}
32
33CAndroidEffect::~CAndroidEffect()
34{
35}
36
37static void audioEffectCallback(int32_t event, void *user, void *info)
38{
39 LOGD("[%s:%d]", __FUNCTION__, __LINE__);
40}
41
42void CAndroidEffect::FreeAudioEffect(AudioEffect **pEffect)
43{
44 if ((*pEffect) != NULL) {
45 (*pEffect)->setEnabled(false);
46 delete (*pEffect);
47 (*pEffect) = NULL;
48 }
49}
50
51void CAndroidEffect::initAudioEffect(AudioEffect **pEffect,
52 const effect_uuid_t *const pEffectType,
53 const effect_uuid_t *const pEffectUuid, int sessionId)
54{
55 if (NULL != (*pEffect)) {
56 LOGE("[%s:%d] AudioEffect is not NULL. Free it first.\n", __FUNCTION__,
57 __LINE__);
58 FreeAudioEffect(pEffect);
59 }
60
61 status_t status;
62
63 (*pEffect) = new AudioEffect();
64 if (NULL == (*pEffect)) {
65 LOGE("[%s:%d] Failed to create audio effect.\n", __FUNCTION__,
66 __LINE__);
67 goto err_exit;
68 }
69
70 status = (*pEffect)->set(pEffectType, //type
71 pEffectUuid, //uuid
72 0, //priority
73 audioEffectCallback, //cbf
74 NULL, //user
75 sessionId, //sessionId
76 0 // default output device
77 );
78
79 if (NO_ERROR != status) {
80 LOGE("[%s:%d] Failed to set audio effect parameters.\n", __FUNCTION__,
81 __LINE__);
82 goto err_exit;
83 }
84
85 status = (*pEffect)->initCheck();
86 if (NO_ERROR != status) {
87 LOGE("[%s:%d] Failed to init audio effect.\n", __FUNCTION__, __LINE__);
88 goto err_exit;
89 }
90
91 status = (*pEffect)->setEnabled(true);
92 if (NO_ERROR != status) {
93 LOGE("[%s:%d] Failed to enable audio effect.\n", __FUNCTION__,
94 __LINE__);
95 goto err_exit;
96 }
97
98 return;
99
100err_exit:
101 if (NULL != (*pEffect)) {
102 delete (*pEffect);
103 (*pEffect) = NULL;
104 }
105}
106
107int CAndroidEffect::setSrsParameterInt(tshd_srs_param_t param, unsigned value)
108{
109 if (NULL == mplpAudioEffectSrs) {
110 return -1;
111 }
112
113 status_t status;
114 effect_param_t *pParam = (effect_param_t *) malloc(
115 sizeof(effect_param_t) + sizeof(unsigned) + sizeof(unsigned));
116 if (NULL == pParam) {
117 LOGE("[%s:%d]Failed to allocate memory!\n", __FUNCTION__, __LINE__);
118 return -1;
119 }
120 pParam->status = 0;
121 pParam->psize = sizeof(unsigned);
122 pParam->vsize = sizeof(unsigned);
123 *(unsigned *) (&pParam->data[0]) = (unsigned) param;
124 *(unsigned *) (&pParam->data[sizeof(unsigned)]) = value;
125 status = mplpAudioEffectSrs->setParameter(pParam);
126 if (NO_ERROR != status) {
127 LOGE("[%s:%d]Failed to set parameter:%d!\n", __FUNCTION__, __LINE__,
128 param);
129 free(pParam);
130 return -1;
131 } else {
132 free(pParam);
133 return 0;
134 }
135}
136
137int CAndroidEffect::getSrsParameterInt(tshd_srs_param_t param, unsigned *value)
138{
139 if (NULL == mplpAudioEffectSrs) {
140 return -1;
141 }
142
143 status_t status;
144 effect_param_t *pParam = (effect_param_t *) malloc(
145 sizeof(effect_param_t) + sizeof(unsigned) + sizeof(unsigned));
146 if (NULL == pParam) {
147 LOGE("[%s:%d]Failed to allocate memory!\n", __FUNCTION__, __LINE__);
148 return -1;
149 }
150 pParam->status = 0;
151 pParam->psize = sizeof(unsigned);
152 pParam->vsize = sizeof(unsigned);
153 *(unsigned *) (&pParam->data[0]) = (unsigned) param;
154 status = mplpAudioEffectSrs->getParameter(pParam);
155 if (NO_ERROR != status) {
156 LOGE("[%s:%d]Failed to get parameter:%d!\n", __FUNCTION__, __LINE__,
157 param);
158 *value = 0;
159 free(pParam);
160 return -1;
161 } else {
162 *value = *(unsigned *) (&pParam->data[sizeof(unsigned)]);
163 free(pParam);
164 return 0;
165 }
166}
167
168int CAndroidEffect::setSrsParameterFloat(tshd_srs_param_t param, float value)
169{
170 if (NULL == mplpAudioEffectSrs) {
171 return -1;
172 }
173
174 status_t status;
175 effect_param_t *pParam = (effect_param_t *) malloc(
176 sizeof(effect_param_t) + sizeof(unsigned) + sizeof(float));
177 if (NULL == pParam) {
178 LOGE("[%s:%d]Failed to allocate memory!\n", __FUNCTION__, __LINE__);
179 return -1;
180 }
181 pParam->status = 0;
182 pParam->psize = sizeof(unsigned);
183 pParam->vsize = sizeof(float);
184 *(unsigned *) (&pParam->data[0]) = (unsigned) param;
185 *(float *) (&pParam->data[sizeof(unsigned)]) = value;
186 status = mplpAudioEffectSrs->setParameter(pParam);
187 if (NO_ERROR != status) {
188 LOGE("[%s:%d]Failed to set parameter:%d!\n", __FUNCTION__, __LINE__,
189 param);
190 free(pParam);
191 return -1;
192 } else {
193 free(pParam);
194 return 0;
195 }
196}
197
198int CAndroidEffect::getSrsParameterFloat(tshd_srs_param_t param, float *value)
199{
200 if (NULL == mplpAudioEffectSrs) {
201 return -1;
202 }
203
204 status_t status;
205 effect_param_t *pParam = (effect_param_t *) malloc(
206 sizeof(effect_param_t) + sizeof(unsigned) + sizeof(float));
207 if (NULL == pParam) {
208 LOGE("[%s:%d]Failed to allocate memory!\n", __FUNCTION__, __LINE__);
209 return -1;
210 }
211 pParam->status = 0;
212 pParam->psize = sizeof(unsigned);
213 pParam->vsize = sizeof(float);
214 *(unsigned *) (&pParam->data[0]) = (unsigned) param;
215 status = mplpAudioEffectSrs->getParameter(pParam);
216 if (NO_ERROR != status) {
217 LOGE("[%s:%d]Failed to set parameter:%d!\n", __FUNCTION__, __LINE__,
218 param);
219 *value = 0.0f;
220 free(pParam);
221 return -1;
222 } else {
223 *value = *(float *) (&pParam->data[sizeof(unsigned)]);
224 free(pParam);
225 return 0;
226 }
227}
228
229int CAndroidEffect::amAndroidSetSrsParameterInt(tshd_srs_param_t param, unsigned value)
230{
231 return setSrsParameterInt(param, value);
232}
233
234int CAndroidEffect::amAndroidGetSrsParameterInt(tshd_srs_param_t param,
235 unsigned *value)
236{
237 return getSrsParameterInt(param, value);
238}
239
240int CAndroidEffect::amAndroidSetSrsParameterFloat(tshd_srs_param_t param, float value)
241{
242 return setSrsParameterFloat(param, value);
243}
244
245int CAndroidEffect::amAndroidGetSrsParameterFloat(tshd_srs_param_t param, float *value)
246{
247 return getSrsParameterFloat(param, value);
248}
249
250int CAndroidEffect::amAndroidNewSRSAudioEffect(void)
251{
252 if ((NULL == mplpAudioEffectSrs) && (GetAudioSRSModuleDisableCFG() == 0)) {
253 initAudioEffect(&mplpAudioEffectSrs, NULL, SL_IID_SRS,
254 mTrackerSessionId);
255 if (NULL == mplpAudioEffectSrs) {
256 LOGE("[%s:%d] Failed to create audio effect SRS!\n", __FUNCTION__,
257 __LINE__);
258 return -1;
259 }
260 }
261
262 return 0;
263}
264
265int CAndroidEffect::amAndroidNewEQAudioEffect(void)
266{
267 if ((NULL == mplpAudioEffectEq) && (GetAudioEqModuleDisableCFG() == 0)) {
268 if (GetAudioEqUsingAndroidCFG()) {
269 initAudioEffect(&mplpAudioEffectEq, SL_IID_EQUALIZER, NULL,
270 mTrackerSessionId);
271 } else {
272 initAudioEffect(&mplpAudioEffectEq, NULL, SL_IID_HPEQ,
273 mTrackerSessionId);
274 }
275
276 if (NULL == mplpAudioEffectEq) {
277 LOGE("[%s:%d] Failed to create audio effect EQ(android:%d)!\n",
278 __FUNCTION__, __LINE__, GetAudioEqUsingAndroidCFG());
279 return -1;
280 } else {
281 // Init all forced gains to be invalid.
282 for (int i = 0; i < EQ_BAND_COUNT; i++) {
283 gEqForcedGain[i] = INVALID_EQ_FORCED_GAIN;
284 }
285 getEqGain(gEqUserSetGain, EQ_BAND_COUNT);
286 LOGD(
287 "[%s:%d] Audio effect EQ(android:%d) was created successfully!\n",
288 __FUNCTION__, __LINE__, GetAudioEqUsingAndroidCFG());
289 }
290 }
291
292 return 0;
293}
294
295int CAndroidEffect::amAndroidNewAudioEffects(void)
296{
297 int tmp_ret = 0;
298
299 tmp_ret |= amAndroidNewSRSAudioEffect();
300 tmp_ret |= amAndroidNewEQAudioEffect();
301
302 return tmp_ret;
303}
304
305void CAndroidEffect::amAndroidFreeAudioEffects(void)
306{
307 {
308 FreeAudioEffect(&mplpAudioEffectEq);
309 FreeAudioEffect(&mplpAudioEffectSrs);
310
311 if (mTrackerSessionId != 0) {
312 AudioSystem::releaseAudioSessionId(mTrackerSessionId, -1);
313 mTrackerSessionId = 0;
314 }
315 }
316}
317
318int CAndroidEffect::amAndroidGetAudioSessionId(void)
319{
320 return mTrackerSessionId;
321}
322
323int CAndroidEffect::amAndroidSetSRSSurroundSwitch(int switch_val)
324{
325 return amAndroidSetSrsParameterInt(SRS_PARAM_SURROUND_ENABLE,
326 (unsigned) switch_val);
327}
328
329int CAndroidEffect::amAndroidSetSRSSurroundGain(int gain_val)
330{
331 return amAndroidSetSrsParameterFloat(SRS_PARAM_SURROUND_GAIN,
332 (float) gain_val / 100.0f);
333}
334
335int CAndroidEffect::amAndroidSetSRSTrubassSwitch(int switch_val)
336{
337 return amAndroidSetSrsParameterInt(SRS_PARAM_TRUEBASS_ENABLE,
338 (unsigned) switch_val);
339}
340
341int CAndroidEffect::amAndroidSetSRSTrubassGain(int gain_val)
342{
343 return amAndroidSetSrsParameterFloat(SRS_PARAM_TRUEBASS_GAIN,
344 (float) gain_val / 100.0f);
345}
346
347int CAndroidEffect::amAndroidSetSRSDialogClaritySwitch(int switch_val)
348{
349 return amAndroidSetSrsParameterInt(SRS_PARAM_DIALOGCLARITY_ENABLE,
350 (unsigned) switch_val);
351}
352
353int CAndroidEffect::amAndroidSetSRSDialogClarityGain(int gain_val)
354{
355 return amAndroidSetSrsParameterFloat(SRS_PARAM_DIALOGCLARTY_GAIN,
356 (float) gain_val / 100.0f);
357}
358
359int CAndroidEffect::amAndroidSetSRSDefinitionGain(int gain_val)
360{
361 return amAndroidSetSrsParameterFloat(SRS_PARAM_DEFINITION_GAIN,
362 (float) gain_val / 100.0f);
363}
364
365int CAndroidEffect::amAndroidSetSRSTrubassSpeakerSize(int tmp_val)
366{
367 int tmp_buf[8] = { 40, 60, 100, 150, 200, 250, 300, 400 };
368 int set_val = 40;
369
370 if (tmp_val >= 0 && tmp_val < sizeof(tmp_buf)) {
371 set_val = tmp_buf[tmp_val];
372 }
373
374 return amAndroidSetSrsParameterInt(SRS_PARAM_TRUEBASS_SPKER_SIZE, set_val);
375}
376
377int CAndroidEffect::setEqGain(const int gain_val_buf[], int band_count)
378{
379 if (NULL == mplpAudioEffectEq) {
380 LOGE("[%s:%d]\n", __FUNCTION__, __LINE__);
381 return -1;
382 }
383
384 status_t status;
385 int i;
386 int gain;
387 effect_param_t *pParam;
388 int bAndroidEq = GetAudioEqUsingAndroidCFG();
389
390 if (bAndroidEq) {
391 pParam = (effect_param_t *) malloc(
392 sizeof(effect_param_t) + sizeof(int) + sizeof(int)
393 + sizeof(short));
394 } else {
395 pParam = (effect_param_t *) malloc(
396 sizeof(effect_param_t) + sizeof(int) + sizeof(int));
397 }
398
399 if (NULL == pParam) {
400 LOGE("[%s:%d]Failed to allocate memory!\n", __FUNCTION__, __LINE__);
401 return -1;
402 }
403
404 for (i = 0; i < band_count; i++) {
405 if (gEqForcedGain[i] != INVALID_EQ_FORCED_GAIN) {
406 gain = gEqForcedGain[i];
407 } else {
408 gain = gain_val_buf[i];
409 }
410
411 if (bAndroidEq) {
412 pParam->status = 0;
413 pParam->psize = sizeof(int) * 2;
414 pParam->vsize = sizeof(short);
415 *(int *) (&pParam->data[0]) = EQ_PARAM_BAND_LEVEL;
416 *(int *) (&pParam->data[sizeof(int)]) = i;
417 *(short *) (&pParam->data[sizeof(int) * 2]) = (short) gain;
418 } else {
419 pParam->status = 0;
420 pParam->psize = sizeof(int);
421 pParam->vsize = sizeof(int);
422 *(int *) (&pParam->data[0]) = i;
423 *(int *) (&pParam->data[sizeof(int)]) = gain;
424 }
425
426 status = mplpAudioEffectEq->setParameter(pParam);
427 if (NO_ERROR != status) {
428 LOGE("[%s:%d]Failed to set parameter:%d!\n", __FUNCTION__, __LINE__,
429 i);
430 free(pParam);
431 return -1;
432 }
433 }
434
435 free(pParam);
436 return 0;
437}
438
439int CAndroidEffect::getEqGain(int gain_val_buf[], int band_count)
440{
441 if (NULL == mplpAudioEffectEq) {
442 return -1;
443 }
444
445 status_t status;
446 effect_param_t *pParam;
447 int bAndroidEq = GetAudioEqUsingAndroidCFG();
448
449 if (bAndroidEq) {
450 pParam = (effect_param_t *) malloc(
451 sizeof(effect_param_t) + sizeof(int) + sizeof(int)
452 + sizeof(short));
453 } else {
454 pParam = (effect_param_t *) malloc(
455 sizeof(effect_param_t) + sizeof(int) + sizeof(int));
456 }
457
458 if (NULL == pParam) {
459 LOGE("[%s:%d]Failed to allocate memory!\n", __FUNCTION__, __LINE__);
460 return -1;
461 }
462
463 for (int i = 0; i < EQ_BAND_COUNT; i++) {
464 if (gEqForcedGain[i] != INVALID_EQ_FORCED_GAIN) {
465 gain_val_buf[i] = gEqUserSetGain[i];
466 } else {
467 if (bAndroidEq) {
468 pParam->status = 0;
469 pParam->psize = sizeof(int) * 2;
470 pParam->vsize = sizeof(short);
471 *(int *) (&pParam->data[0]) = EQ_PARAM_BAND_LEVEL;
472 *(int *) (&pParam->data[sizeof(int)]) = i;
473 } else {
474 pParam->status = 0;
475 pParam->psize = sizeof(int);
476 pParam->vsize = sizeof(int);
477 *(int *) (&pParam->data[0]) = i;
478 }
479 status = mplpAudioEffectEq->getParameter(pParam);
480 if (NO_ERROR != status) {
481 LOGE("[%s:%d]Failed to set parameter:%d!\n", __FUNCTION__,
482 __LINE__, i);
483 free(pParam);
484 return -1;
485 }
486
487 if (bAndroidEq) {
488 gain_val_buf[i] = *(short *) (&pParam->data[sizeof(int) * 2]);
489 } else {
490 gain_val_buf[i] = *(int *) (&pParam->data[sizeof(int)]);
491 }
492 }
493 }
494
495 free(pParam);
496 return 0;
497}
498
499int CAndroidEffect::amAndroidSetEQGain(const int gain_val_buf[], int band_count)
500{
501 int i;
502 int gain_factor = 1;
503
504 if (band_count > EQ_BAND_COUNT) {
505 band_count = EQ_BAND_COUNT;
506 }
507
508 // convert dB to 100th dB for android EQ
509 if (GetAudioEqUsingAndroidCFG()) {
510 gain_factor = 100;
511 }
512
513 // store the gains set by the user, and convert it to the internal representation.
514 for (i = 0; i < band_count; i++) {
515 gEqUserSetGain[i] = gain_val_buf[i] * gain_factor;
516 }
517
518 return setEqGain(gEqUserSetGain, band_count);
519}
520
521int CAndroidEffect::amAndroidGetEQGain(int gain_val_buf[], int band_count)
522{
523 int i;
524 int ret;
525
526 if (band_count > EQ_BAND_COUNT) {
527 band_count = EQ_BAND_COUNT;
528 }
529
530 ret = getEqGain(gain_val_buf, band_count);
531
532 // convert 100th dB to dB for android EQ
533 if (GetAudioEqUsingAndroidCFG()) {
534 for (i = 0; i < band_count; i++) {
535 gain_val_buf[i] /= 100;
536 }
537 }
538
539 return ret;
540}
541
542int CAndroidEffect::amAndroidSetEQEnable(int enabled)
543{
544 if (NULL == mplpAudioEffectEq) {
545 return -1;
546 }
547
548 if (NO_ERROR != mplpAudioEffectEq->setEnabled(enabled)) {
549 return -1;
550 } else {
551 return 0;
552 }
553}
554
555int CAndroidEffect::amAndroidGetEQEnabled()
556{
557 if (NULL == mplpAudioEffectEq) {
558 return 0;
559 }
560
561 if (mplpAudioEffectEq->getEnabled()) {
562 return 1;
563 } else {
564 return 0;
565 }
566}
567
568int CAndroidEffect::amAndroidForceEQGain(int band, int gain)
569{
570 if (band >= EQ_BAND_COUNT) {
571 LOGE("[%s:%d] band(%d) is out of bound!\n", __FUNCTION__, __LINE__,
572 band);
573 return -1;
574 } else {
575 if (GetAudioEqUsingAndroidCFG() && (gain != INVALID_EQ_FORCED_GAIN)) {
576 gEqForcedGain[band] = gain * 100;
577 } else {
578 gEqForcedGain[band] = gain;
579 }
580
581 // reset the EQ bands to take effect of the forced one.
582 if (setEqGain(gEqUserSetGain, EQ_BAND_COUNT) != 0) {
583 LOGE("[%s:%d]Failed to reset EQ gain!\n", __FUNCTION__, __LINE__);
584 return -1;
585 }
586
587 LOGD("[%s:%d] band(%d) is forced to %d!\n", __FUNCTION__, __LINE__,
588 band, gain);
589 return 0;
590 }
591}
592