755 lines
21 KiB
C
755 lines
21 KiB
C
#include "audio_digital_vol.h"
|
||
|
||
|
||
#define DIGITAL_FADE_EN 1
|
||
#define DIGITAL_FADE_STEP 4
|
||
|
||
#define BG_DVOL_MAX 14
|
||
#define BG_DVOL_MID 10
|
||
#define BG_DVOL_MIN 6
|
||
#define BG_DVOL_MAX_FADE 5 /*>= BG_DVOL_MAX:自动淡出BG_DVOL_MAX_FADE*/
|
||
#define BG_DVOL_MID_FADE 3 /*>= BG_DVOL_MID:自动淡出BG_DVOL_MID_FADE*/
|
||
#define BG_DVOL_MIN_FADE 1 /*>= BG_DVOL_MIN:自动淡出BG_DVOL_MIN_FADE*/
|
||
|
||
#define ASM_ENABLE 1
|
||
#define L_sat(b,a) __asm__ volatile("%0=sat16(%1)(s)":"=&r"(b) : "r"(a));
|
||
#define L_sat32(b,a,n) __asm__ volatile("%0=%1>>%2(s)":"=&r"(b) : "r"(a),"r"(n));
|
||
|
||
typedef struct {
|
||
u8 bg_dvol_fade_out;
|
||
struct list_head dvol_head;
|
||
} dvol_t;
|
||
static dvol_t dvol_attr;
|
||
|
||
//static struct digital_volume d_volume;
|
||
/*
|
||
*数字音量级数 DIGITAL_VOL_MAX
|
||
*数组长度 DIGITAL_VOL_MAX + 1
|
||
*/
|
||
#define DIGITAL_VOL_MAX 31
|
||
const u16 dig_vol_table[DIGITAL_VOL_MAX + 1] = {
|
||
0 , //0
|
||
93 , //1
|
||
111 , //2
|
||
132 , //3
|
||
158 , //4
|
||
189 , //5
|
||
226 , //6
|
||
270 , //7
|
||
323 , //8
|
||
386 , //9
|
||
462 , //10
|
||
552 , //11
|
||
660 , //12
|
||
789 , //13
|
||
943 , //14
|
||
1127, //15
|
||
1347, //16
|
||
1610, //17
|
||
1925, //18
|
||
2301, //19
|
||
2751, //20
|
||
3288, //21
|
||
3930, //22
|
||
4698, //23
|
||
5616, //24
|
||
6713, //25
|
||
8025, //26
|
||
9592, //27
|
||
11466,//28
|
||
15200,//29
|
||
16000,//30
|
||
16384 //31
|
||
};
|
||
|
||
int audio_digital_vol_init(void)
|
||
{
|
||
INIT_LIST_HEAD(&dvol_attr.dvol_head);
|
||
return 0;
|
||
}
|
||
|
||
/*背景音乐淡出使能*/
|
||
void audio_digital_vol_bg_fade(u8 fade_out)
|
||
{
|
||
printf("audio_digital_vol_bg_fade:%d", fade_out);
|
||
dvol_attr.bg_dvol_fade_out = fade_out;
|
||
}
|
||
|
||
/*
|
||
*fade_step一般不超过两级数字音量的最小差值
|
||
*(1)通话如果用数字音量,一般步进小一点,音量调节的时候不会有杂音
|
||
*(2)淡出的时候可以快一点,尽快淡出到0
|
||
*/
|
||
dvol_handle *audio_digital_vol_open(u8 vol, u8 vol_max, u16 fade_step)
|
||
{
|
||
dvol_handle *dvol = NULL;
|
||
dvol = zalloc(sizeof(dvol_handle));
|
||
if (dvol) {
|
||
u8 vol_level;
|
||
dvol->fade = DIGITAL_FADE_EN;
|
||
dvol->vol = (vol > vol_max) ? vol_max : vol;
|
||
if (vol > vol_max) {
|
||
printf("[warning]cur digital_vol(%d) > digital_vol_max(%d)!!", vol, vol_max);
|
||
}
|
||
dvol->vol_max = vol_max;
|
||
vol_level = dvol->vol * DIGITAL_VOL_MAX / vol_max;
|
||
dvol->vol_target = dig_vol_table[vol_level];
|
||
dvol->vol_fade = dvol->vol_target;
|
||
dvol->fade_step = fade_step;
|
||
dvol->toggle = 1;
|
||
#if BG_DVOL_FADE_ENABLE
|
||
dvol->vol_bk = -1;
|
||
local_irq_disable();
|
||
list_add(&dvol->entry, &dvol_attr.dvol_head);
|
||
if (dvol_attr.bg_dvol_fade_out) {
|
||
dvol_handle *hdl;
|
||
list_for_each_entry(hdl, &dvol_attr.dvol_head, entry) {
|
||
if (hdl != dvol) {
|
||
hdl->vol_bk = hdl->vol;
|
||
if (hdl->vol >= BG_DVOL_MAX) {
|
||
hdl->vol -= BG_DVOL_MAX_FADE;
|
||
} else if (hdl->vol >= BG_DVOL_MID) {
|
||
hdl->vol -= BG_DVOL_MID_FADE;
|
||
} else if (hdl->vol >= BG_DVOL_MIN) {
|
||
hdl->vol -= BG_DVOL_MIN_FADE;
|
||
} else {
|
||
hdl->vol_bk = -1;
|
||
continue;
|
||
}
|
||
u8 vol_level = hdl->vol * DIGITAL_VOL_MAX / hdl->vol_max;
|
||
hdl->vol_target = dig_vol_table[vol_level];
|
||
//y_printf("bg_dvol fade_out:%x,vol_bk:%d,vol_set:%d,tartget:%d",hdl,hdl->vol_bk,hdl->vol,hdl->vol_target);
|
||
}
|
||
}
|
||
}
|
||
local_irq_enable();
|
||
#endif
|
||
printf("digital_vol_open:%x-%d-%d-%d\n", dvol, dvol->vol, dvol->vol_max, fade_step);
|
||
}
|
||
return dvol;
|
||
}
|
||
|
||
void audio_digital_vol_close(dvol_handle *dvol)
|
||
{
|
||
printf("digital_vol_close:%x\n", dvol);
|
||
if (dvol) {
|
||
#if BG_DVOL_FADE_ENABLE
|
||
local_irq_disable();
|
||
list_del(&dvol->entry);
|
||
dvol_handle *hdl;
|
||
list_for_each_entry(hdl, &dvol_attr.dvol_head, entry) {
|
||
if ((hdl != dvol) && (hdl->vol_bk >= 0)) {
|
||
//y_printf("bg_dvol fade_in:%x,%d",hdl,hdl->vol_bk);
|
||
hdl->vol = hdl->vol_bk;
|
||
u8 vol_level = hdl->vol_bk * DIGITAL_VOL_MAX / hdl->vol_max;
|
||
hdl->vol_target = dig_vol_table[vol_level];
|
||
hdl->vol_bk = -1;
|
||
}
|
||
}
|
||
local_irq_enable();
|
||
#endif
|
||
free(dvol);
|
||
dvol = NULL;
|
||
}
|
||
}
|
||
|
||
/* u8 audio_digital_vol_get(void)
|
||
{
|
||
return d_volume.vol;
|
||
} */
|
||
|
||
void audio_digital_vol_set(dvol_handle *dvol, u8 vol)
|
||
{
|
||
if (dvol == NULL) {
|
||
return;
|
||
}
|
||
if (dvol->toggle == 0) {
|
||
return;
|
||
}
|
||
dvol->vol = (vol > dvol->vol_max) ? dvol->vol_max : vol;
|
||
#if BG_DVOL_FADE_ENABLE
|
||
if (dvol->vol_bk != -1) {
|
||
dvol->vol_bk = vol;
|
||
}
|
||
#endif
|
||
dvol->fade = DIGITAL_FADE_EN;
|
||
u8 vol_level = dvol->vol * DIGITAL_VOL_MAX / dvol->vol_max;
|
||
dvol->vol_target = dig_vol_table[vol_level];
|
||
printf("digital_vol:%d-%d-%d-%d\n", vol, vol_level, dvol->vol_fade, dvol->vol_target);
|
||
}
|
||
|
||
void audio_digital_vol_reset_fade(dvol_handle *dvol)
|
||
{
|
||
if (dvol) {
|
||
dvol->vol_fade = 0;
|
||
}
|
||
}
|
||
|
||
int audio_digital_vol_run(dvol_handle *dvol, void *data, u32 len)
|
||
{
|
||
s32 valuetemp;
|
||
s16 *buf;
|
||
|
||
if (dvol->toggle == 0) {
|
||
return -1;
|
||
}
|
||
|
||
buf = data;
|
||
len >>= 1; //byte to point
|
||
|
||
for (u32 i = 0; i < len; i += 2) {
|
||
///left channel
|
||
if (dvol->fade) {
|
||
if (dvol->vol_fade > dvol->vol_target) {
|
||
dvol->vol_fade -= dvol->fade_step;
|
||
if (dvol->vol_fade < dvol->vol_target) {
|
||
dvol->vol_fade = dvol->vol_target;
|
||
}
|
||
} else if (dvol->vol_fade < dvol->vol_target) {
|
||
dvol->vol_fade += dvol->fade_step;
|
||
if (dvol->vol_fade > dvol->vol_target) {
|
||
dvol->vol_fade = dvol->vol_target;
|
||
}
|
||
}
|
||
} else {
|
||
dvol->vol_fade = dvol->vol_target;
|
||
}
|
||
|
||
valuetemp = buf[i];
|
||
if (valuetemp < 0) {
|
||
valuetemp = -valuetemp;
|
||
valuetemp = (valuetemp * dvol->vol_fade) >> 14 ;
|
||
valuetemp = -valuetemp;
|
||
} else {
|
||
valuetemp = (valuetemp * dvol->vol_fade) >> 14 ;
|
||
}
|
||
if (valuetemp < -32768) {
|
||
valuetemp = -32768;
|
||
} else if (valuetemp > 32767) {
|
||
valuetemp = 32767;
|
||
}
|
||
buf[i] = (s16)valuetemp;
|
||
|
||
///right channel
|
||
valuetemp = buf[i + 1];
|
||
if (valuetemp < 0) {
|
||
valuetemp = -valuetemp;
|
||
valuetemp = (valuetemp * dvol->vol_fade) >> 14 ;
|
||
valuetemp = -valuetemp;
|
||
} else {
|
||
valuetemp = (valuetemp * dvol->vol_fade) >> 14 ;
|
||
}
|
||
if (valuetemp < -32768) {
|
||
valuetemp = -32768;
|
||
} else if (valuetemp > 32767) {
|
||
valuetemp = 32767;
|
||
}
|
||
buf[i + 1] = (s16)valuetemp;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
/*************************支持重入的数字音量调节****************************/
|
||
|
||
|
||
|
||
/*
|
||
*fade_step一般不超过两级数字音量的最小差值
|
||
*(1)通话如果用数字音量,一般步进小一点,音量调节的时候不会有杂音
|
||
*(2)淡出的时候可以快一点,尽快淡出到0
|
||
*/
|
||
void *user_audio_digital_volume_open(u8 vol, u8 vol_max, u16 fade_step)
|
||
{
|
||
struct digital_volume *d_volume = zalloc(sizeof(struct digital_volume));
|
||
if (!d_volume) {
|
||
log_e("d_volume NULL\n");
|
||
return NULL;
|
||
}
|
||
u8 vol_level;
|
||
d_volume->fade = 0;
|
||
d_volume->vol = vol;
|
||
d_volume->vol_max = vol_max;
|
||
vol_level = vol * DIGITAL_VOL_MAX / vol_max;
|
||
d_volume->vol_target = dig_vol_table[vol_level];
|
||
//d_volume->vol_fade = 0;//d_volume->vol_target;//打开时,从0开始淡入
|
||
d_volume->vol_fade = d_volume->vol_target;
|
||
d_volume->fade_step = fade_step;
|
||
d_volume->toggle = 1;
|
||
d_volume->ch_num = 2;//默认双声道
|
||
d_volume->user_vol_tab = NULL;
|
||
d_volume->user_vol_max = 0;
|
||
|
||
os_mutex_create(&d_volume->mutex);
|
||
printf("digital_vol_open:%d-%d-%d\n", vol, vol_max, fade_step);
|
||
return d_volume;
|
||
}
|
||
|
||
int user_audio_digital_volume_close(void *_d_volume)
|
||
{
|
||
struct digital_volume *d_volume = (struct digital_volume *)_d_volume;
|
||
if (!d_volume) {
|
||
log_e("d_volume NULL\n");
|
||
return -1;
|
||
}
|
||
/* os_mutex_pend(&d_volume->mutex, 0); */
|
||
d_volume->toggle = 0;
|
||
d_volume->user_vol_tab = NULL;
|
||
d_volume->user_vol_max = 0;
|
||
|
||
if (d_volume) {
|
||
free(d_volume);
|
||
d_volume = NULL;
|
||
}
|
||
/* os_mutex_post(&d_volume->mutex); */
|
||
printf("digital_vol_close\n");
|
||
return 0;
|
||
}
|
||
|
||
u8 user_audio_digital_volume_get(void *_d_volume)
|
||
{
|
||
struct digital_volume *d_volume = (struct digital_volume *)_d_volume;
|
||
if (!d_volume) {
|
||
log_e("d_volume NULL\n");
|
||
return 0;
|
||
}
|
||
/* os_mutex_pend(&d_volume->mutex, 0); */
|
||
u8 vol = d_volume->vol;
|
||
/* os_mutex_post(&d_volume->mutex); */
|
||
return vol;
|
||
}
|
||
|
||
int user_audio_digital_volume_set(void *_d_volume, u8 vol)
|
||
{
|
||
struct digital_volume *d_volume = (struct digital_volume *)_d_volume;
|
||
if (!d_volume) {
|
||
log_e("d_volume NULL\n");
|
||
return -1;
|
||
}
|
||
|
||
u8 vol_level;
|
||
if (d_volume->toggle == 0) {
|
||
return 0;
|
||
}
|
||
/* os_mutex_pend(&d_volume->mutex, 0); */
|
||
d_volume->vol = vol;
|
||
d_volume->fade = DIGITAL_FADE_EN;
|
||
if (!d_volume->user_vol_tab) {
|
||
vol_level = d_volume->vol * DIGITAL_VOL_MAX / d_volume->vol_max;
|
||
d_volume->vol_target = dig_vol_table[vol_level];
|
||
} else {
|
||
u8 d_vol_max = d_volume->user_vol_max - 1;
|
||
vol_level = d_volume->vol * d_vol_max / d_volume->vol_max;
|
||
d_volume->vol_target = d_volume->user_vol_tab[vol_level];
|
||
}
|
||
|
||
/* os_mutex_post(&d_volume->mutex); */
|
||
/* printf("digital_vol:%d-%d-%d-%d\n", vol, vol_level, d_volume->vol_fade, d_volume->vol_target); */
|
||
return 0;
|
||
}
|
||
|
||
int user_audio_digital_volume_reset_fade(void *_d_volume)
|
||
{
|
||
struct digital_volume *d_volume = (struct digital_volume *)_d_volume;
|
||
if (!d_volume) {
|
||
log_e("d_volume NULL\n");
|
||
return -1;
|
||
}
|
||
|
||
os_mutex_pend(&d_volume->mutex, 0);
|
||
d_volume->vol_fade = 0;
|
||
os_mutex_post(&d_volume->mutex);
|
||
return 0;
|
||
}
|
||
|
||
#if ASM_ENABLE
|
||
|
||
#define audio_vol_mix(data,len, ch_num,volumeNOW,volumeDest,step){ \
|
||
int i, j; \
|
||
int fade = 0; \
|
||
if (volumeNOW != volumeDest) \
|
||
{ \
|
||
fade = 1; \
|
||
} \
|
||
if(d_volume->fade == 0)\
|
||
{\
|
||
fade = 0;\
|
||
d_volume->vol_fade = d_volume->vol_target;\
|
||
}\
|
||
if (ch_num == 2) \
|
||
{ \
|
||
len = len >> 1; \
|
||
} \
|
||
else if (ch_num == 3) \
|
||
{ \
|
||
len = (len*5462)>>14; /*等效除3,因为5462向上取整得到的*/\
|
||
} \
|
||
else if(ch_num == 4) \
|
||
{ \
|
||
len = len >> 2; \
|
||
} \
|
||
if (fade) \
|
||
{ \
|
||
short *in_ptr = data; \
|
||
for (i = 0; i < len; i++) \
|
||
{ \
|
||
if (volumeNOW < volumeDest) \
|
||
{ \
|
||
volumeNOW = volumeNOW + step; \
|
||
if (volumeNOW > volumeDest) \
|
||
{ \
|
||
volumeNOW = volumeDest; \
|
||
} \
|
||
} \
|
||
else if (volumeNOW > volumeDest) \
|
||
{ \
|
||
volumeNOW = volumeNOW - step; \
|
||
if (volumeNOW < volumeDest) \
|
||
{ \
|
||
volumeNOW = volumeDest; \
|
||
} \
|
||
} \
|
||
{ \
|
||
int tmp; \
|
||
int reptime = ch_num; \
|
||
__asm__ volatile( \
|
||
" 1 : \n\t" \
|
||
" rep %0 { \n\t" \
|
||
" %1 = h[%2](s) \n\t" \
|
||
" %1 =%1* %3 \n\t "\
|
||
" %1 =%1 >>>14 \n\t"\
|
||
" h[%2++=2]= %1 \n\t"\
|
||
" }\n\t" \
|
||
" if(%0!=0 )goto 1b \n\t" \
|
||
: "=&r"(reptime), \
|
||
"=&r"(tmp), \
|
||
"=&r"(in_ptr) \
|
||
:"r"(volumeNOW), \
|
||
"0"(reptime),\
|
||
"2"(in_ptr)\
|
||
: "cc", "memory"); \
|
||
} \
|
||
} \
|
||
} \
|
||
else \
|
||
{ \
|
||
for (i = 0; i < ch_num; i++) \
|
||
{ \
|
||
short *in_ptr = &data[i]; \
|
||
{ \
|
||
int tmp; \
|
||
int chnumv=ch_num*2;\
|
||
int reptime = len;\
|
||
__asm__ volatile(\
|
||
" 1 : \n\t"\
|
||
" rep %0 { \n\t"\
|
||
" %1 = h[%2](s) \n\t"\
|
||
" %1 = %1 *%3 \n\t "\
|
||
" %1= %1 >>>14 \n\t"\
|
||
" h[%2++=%4]= %1 \n\t"\
|
||
" }\n\t"\
|
||
" if(%0!=0 )goto 1b \n\t"\
|
||
: "=&r"(reptime),\
|
||
"=&r"(tmp),\
|
||
"=&r"(in_ptr) \
|
||
:"r"(volumeNOW), \
|
||
"r"(chnumv),\
|
||
"0"(reptime),\
|
||
"2"(in_ptr)\
|
||
: "cc", "memory");\
|
||
} \
|
||
}\
|
||
}\
|
||
}
|
||
|
||
#else
|
||
|
||
#define audio_vol_mix(data,len, ch_num,volumeNOW,volumeDest,step){ \
|
||
int i, j; \
|
||
int fade = 0; \
|
||
if (volumeNOW != volumeDest) \
|
||
{ \
|
||
fade = 1; \
|
||
} \
|
||
if(d_volume->fade == 0)\
|
||
{\
|
||
fade = 0;\
|
||
d_volume->vol_fade = d_volume->vol_target;\
|
||
}\
|
||
if (ch_num == 2) \
|
||
{ \
|
||
len = len >> 1; \
|
||
} \
|
||
else if (ch_num == 3) \
|
||
{ \
|
||
len = (len*5462)>>14; /*等效除3,因为5462向上取整得到的*/\
|
||
} \
|
||
else if(ch_num == 4) \
|
||
{ \
|
||
len = len >> 2; \
|
||
} \
|
||
if (fade) \
|
||
{ \
|
||
short *in_ptr = data; \
|
||
for (i = 0; i < len; i++) \
|
||
{ \
|
||
if (volumeNOW < volumeDest) \
|
||
{ \
|
||
volumeNOW = volumeNOW + step; \
|
||
if (volumeNOW > volumeDest) \
|
||
{ \
|
||
volumeNOW = volumeDest; \
|
||
} \
|
||
} \
|
||
else if (volumeNOW > volumeDest) \
|
||
{ \
|
||
volumeNOW = volumeNOW - step; \
|
||
if (volumeNOW < volumeDest) \
|
||
{ \
|
||
volumeNOW = volumeDest; \
|
||
} \
|
||
} \
|
||
for (j = 0; j < ch_num; j++) \
|
||
{ \
|
||
int tmp = (*in_ptr*volumeNOW) >> 14; \
|
||
L_sat(tmp, tmp); \
|
||
*in_ptr = tmp; \
|
||
in_ptr++; \
|
||
} \
|
||
} \
|
||
} \
|
||
else \
|
||
{ \
|
||
for (i = 0; i < ch_num; i++) \
|
||
{ \
|
||
short *in_ptr = &data[i]; \
|
||
for (j = 0; j < len; j++)\
|
||
{\
|
||
int tmp= (*in_ptr*volumeNOW) >> 14; \
|
||
L_sat(tmp, tmp); \
|
||
*in_ptr = tmp;\
|
||
in_ptr += ch_num;\
|
||
}\
|
||
}\
|
||
}\
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
|
||
int user_audio_digital_volume_run(void *_d_volume, void *data, u32 len, u8 ch_num)
|
||
{
|
||
|
||
struct digital_volume *d_volume = (struct digital_volume *)_d_volume;
|
||
if (!d_volume) {
|
||
log_e("d_volume NULL\n");
|
||
return -1;
|
||
}
|
||
|
||
s32 valuetemp;
|
||
s16 *buf;
|
||
|
||
if (d_volume->toggle == 0) {
|
||
return -1;
|
||
}
|
||
if (ch_num > 4) {
|
||
return -1;
|
||
}
|
||
os_mutex_pend(&d_volume->mutex, 0);
|
||
|
||
|
||
if (ch_num) {
|
||
d_volume->ch_num = ch_num;
|
||
}
|
||
buf = data;
|
||
len >>= 1; //byte to point
|
||
/* printf("d_volume->vol_target %d %d %d %d\n", d_volume->vol_target, ch_num, d_volume->vol_fade, d_volume->fade_step); */
|
||
#if 1
|
||
audio_vol_mix(buf, len, ch_num, d_volume->vol_fade, d_volume->vol_target, d_volume->fade_step);
|
||
#else
|
||
|
||
/* printf("d_volume->vol_target %d %d\n", d_volume->vol_target, ch_num); */
|
||
for (u32 i = 0; i < len; i += d_volume->ch_num) {//ch_num 1/2/3/4
|
||
///FL channel
|
||
if (d_volume->fade) {
|
||
if (d_volume->vol_fade > d_volume->vol_target) {
|
||
d_volume->vol_fade -= d_volume->fade_step;
|
||
if (d_volume->vol_fade < d_volume->vol_target) {
|
||
d_volume->vol_fade = d_volume->vol_target;
|
||
}
|
||
} else if (d_volume->vol_fade < d_volume->vol_target) {
|
||
d_volume->vol_fade += d_volume->fade_step;
|
||
if (d_volume->vol_fade > d_volume->vol_target) {
|
||
d_volume->vol_fade = d_volume->vol_target;
|
||
}
|
||
}
|
||
} else {
|
||
d_volume->vol_fade = d_volume->vol_target;
|
||
}
|
||
|
||
valuetemp = buf[i];
|
||
if (valuetemp < 0) {
|
||
valuetemp = -valuetemp;
|
||
valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
|
||
valuetemp = -valuetemp;
|
||
} else {
|
||
valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
|
||
}
|
||
if (valuetemp < -32768) {
|
||
valuetemp = -32768;
|
||
} else if (valuetemp > 32767) {
|
||
valuetemp = 32767;
|
||
}
|
||
buf[i] = (s16)valuetemp;
|
||
|
||
if (d_volume->ch_num > 1) { //双声道
|
||
///FR channel
|
||
valuetemp = buf[i + 1];
|
||
if (valuetemp < 0) {
|
||
valuetemp = -valuetemp;
|
||
valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
|
||
valuetemp = -valuetemp;
|
||
} else {
|
||
valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
|
||
}
|
||
|
||
if (valuetemp < -32768) {
|
||
valuetemp = -32768;
|
||
} else if (valuetemp > 32767) {
|
||
valuetemp = 32767;
|
||
}
|
||
buf[i + 1] = (s16)valuetemp;
|
||
|
||
if (d_volume->ch_num > 2) { //三声道
|
||
//RL channel
|
||
valuetemp = buf[i + 2];
|
||
if (valuetemp < 0) {
|
||
valuetemp = -valuetemp;
|
||
valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
|
||
valuetemp = -valuetemp;
|
||
} else {
|
||
valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
|
||
}
|
||
if (valuetemp < -32768) {
|
||
valuetemp = -32768;
|
||
} else if (valuetemp > 32767) {
|
||
valuetemp = 32767;
|
||
}
|
||
buf[i + 2] = (s16)valuetemp;
|
||
|
||
|
||
if (d_volume->ch_num > 3) { //四声道
|
||
///RR channel
|
||
valuetemp = buf[i + 3];
|
||
if (valuetemp < 0) {
|
||
valuetemp = -valuetemp;
|
||
valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
|
||
valuetemp = -valuetemp;
|
||
} else {
|
||
valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
|
||
}
|
||
if (valuetemp < -32768) {
|
||
valuetemp = -32768;
|
||
} else if (valuetemp > 32767) {
|
||
valuetemp = 32767;
|
||
}
|
||
buf[i + 3] = (s16)valuetemp;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
os_mutex_post(&d_volume->mutex);
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
/*
|
||
*user_vol_max:音量级数
|
||
*user_vol_tab:自定义音量表,自定义表长user_vol_max+1
|
||
*/
|
||
void user_audio_digital_set_volume_tab(void *_d_volume, u16 *user_vol_tab, u8 user_vol_max)
|
||
{
|
||
struct digital_volume *d_volume = (struct digital_volume *)_d_volume;
|
||
if (!d_volume) {
|
||
log_e("d_volume NULL\n");
|
||
return ;
|
||
}
|
||
|
||
os_mutex_pend(&d_volume->mutex, 0);
|
||
if (user_vol_tab) {
|
||
d_volume->user_vol_tab = user_vol_tab;
|
||
d_volume->user_vol_max = user_vol_max;
|
||
}
|
||
os_mutex_post(&d_volume->mutex);
|
||
}
|
||
|
||
|
||
|
||
/*
|
||
*priv:用户自定义指针
|
||
*void (*handler)(void *priv, void *data, int len, u8 ch_num):用户自定义回调
|
||
* */
|
||
void *user_audio_process_open(void *parm, void *priv, void (*handler)(void *priv, void *data, int len, u8 ch_num))
|
||
{
|
||
struct user_audio_parm *user_hdl = zalloc(sizeof(struct user_audio_parm));
|
||
if (!user_hdl) {
|
||
log_e("user_hdl NULL\n");
|
||
return NULL;
|
||
}
|
||
user_hdl->priv = priv;
|
||
user_hdl->handler = handler;
|
||
|
||
struct user_audio_digital_parm *dvol_parm = (struct user_audio_digital_parm *)parm;
|
||
if (dvol_parm->en) {
|
||
log_i("vol :%d vol_max:%d fade_step:%d\n", dvol_parm->vol, dvol_parm->vol_max, dvol_parm->fade_step);
|
||
user_hdl->dvol_hdl = user_audio_digital_volume_open(dvol_parm->vol, dvol_parm->vol_max, dvol_parm->fade_step);
|
||
}
|
||
log_i("%s ok\n", __FUNCTION__);
|
||
return user_hdl;
|
||
}
|
||
|
||
|
||
int user_audio_process_close(void *_uparm_hdl)
|
||
{
|
||
struct user_audio_parm *user_hdl = (struct user_audio_parm *)_uparm_hdl;
|
||
if (!user_hdl) {
|
||
log_e("user_hdl NULL\n");
|
||
return -1;
|
||
}
|
||
if (user_hdl->dvol_hdl) {
|
||
user_audio_digital_volume_close(user_hdl->dvol_hdl);
|
||
user_hdl->dvol_hdl = NULL;
|
||
}
|
||
free(user_hdl);
|
||
user_hdl = NULL;
|
||
log_i("%s ok\n", __FUNCTION__);
|
||
return 0;
|
||
}
|
||
|
||
void user_audio_process_handler_run(void *_uparm_hdl, void *data, u32 len, u8 ch_num)
|
||
{
|
||
struct user_audio_parm *user_hdl = (struct user_audio_parm *)_uparm_hdl;
|
||
if (!user_hdl) {
|
||
log_e("user_hdl NULL\n");
|
||
return;
|
||
}
|
||
|
||
|
||
if (user_hdl->handler) {
|
||
user_hdl->handler(user_hdl->priv, data, len, ch_num);
|
||
}
|
||
|
||
if (user_hdl->dvol_hdl) {
|
||
user_audio_digital_volume_run(user_hdl->dvol_hdl, data, len, ch_num);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|