1030 lines
32 KiB
C
1030 lines
32 KiB
C
#include "system/includes.h"
|
||
#include "media/includes.h"
|
||
#include "app_config.h"
|
||
#include "app_action.h"
|
||
#include "app_main.h"
|
||
#include "user_cfg.h"
|
||
#include "audio_config.h"
|
||
#include "audio_dvol.h"
|
||
#include "audio_anc.h"
|
||
#include "audio_output_dac.h"
|
||
#include "asm/math_fast_function.h"
|
||
|
||
#define LOG_TAG "[APP_AUDIO]"
|
||
#define LOG_ERROR_ENABLE
|
||
#define LOG_DEBUG_ENABLE
|
||
#define LOG_INFO_ENABLE
|
||
/* #define LOG_DUMP_ENABLE */
|
||
#define LOG_CLI_ENABLE
|
||
#include "debug.h"
|
||
|
||
#define DEFAULT_DIGTAL_VOLUME 16384
|
||
|
||
typedef short unaligned_u16 __attribute__((aligned(1)));
|
||
struct app_audio_config {
|
||
u8 state;
|
||
u8 prev_state;
|
||
u8 mute_when_vol_zero;
|
||
volatile u8 fade_gain_l;
|
||
volatile u8 fade_gain_r;
|
||
volatile s16 fade_dgain_l;
|
||
volatile s16 fade_dgain_r;
|
||
volatile s16 fade_dgain_step_l;
|
||
volatile s16 fade_dgain_step_r;
|
||
volatile int fade_timer;
|
||
s16 digital_volume;
|
||
u8 analog_volume_l;
|
||
u8 analog_volume_r;
|
||
atomic_t ref;
|
||
s16 max_volume[APP_AUDIO_STATE_WTONE + 1];
|
||
u8 sys_cvol_max;
|
||
u8 call_cvol_max;
|
||
u16 sys_hw_dvol_max; //系统最大硬件数字音量(非通话模式)
|
||
u16 call_hw_dvol_max; //通话模式最大硬件数字音量
|
||
unaligned_u16 *sys_cvol;
|
||
unaligned_u16 *call_cvol;
|
||
};
|
||
static const char *audio_state[] = {
|
||
"idle",
|
||
"music",
|
||
"call",
|
||
"tone",
|
||
"err",
|
||
};
|
||
|
||
static struct app_audio_config app_audio_cfg = {0};
|
||
|
||
#define __this (&app_audio_cfg)
|
||
extern struct audio_dac_hdl dac_hdl;
|
||
extern struct dac_platform_data dac_data;
|
||
|
||
/*
|
||
*************************************************************
|
||
*
|
||
* audio volume fade
|
||
*
|
||
*************************************************************
|
||
*/
|
||
|
||
static void audio_fade_timer(void *priv)
|
||
{
|
||
u8 gain_l = dac_hdl.vol_l;
|
||
u8 gain_r = dac_hdl.vol_r;
|
||
//printf("<fade:%d-%d-%d-%d>", gain_l, gain_r, __this->fade_gain_l, __this->fade_gain_r);
|
||
local_irq_disable();
|
||
if ((gain_l == __this->fade_gain_l) && (gain_r == __this->fade_gain_r)) {
|
||
usr_timer_del(__this->fade_timer);
|
||
__this->fade_timer = 0;
|
||
/*音量为0的时候mute住*/
|
||
audio_dac_set_L_digital_vol(&dac_hdl, gain_l ? __this->digital_volume : 0);
|
||
audio_dac_set_R_digital_vol(&dac_hdl, gain_r ? __this->digital_volume : 0);
|
||
if ((gain_l == 0) && (gain_r == 0)) {
|
||
if (__this->mute_when_vol_zero) {
|
||
__this->mute_when_vol_zero = 0;
|
||
audio_dac_mute(&dac_hdl, 1);
|
||
}
|
||
}
|
||
local_irq_enable();
|
||
/*
|
||
*淡入淡出结束,也把当前的模拟音量设置一下,防止因为淡入淡出的音量和保存音量的变量一致,
|
||
*而寄存器已经被清0的情况
|
||
*/
|
||
audio_dac_set_analog_vol(&dac_hdl, gain_l);
|
||
/* log_info("dac_fade_end, VOL : 0x%x 0x%x\n", JL_ADDA->DAA_CON1, JL_AUDIO->DAC_VL0); */
|
||
return;
|
||
}
|
||
if (gain_l > __this->fade_gain_l) {
|
||
gain_l--;
|
||
} else if (gain_l < __this->fade_gain_l) {
|
||
gain_l++;
|
||
}
|
||
|
||
if (gain_r > __this->fade_gain_r) {
|
||
gain_r--;
|
||
} else if (gain_r < __this->fade_gain_r) {
|
||
gain_r++;
|
||
}
|
||
audio_dac_set_analog_vol(&dac_hdl, gain_l);
|
||
local_irq_enable();
|
||
}
|
||
|
||
static int audio_fade_timer_add(u8 gain_l, u8 gain_r)
|
||
{
|
||
/* r_printf("dac_fade_begin:0x%x,gain_l:%d,gain_r:%d\n", __this->fade_timer, gain_l, gain_r); */
|
||
local_irq_disable();
|
||
__this->fade_gain_l = gain_l;
|
||
__this->fade_gain_r = gain_r;
|
||
if (__this->fade_timer == 0) {
|
||
__this->fade_timer = usr_timer_add((void *)0, audio_fade_timer, 2, 1);
|
||
/* y_printf("fade_timer:0x%x", __this->fade_timer); */
|
||
}
|
||
local_irq_enable();
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_AD)
|
||
|
||
#define DGAIN_SET_MAX_STEP (300)
|
||
#define DGAIN_SET_MIN_STEP (30)
|
||
|
||
static unsigned short combined_vol_list[17][2] = {
|
||
{ 0, 0}, //0: None
|
||
{ 0, 412}, // 1:-50.00 db
|
||
{ 0, 604}, // 2:-46.67 db
|
||
{ 0, 887}, // 3:-43.33 db
|
||
{ 0, 1301}, // 4:-40.00 db
|
||
{ 0, 1910}, // 5:-36.67 db
|
||
{ 0, 2804}, // 6:-33.33 db
|
||
{ 0, 4115}, // 7:-30.00 db
|
||
{ 0, 6041}, // 8:-26.67 db
|
||
{ 0, 8867}, // 9:-23.33 db
|
||
{ 0, 13014}, // 10:-20.00 db
|
||
{ 1, 9574}, // 11:-16.67 db
|
||
{ 1, 14052}, // 12:-13.33 db
|
||
{ 2, 10338}, // 13:-10.00 db
|
||
{ 2, 15174}, // 14:-6.67 db
|
||
{ 3, 11162}, // 15:-3.33 db
|
||
{ 3, 16384}, // 16:0.00 db
|
||
};
|
||
static unsigned short call_combined_vol_list[16][2] = {
|
||
{ 0, 0}, //0: None
|
||
{ 0, 412}, // 1:-50.00 db
|
||
{ 0, 604}, // 2:-46.67 db
|
||
{ 0, 887}, // 3:-43.33 db
|
||
{ 0, 1301}, // 4:-40.00 db
|
||
{ 0, 1910}, // 5:-36.67 db
|
||
{ 0, 2804}, // 6:-33.33 db
|
||
{ 0, 4115}, // 7:-30.00 db
|
||
{ 0, 6041}, // 8:-26.67 db
|
||
{ 0, 8867}, // 9:-23.33 db
|
||
{ 0, 13014}, // 10:-20.00 db
|
||
{ 1, 9574}, // 11:-16.67 db
|
||
{ 1, 14052}, // 12:-13.33 db
|
||
{ 2, 10338}, // 13:-10.00 db
|
||
{ 2, 15174}, // 14:-6.67 db
|
||
{ 3, 11162}, // 15:-3.33 db
|
||
};
|
||
|
||
void audio_combined_vol_init(u8 cfg_en)
|
||
{
|
||
u16 sys_cvol_len = 0;
|
||
u16 call_cvol_len = 0;
|
||
u8 *sys_cvol = NULL;
|
||
u8 *call_cvol = NULL;
|
||
unaligned_u16 *cvol;
|
||
|
||
__this->sys_cvol_max = ARRAY_SIZE(combined_vol_list) - 1;
|
||
__this->sys_cvol = combined_vol_list;
|
||
__this->call_cvol_max = ARRAY_SIZE(call_combined_vol_list) - 1;
|
||
__this->call_cvol = call_combined_vol_list;
|
||
|
||
if (cfg_en) {
|
||
sys_cvol = syscfg_ptr_read(CFG_COMBINE_SYS_VOL_ID, &sys_cvol_len);
|
||
//ASSERT(((u32)sys_cvol & BIT(0)) == 0, "sys_cvol addr unalignd(2):%x\n", sys_cvol);
|
||
if (sys_cvol && sys_cvol_len) {
|
||
__this->sys_cvol = sys_cvol;
|
||
__this->sys_cvol_max = sys_cvol_len / 4 - 1;
|
||
//y_printf("read sys_combine_vol succ:%x,len:%d",__this->sys_cvol,sys_cvol_len);
|
||
/* cvol = __this->sys_cvol;
|
||
for(int i = 0,j = 0;i < (sys_cvol_len / 2);j++) {
|
||
printf("sys_vol %d: %d, %d\n",j,*cvol++,*cvol++);
|
||
i += 2;
|
||
} */
|
||
} else {
|
||
r_printf("read sys_cvol false:%x,%x\n", sys_cvol, sys_cvol_len);
|
||
}
|
||
|
||
call_cvol = syscfg_ptr_read(CFG_COMBINE_CALL_VOL_ID, &call_cvol_len);
|
||
//ASSERT(((u32)call_cvol & BIT(0)) == 0, "call_cvol addr unalignd(2):%d\n", call_cvol);
|
||
if (call_cvol && call_cvol_len) {
|
||
__this->call_cvol = (unaligned_u16 *)call_cvol;
|
||
__this->call_cvol_max = call_cvol_len / 4 - 1;
|
||
//y_printf("read call_combine_vol succ:%x,len:%d",__this->call_cvol,call_cvol_len);
|
||
/* cvol = __this->call_cvol;
|
||
for(int i = 0,j = 0;i < call_cvol_len / 2;j++) {
|
||
printf("call_vol %d: %d, %d\n",j,*cvol++,*cvol++);
|
||
i += 2;
|
||
} */
|
||
} else {
|
||
r_printf("read call_combine_vol false:%x,%x\n", call_cvol, call_cvol_len);
|
||
}
|
||
}
|
||
|
||
log_info("sys_cvol_max:%d,call_cvol_max:%d\n", __this->sys_cvol_max, __this->call_cvol_max);
|
||
}
|
||
|
||
static int audio_combined_fade_timer_add(u8 gain_l, u8 gain_r)
|
||
{
|
||
u8 gain_max;
|
||
u8 target_again_l = 0;
|
||
u8 target_again_r = 0;
|
||
u16 target_dgain_l = 0;
|
||
u16 target_dgain_r = 0;
|
||
|
||
if (__this->state == APP_AUDIO_STATE_CALL) {
|
||
gain_max = __this->call_cvol_max;
|
||
gain_l = (gain_l > gain_max) ? gain_max : gain_l;
|
||
gain_r = (gain_r > gain_max) ? gain_max : gain_r;
|
||
target_again_l = *(&__this->call_cvol[gain_l * 2]);
|
||
target_again_r = *(&__this->call_cvol[gain_r * 2]);
|
||
target_dgain_l = *(&__this->call_cvol[gain_l * 2 + 1]);
|
||
target_dgain_r = *(&__this->call_cvol[gain_r * 2 + 1]);
|
||
} else {
|
||
gain_max = __this->sys_cvol_max;
|
||
gain_l = (gain_l > gain_max) ? gain_max : gain_l;
|
||
gain_r = (gain_r > gain_max) ? gain_max : gain_r;
|
||
target_again_l = *(&__this->sys_cvol[gain_l * 2]);
|
||
target_again_r = *(&__this->sys_cvol[gain_r * 2]);
|
||
target_dgain_l = *(&__this->sys_cvol[gain_l * 2 + 1]);
|
||
target_dgain_r = *(&__this->sys_cvol[gain_r * 2 + 1]);
|
||
}
|
||
#if 0//TCFG_AUDIO_ANC_ENABLE
|
||
target_again_l = anc_dac_gain_get(ANC_DAC_CH_L);
|
||
target_again_r = anc_dac_gain_get(ANC_DAC_CH_R);
|
||
#endif
|
||
|
||
printf("[l]v:%d,Av:%d,Dv:%d", gain_l, target_again_l, target_dgain_l);
|
||
//y_printf("[r]v:%d,Av:%d,Dv:%d", gain_r, target_again_r, target_dgain_r);
|
||
/* log_info("dac_com_fade_begin:0x%x\n", __this->fade_timer); */
|
||
|
||
local_irq_disable();
|
||
|
||
__this->fade_gain_l = target_again_l;
|
||
__this->fade_gain_r = target_again_r;
|
||
__this->fade_dgain_l = target_dgain_l;
|
||
__this->fade_dgain_r = target_dgain_r;
|
||
|
||
if (__this->fade_timer == 0) {
|
||
/* __this->fade_timer = usr_timer_add((void *)0, audio_combined_fade_timer, 2, 1); */
|
||
/* log_info("combined_fade_timer:0x%x", __this->fade_timer); */
|
||
}
|
||
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, 0x3, __this->fade_gain_l, 1);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, 0x3, __this->fade_dgain_l, 1);
|
||
|
||
local_irq_enable();
|
||
|
||
return 0;
|
||
}
|
||
|
||
#endif/*SYS_VOL_TYPE == VOL_TYPE_AD*/
|
||
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_DIGITAL_HW)
|
||
#define DVOL_HW_LEVEL_MAX 31 /*注意:总共是(DVOL_HW_LEVEL_MAX + 1)级*/
|
||
u16 hw_dig_vol_table[DVOL_HW_LEVEL_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
|
||
10222,//28
|
||
14200,//29
|
||
16000,//30
|
||
16384 //31
|
||
};
|
||
|
||
//float dB_Convert_Mag(float x)
|
||
/* #define DIG_VOL_MAX_VALUE (0.0f) // 数字音量最大值(单位:dB) */
|
||
/* #define DIG_VOL_STEP (1.5f) // 逐级递减差值(单位:dB) */
|
||
void audio_hw_digital_vol_init(u8 cfg_en)
|
||
{
|
||
float dB_value = DIG_VOL_MAX_VALUE;
|
||
#if (TCFG_AUDIO_ANC_ENABLE)
|
||
dB_value = (dB_value > ANC_MODE_DIG_VOL_LIMIT) ? ANC_MODE_DIG_VOL_LIMIT : dB_value;
|
||
#endif/*TCFG_AUDIO_ANC_ENABLE*/
|
||
#if 0
|
||
int vol = get_max_sys_vol();
|
||
float temp = 0;
|
||
//printf("hw digital volume list:\n");
|
||
while (vol) {
|
||
temp = 16384.0f * dB_Convert_Mag(dB_value);
|
||
hw_dig_vol_table[vol] = (u16)temp;
|
||
//printf("[%d] dB:%.1f %.1f %d\n", vol, dB_value, temp, hw_dig_vol_table[vol]);
|
||
dB_value -= DIG_VOL_STEP;
|
||
vol--;
|
||
}
|
||
hw_dig_vol_table[0] = 0;
|
||
#else
|
||
app_var.aec_dac_gain = (app_var.aec_dac_gain > BT_CALL_VOL_LEAVE_MAX) ? BT_CALL_VOL_LEAVE_MAX : app_var.aec_dac_gain;
|
||
__this->sys_hw_dvol_max = (u16)(16384.f * dB_Convert_Mag(dB_value));
|
||
float call_hw_dvol_max_dB = DIG_VOL_MAX_VALUE + (BT_CALL_VOL_LEAVE_MAX - app_var.aec_dac_gain) * BT_CALL_VOL_STEP;
|
||
printf("aec_dac_gain:%d,call_hw_dvol_max_dB:%.1f\n", app_var.aec_dac_gain, call_hw_dvol_max_dB);
|
||
__this->call_hw_dvol_max = (u16)(16384.f * dB_Convert_Mag(call_hw_dvol_max_dB));
|
||
printf("sys_hw_dvol_max:%d,call_hw_dvol_max:%d\n", __this->sys_hw_dvol_max, __this->call_hw_dvol_max);
|
||
#endif
|
||
}
|
||
|
||
#endif/*SYS_VOL_TYPE == VOL_TYPE_DIGITAL_HW*/
|
||
|
||
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_DIGITAL)
|
||
|
||
#define DVOL_SW_LEVEL_MAX 31 /*注意:总共是(DVOL_SW_LEVEL_MAX + 1)级*/
|
||
u16 sw_dig_vol_table[DVOL_SW_LEVEL_MAX + 1] = {0};
|
||
|
||
void audio_sw_digital_vol_init(u8 cfg_en)
|
||
{
|
||
printf("audio_sw_digital_vol_init,user-defined[%d]\n", SW_DIG_VOL_TAB_USER_DEFINED);
|
||
float dB_value = DIG_VOL_MAX_VALUE;
|
||
#if (TCFG_AUDIO_ANC_ENABLE)
|
||
dB_value = (dB_value > ANC_MODE_DIG_VOL_LIMIT) ? ANC_MODE_DIG_VOL_LIMIT : dB_value;
|
||
#endif/*TCFG_AUDIO_ANC_ENABLE*/
|
||
|
||
#if SW_DIG_VOL_TAB_USER_DEFINED
|
||
int vol = get_max_sys_vol();
|
||
float temp = 0;
|
||
//printf("sw digital volume list:\n");
|
||
while (vol) {
|
||
temp = 16384.0f * dB_Convert_Mag(dB_value);
|
||
sw_dig_vol_table[vol] = (u16)temp;
|
||
//printf("[%d] dB:%.1f %.1f %d\n", vol, dB_value, temp, sw_dig_vol_table[vol]);
|
||
dB_value -= DIG_VOL_STEP;
|
||
vol--;
|
||
}
|
||
sw_dig_vol_table[0] = 0;
|
||
__this->sys_hw_dvol_max = DEFAULT_DIGITAL_VOLUME;
|
||
audio_digital_vol_init(sw_dig_vol_table, get_max_sys_vol());
|
||
#else
|
||
__this->sys_hw_dvol_max = (u16)(16384.0f * dB_Convert_Mag(dB_value));
|
||
audio_digital_vol_init(NULL, 0);
|
||
#endif/*SW_DIG_VOL_TAB_USER_DEFINED*/
|
||
|
||
app_var.aec_dac_gain = (app_var.aec_dac_gain > BT_CALL_VOL_LEAVE_MAX) ? BT_CALL_VOL_LEAVE_MAX : app_var.aec_dac_gain;
|
||
__this->call_hw_dvol_max = (u16)(__this->sys_hw_dvol_max * dB_Convert_Mag((BT_CALL_VOL_LEAVE_MAX - app_var.aec_dac_gain) * BT_CALL_VOL_STEP));
|
||
printf("sys_hw_dvol_max:%d,call_hw_dvol_max:%d\n", __this->sys_hw_dvol_max, __this->call_hw_dvol_max);
|
||
}
|
||
#endif/*SYS_VOL_TYPE == VOL_TYPE_DIGITAL*/
|
||
|
||
void audio_volume_list_init(u8 cfg_en)
|
||
{
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_AD)
|
||
audio_combined_vol_init(cfg_en);
|
||
#elif (SYS_VOL_TYPE == VOL_TYPE_DIGITAL_HW)
|
||
audio_hw_digital_vol_init(cfg_en);
|
||
#elif (SYS_VOL_TYPE == VOL_TYPE_DIGITAL)
|
||
audio_sw_digital_vol_init(cfg_en);
|
||
#endif/*SYS_VOL_TYPE*/
|
||
}
|
||
|
||
static void set_audio_device_volume(u8 type, s16 vol)
|
||
{
|
||
audio_dac_set_analog_vol(&dac_hdl, vol);
|
||
}
|
||
|
||
static int get_audio_device_volume(u8 vol_type)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
void volume_up_down_direct(s8 value)
|
||
{
|
||
|
||
}
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Audio Volume Fade
|
||
* Description: 音量淡入淡出
|
||
* Arguments : left_vol
|
||
* right_vol
|
||
* Return : None.
|
||
* Note(s) : None.
|
||
*********************************************************************
|
||
*/
|
||
void audio_fade_in_fade_out(u8 left_vol, u8 right_vol)
|
||
{
|
||
/*根据audio state切换的时候设置的最大音量,限制淡入淡出的最大音量*/
|
||
u8 max_vol_l = __this->max_volume[__this->state];
|
||
u8 max_vol_r = max_vol_l;
|
||
/*printf("[fade]state:%s,max_volume:%d,cur:%d,%d", audio_state[__this->state], max_vol_l, left_vol, left_vol);*/
|
||
/*淡入淡出音量限制*/
|
||
u8 left_gain = left_vol > max_vol_l ? max_vol_l : left_vol;
|
||
u8 right_gain = right_vol > max_vol_r ? max_vol_r : right_vol;
|
||
|
||
/*数字音量*/
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_DIGITAL)
|
||
u8 dvol_idx = 0; //记录音量通道供数字音量控制使用
|
||
s8 volume = right_gain;
|
||
switch (__this->state) {
|
||
case APP_AUDIO_STATE_IDLE:
|
||
case APP_AUDIO_STATE_MUSIC:
|
||
dvol_idx = MUSIC_DVOL;
|
||
break;
|
||
case APP_AUDIO_STATE_CALL:
|
||
dvol_idx = CALL_DVOL;
|
||
break;
|
||
case APP_AUDIO_STATE_WTONE:
|
||
dvol_idx = TONE_DVOL;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if (volume > __this->max_volume[__this->state]) {
|
||
volume = __this->max_volume[__this->state];
|
||
}
|
||
/*printf("set_vol[%s]:=%d\n", audio_state[__this->state], volume);*/
|
||
|
||
/*按照配置限制通话时候spk最大音量*/
|
||
if (__this->state == APP_AUDIO_STATE_CALL) {
|
||
__this->digital_volume = __this->call_hw_dvol_max;
|
||
} else {
|
||
__this->digital_volume = __this->sys_hw_dvol_max;
|
||
}
|
||
/*printf("[SW_DVOL]Gain:%d,AVOL:%d,DVOL:%d\n", left_gain, __this->analog_volume_l, __this->digital_volume);*/
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, 0x3, __this->analog_volume_l, 1);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, 0x3, __this->digital_volume, 1);
|
||
#endif/*SYS_VOL_TYPE == VOL_TYPE_DIGITAL*/
|
||
|
||
/*模拟数字联合音量*/
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_AD)
|
||
#if TCFG_CALL_USE_DIGITAL_VOLUME
|
||
if (__this->state == APP_AUDIO_STATE_CALL) {
|
||
audio_fade_timer_add(left_gain, right_gain);
|
||
} else {
|
||
audio_combined_fade_timer_add(left_gain, right_gain);
|
||
}
|
||
#else
|
||
audio_combined_fade_timer_add(left_gain, right_gain);
|
||
#endif/*TCFG_CALL_USE_DIGITAL_VOLUME*/
|
||
#endif/*SYS_VOL_TYPE == VOL_TYPE_AD*/
|
||
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_DIGITAL_HW)
|
||
/* u8 dvol_hw_level = 0; */
|
||
/* dvol_hw_level = left_gain * DVOL_HW_LEVEL_MAX / get_max_sys_vol(); */
|
||
/* __this->digital_volume = hw_dig_vol_table[dvol_hw_level]; */
|
||
#if 0
|
||
__this->digital_volume = hw_dig_vol_table[left_gain];
|
||
/* audio_fade_timer_add(__this->analog_volume_l, __this->analog_volume_r); */
|
||
#else
|
||
float dvol_db = 0;
|
||
if (left_gain) {
|
||
if (__this->state == APP_AUDIO_STATE_CALL) {
|
||
dvol_db = (BT_CALL_VOL_LEAVE_MAX - left_gain) * BT_CALL_VOL_STEP;
|
||
__this->digital_volume = (s16)(__this->call_hw_dvol_max * dB_Convert_Mag(dvol_db));
|
||
} else {
|
||
dvol_db = (BT_MUSIC_VOL_LEAVE_MAX - left_gain) * BT_MUSIC_VOL_STEP;
|
||
__this->digital_volume = (s16)(__this->sys_hw_dvol_max * dB_Convert_Mag(dvol_db));
|
||
}
|
||
} else {
|
||
__this->digital_volume = 0;
|
||
}
|
||
#endif
|
||
printf("[HW_DVOL]Gain:%d,AVOL:%d,DVOL:%d\n", left_gain, __this->analog_volume_l, __this->digital_volume);
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, 0x3, __this->analog_volume_l, 1);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, 0x3, __this->digital_volume, 1);
|
||
#endif/*SYS_VOL_TYPE == VOL_TYPE_DIGITAL_HW*/
|
||
}
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Audio Volume Set
|
||
* Description: 音量设置
|
||
* Arguments : state 目标声音通道
|
||
* volume 目标音量值
|
||
* fade 是否淡入淡出
|
||
* Return : None.
|
||
* Note(s) : None.
|
||
*********************************************************************
|
||
*/
|
||
void app_audio_set_volume(u8 state, s8 volume, u8 fade)
|
||
{
|
||
u8 dvol_idx = 0; //记录音量通道供数字音量控制使用
|
||
switch (state) {
|
||
case APP_AUDIO_STATE_IDLE:
|
||
case APP_AUDIO_STATE_MUSIC:
|
||
app_var.music_volume = volume;
|
||
dvol_idx = MUSIC_DVOL;
|
||
break;
|
||
case APP_AUDIO_STATE_CALL:
|
||
app_var.call_volume = volume;
|
||
dvol_idx = CALL_DVOL;
|
||
#if TCFG_CALL_USE_DIGITAL_VOLUME
|
||
audio_digital_vol_set(volume);
|
||
return;
|
||
#endif/*TCFG_CALL_USE_DIGITAL_VOLUME*/
|
||
break;
|
||
case APP_AUDIO_STATE_WTONE:
|
||
app_var.wtone_volume = volume;
|
||
dvol_idx = TONE_DVOL;
|
||
break;
|
||
default:
|
||
return;
|
||
}
|
||
printf("set_vol[%s]:%s=%d\n", audio_state[__this->state], audio_state[state], volume);
|
||
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_DIGITAL)
|
||
if (volume > __this->max_volume[state]) {
|
||
volume = __this->max_volume[state];
|
||
}
|
||
audio_digital_vol_set(dvol_idx, volume);
|
||
#endif/*SYS_VOL_TYPE == VOL_TYPE_DIGITAL*/
|
||
|
||
if (state == __this->state) {
|
||
audio_dac_set_volume(&dac_hdl, volume);
|
||
audio_fade_in_fade_out(volume, volume);
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Audio Volume Get
|
||
* Description: 音量获取
|
||
* Arguments : state 要获取音量值的音量状态
|
||
* Return : 返回指定状态对应得音量值
|
||
* Note(s) : None.
|
||
*********************************************************************
|
||
*/
|
||
s8 app_audio_get_volume(u8 state)
|
||
{
|
||
s8 volume = 0;
|
||
switch (state) {
|
||
case APP_AUDIO_STATE_IDLE:
|
||
case APP_AUDIO_STATE_MUSIC:
|
||
volume = app_var.music_volume;
|
||
break;
|
||
case APP_AUDIO_STATE_CALL:
|
||
volume = app_var.call_volume;
|
||
break;
|
||
case APP_AUDIO_STATE_WTONE:
|
||
volume = app_var.wtone_volume;
|
||
if (!volume) {
|
||
volume = app_var.music_volume;
|
||
}
|
||
break;
|
||
case APP_AUDIO_CURRENT_STATE:
|
||
volume = app_audio_get_volume(__this->state);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return volume;
|
||
}
|
||
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Audio Mute
|
||
* Description: 静音控制
|
||
* Arguments : value Mute操作
|
||
* Return : None.
|
||
* Note(s) : None.
|
||
*********************************************************************
|
||
*/
|
||
static const char *audio_mute_string[] = {
|
||
"mute_default",
|
||
"unmute_default",
|
||
"mute_L",
|
||
"unmute_L",
|
||
"mute_R",
|
||
"unmute_R",
|
||
};
|
||
|
||
#define AUDIO_MUTE_FADE 1
|
||
#define AUDIO_UMMUTE_FADE 1
|
||
void app_audio_mute(u8 value)
|
||
{
|
||
u8 volume = 0;
|
||
printf("audio_mute:%s", audio_mute_string[value]);
|
||
switch (value) {
|
||
case AUDIO_MUTE_DEFAULT:
|
||
#if AUDIO_MUTE_FADE
|
||
audio_fade_in_fade_out(0, 0);
|
||
__this->mute_when_vol_zero = 1;
|
||
#else
|
||
audio_dac_set_analog_vol(&dac_hdl, 0);
|
||
audio_dac_mute(&dac_hdl, 1);
|
||
#endif/*AUDIO_MUTE_FADE*/
|
||
break;
|
||
case AUDIO_UNMUTE_DEFAULT:
|
||
#if AUDIO_UMMUTE_FADE
|
||
audio_dac_mute(&dac_hdl, 0);
|
||
volume = app_audio_get_volume(APP_AUDIO_CURRENT_STATE);
|
||
audio_fade_in_fade_out(volume, volume);
|
||
#else
|
||
audio_dac_mute(&dac_hdl, 0);
|
||
volume = app_audio_get_volume(APP_AUDIO_CURRENT_STATE);
|
||
audio_dac_set_analog_vol(&dac_hdl, volume);
|
||
#endif/*AUDIO_UMMUTE_FADE*/
|
||
break;
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Audio Volume Up
|
||
* Description: 增加当前音量通道的音量
|
||
* Arguments : value 要增加的音量值
|
||
* Return : None.
|
||
* Note(s) : None.
|
||
*********************************************************************
|
||
*/
|
||
void app_audio_volume_up(u8 value)
|
||
{
|
||
s16 volume = 0;
|
||
switch (__this->state) {
|
||
case APP_AUDIO_STATE_IDLE:
|
||
case APP_AUDIO_STATE_MUSIC:
|
||
app_var.music_volume += value;
|
||
if (app_var.music_volume > get_max_sys_vol()) {
|
||
app_var.music_volume = get_max_sys_vol();
|
||
}
|
||
volume = app_var.music_volume;
|
||
break;
|
||
case APP_AUDIO_STATE_CALL:
|
||
app_var.call_volume += value;
|
||
#if TCFG_CALL_USE_DIGITAL_VOLUME
|
||
audio_digital_vol_set(volume);
|
||
return;
|
||
#endif
|
||
if (app_var.call_volume > app_var.aec_dac_gain) {
|
||
app_var.call_volume = app_var.aec_dac_gain;
|
||
}
|
||
volume = app_var.call_volume;
|
||
|
||
break;
|
||
case APP_AUDIO_STATE_WTONE:
|
||
app_var.wtone_volume += value;
|
||
if (app_var.wtone_volume > get_max_sys_vol()) {
|
||
app_var.wtone_volume = get_max_sys_vol();
|
||
}
|
||
volume = app_var.wtone_volume;
|
||
break;
|
||
default:
|
||
return;
|
||
}
|
||
|
||
app_audio_set_volume(__this->state, volume, 1);
|
||
}
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Audio Volume Down
|
||
* Description: 减少当前音量通道的音量
|
||
* Arguments : value 要减少的音量值
|
||
* Return : None.
|
||
* Note(s) : None.
|
||
*********************************************************************
|
||
*/
|
||
void app_audio_volume_down(u8 value)
|
||
{
|
||
s16 volume = 0;
|
||
switch (__this->state) {
|
||
case APP_AUDIO_STATE_IDLE:
|
||
case APP_AUDIO_STATE_MUSIC:
|
||
app_var.music_volume -= value;
|
||
if (app_var.music_volume < 0) {
|
||
app_var.music_volume = 0;
|
||
}
|
||
volume = app_var.music_volume;
|
||
break;
|
||
case APP_AUDIO_STATE_CALL:
|
||
app_var.call_volume -= value;
|
||
if (app_var.call_volume < 0) {
|
||
app_var.call_volume = 0;
|
||
}
|
||
volume = app_var.call_volume;
|
||
#if TCFG_CALL_USE_DIGITAL_VOLUME
|
||
audio_digital_vol_set(volume);
|
||
return;
|
||
#endif
|
||
break;
|
||
case APP_AUDIO_STATE_WTONE:
|
||
app_var.wtone_volume -= value;
|
||
if (app_var.wtone_volume < 0) {
|
||
app_var.wtone_volume = 0;
|
||
}
|
||
volume = app_var.wtone_volume;
|
||
break;
|
||
default:
|
||
return;
|
||
}
|
||
|
||
app_audio_set_volume(__this->state, volume, 1);
|
||
}
|
||
|
||
/*level:0~15*/
|
||
static const u16 phone_call_dig_vol_tab[] = {
|
||
0, //0
|
||
111,//1
|
||
161,//2
|
||
234,//3
|
||
338,//4
|
||
490,//5
|
||
708,//6
|
||
1024,//7
|
||
1481,//8
|
||
2142,//9
|
||
3098,//10
|
||
4479,//11
|
||
6477,//12
|
||
9366,//13
|
||
14955,//14
|
||
16384 //15
|
||
};
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Audio State Switch
|
||
* Description: 切换声音状态
|
||
* Arguments : state
|
||
* max_volume
|
||
* Return : None.
|
||
* Note(s) : None.
|
||
*********************************************************************
|
||
*/
|
||
void app_audio_state_switch(u8 state, s16 max_volume)
|
||
{
|
||
r_printf("audio state old:%s,new:%s,vol:%d\n", audio_state[__this->state], audio_state[state], max_volume);
|
||
printf(">>>>>>>>>>>>>> audio state old:%s,new:%s,vol:%d\n", audio_state[__this->state], audio_state[state], max_volume);
|
||
|
||
u8 analog_vol = MAX_ANA_VOL;
|
||
#if TCFG_AUDIO_ANC_ENABLE
|
||
analog_vol = anc_dac_gain_get(ANC_DAC_CH_L); //获取ANC设置的DAC模拟增益
|
||
#endif/*TCFG_AUDIO_ANC_ENABLE*/
|
||
__this->prev_state = __this->state;
|
||
__this->state = state;
|
||
#if TCFG_CALL_USE_DIGITAL_VOLUME
|
||
if (__this->state == APP_AUDIO_STATE_CALL) {
|
||
audio_digital_vol_open(max_volume, max_volume, 4);
|
||
/*调数字音量的时候,模拟音量定最大*/
|
||
audio_dac_set_analog_vol(&dac_hdl, max_volume);
|
||
}
|
||
#endif
|
||
/*限制最大音量*/
|
||
__this->max_volume[state] = max_volume;
|
||
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_DIGITAL_HW)
|
||
__this->analog_volume_l = analog_vol;
|
||
__this->analog_volume_r = analog_vol;
|
||
#else
|
||
__this->digital_volume = DEFAULT_DIGITAL_VOLUME;
|
||
#endif/*SYS_VOL_TYPE == VOL_TYPE_DIGITAL_HW*/
|
||
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_DIGITAL)
|
||
__this->analog_volume_l = MAX_ANA_VOL;
|
||
__this->analog_volume_r = MAX_ANA_VOL;
|
||
#if 0//TCFG_AUDIO_ANC_ENABLE
|
||
__this->analog_volume_l = anc_dac_gain_get(ANC_DAC_CH_L);
|
||
__this->analog_volume_r = anc_dac_gain_get(ANC_DAC_CH_R);
|
||
//g_printf("anc mode,vol_l:%d,vol_r:%d", __this->analog_volume_l, __this->analog_volume_r);
|
||
#endif/*TCFG_AUDIO_ANC_ENABLE*/
|
||
#else
|
||
if (__this->state == APP_AUDIO_STATE_CALL) {
|
||
#if TCFG_CALL_USE_DIGITAL_VOLUME
|
||
u8 call_volume_level_max = ARRAY_SIZE(phone_call_dig_vol_tab) - 1;
|
||
app_var.call_volume = (app_var.call_volume > call_volume_level_max) ? call_volume_level_max : app_var.call_volume;
|
||
__this->digital_volume = phone_call_dig_vol_tab[app_var.call_volume];
|
||
printf("call_volume:%d,digital_volume:%d", app_var.call_volume, __this->digital_volume);
|
||
dac_digital_vol_open();
|
||
dac_digital_vol_tab_register(phone_call_dig_vol_tab, ARRAY_SIZE(phone_call_dig_vol_tab));
|
||
/*调数字音量的时候,模拟音量定最大*/
|
||
audio_dac_set_analog_vol(&dac_hdl, max_volume);
|
||
#elif (SYS_VOL_TYPE == VOL_TYPE_AD)
|
||
/*通话联合音量调节的时候,最大音量为15,和手机的等级一致*/
|
||
__this->max_volume[state] = BT_CALL_VOL_LEAVE_MAX;
|
||
#endif/*TCFG_CALL_USE_DIGITAL_VOLUME*/
|
||
}
|
||
#endif/*SYS_VOL_TYPE == VOL_TYPE_DIGITAL*/
|
||
|
||
app_audio_set_volume(state, app_audio_get_volume(state), 1);
|
||
}
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Audio State Exit
|
||
* Description: 退出当前的声音状态
|
||
* Arguments : state 要退出的声音状态
|
||
* Return : None.
|
||
* Note(s) : None.
|
||
*********************************************************************
|
||
*/
|
||
void app_audio_state_exit(u8 state)
|
||
{
|
||
#if TCFG_CALL_USE_DIGITAL_VOLUME
|
||
if (__this->state == APP_AUDIO_STATE_CALL) {
|
||
audio_digital_vol_close();
|
||
}
|
||
#endif/*TCFG_CALL_USE_DIGITAL_VOLUME*/
|
||
if (state == __this->state) {
|
||
__this->state = __this->prev_state;
|
||
__this->prev_state = APP_AUDIO_STATE_IDLE;
|
||
} else if (state == __this->prev_state) {
|
||
__this->prev_state = APP_AUDIO_STATE_IDLE;
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Audio Set Max Volume
|
||
* Description: 设置最大音量
|
||
* Arguments : state 要设置最大音量的声音状态
|
||
* max_volume 最大音量
|
||
* Return : None.
|
||
* Note(s) : None.
|
||
*********************************************************************
|
||
*/
|
||
void app_audio_set_max_volume(u8 state, s16 max_volume)
|
||
{
|
||
__this->max_volume[state] = max_volume;
|
||
}
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Audio State Get
|
||
* Description: 获取当前声音状态
|
||
* Arguments : None.
|
||
* Return : 返回当前的声音状态
|
||
* Note(s) : None.
|
||
*********************************************************************
|
||
*/
|
||
u8 app_audio_get_state(void)
|
||
{
|
||
return __this->state;
|
||
}
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Audio Volume_Max Get
|
||
* Description: 获取当前声音通道的最大音量
|
||
* Arguments : None.
|
||
* Return : 返回当前的声音通道最大音量
|
||
* Note(s) : None.
|
||
*********************************************************************
|
||
*/
|
||
s16 app_audio_get_max_volume(void)
|
||
{
|
||
if (__this->state == APP_AUDIO_STATE_IDLE) {
|
||
return get_max_sys_vol();
|
||
}
|
||
#if TCFG_CALL_USE_DIGITAL_VOLUME
|
||
if (__this->state == APP_AUDIO_STATE_CALL) {
|
||
return (ARRAY_SIZE(phone_call_dig_vol_tab) - 1);
|
||
}
|
||
#endif/*TCFG_CALL_USE_DIGITAL_VOLUME*/
|
||
return __this->max_volume[__this->state];
|
||
}
|
||
|
||
void app_audio_set_mix_volume(u8 front_volume, u8 back_volume)
|
||
{
|
||
/*set_audio_device_volume(AUDIO_MIX_FRONT_VOL, front_volume);
|
||
set_audio_device_volume(AUDIO_MIX_BACK_VOL, back_volume);*/
|
||
}
|
||
#if 0
|
||
|
||
void audio_vol_test()
|
||
{
|
||
app_set_sys_vol(10, 10);
|
||
log_info("sys vol %d %d\n", get_audio_device_volume(AUDIO_SYS_VOL) >> 16, get_audio_device_volume(AUDIO_SYS_VOL) & 0xffff);
|
||
log_info("ana vol %d %d\n", get_audio_device_volume(AUDIO_ANA_VOL) >> 16, get_audio_device_volume(AUDIO_ANA_VOL) & 0xffff);
|
||
log_info("dig vol %d %d\n", get_audio_device_volume(AUDIO_DIG_VOL) >> 16, get_audio_device_volume(AUDIO_DIG_VOL) & 0xffff);
|
||
log_info("max vol %d %d\n", get_audio_device_volume(AUDIO_MAX_VOL) >> 16, get_audio_device_volume(AUDIO_MAX_VOL) & 0xffff);
|
||
|
||
app_set_max_vol(30);
|
||
app_set_ana_vol(25, 24);
|
||
app_set_dig_vol(90, 90);
|
||
|
||
log_info("sys vol %d %d\n", get_audio_device_volume(AUDIO_SYS_VOL) >> 16, get_audio_device_volume(AUDIO_SYS_VOL) & 0xffff);
|
||
log_info("ana vol %d %d\n", get_audio_device_volume(AUDIO_ANA_VOL) >> 16, get_audio_device_volume(AUDIO_ANA_VOL) & 0xffff);
|
||
log_info("dig vol %d %d\n", get_audio_device_volume(AUDIO_DIG_VOL) >> 16, get_audio_device_volume(AUDIO_DIG_VOL) & 0xffff);
|
||
log_info("max vol %d %d\n", get_audio_device_volume(AUDIO_MAX_VOL) >> 16, get_audio_device_volume(AUDIO_MAX_VOL) & 0xffff);
|
||
}
|
||
#endif
|
||
|
||
void dac_power_on(void)
|
||
{
|
||
log_info(">>>dac_power_on:%d", __this->ref.counter);
|
||
#if TCFG_AUDIO_DAC_ENABLE
|
||
if (atomic_inc_return(&__this->ref) == 1) {
|
||
audio_dac_open(&dac_hdl);
|
||
}
|
||
#endif // #if TCFG_AUDIO_DAC_ENABLE
|
||
}
|
||
|
||
void dac_power_off(void)
|
||
{
|
||
#if TCFG_AUDIO_DAC_ENABLE
|
||
/*log_info(">>>dac_power_off:%d", __this->ref.counter);*/
|
||
if (atomic_read(&__this->ref) != 0 && atomic_dec_return(&__this->ref)) {
|
||
return;
|
||
}
|
||
#if 0
|
||
app_audio_mute(AUDIO_MUTE_DEFAULT);
|
||
if (dac_hdl.vol_l || dac_hdl.vol_r) {
|
||
u8 fade_time = dac_hdl.vol_l * 2 / 10 + 1;
|
||
os_time_dly(fade_time);
|
||
printf("fade_time:%d ms", fade_time);
|
||
}
|
||
#endif
|
||
audio_dac_close(&dac_hdl);
|
||
#endif // #if TCFG_AUDIO_DAC_ENABLE
|
||
}
|
||
|
||
#if 0
|
||
/*
|
||
*写到dac buf的数据接口
|
||
*/
|
||
void audio_write_data_hook(void *data, u32 len)
|
||
{
|
||
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
*dac快速校准
|
||
*/
|
||
//#define DAC_TRIM_FAST_EN
|
||
#ifdef DAC_TRIM_FAST_EN
|
||
u8 dac_trim_fast_en()
|
||
{
|
||
return 1;
|
||
}
|
||
#endif/*DAC_TRIM_FAST_EN*/
|
||
|
||
/*
|
||
*自定义dac上电延时时间,具体延时多久应通过示波器测量
|
||
*/
|
||
#if 1
|
||
void dac_power_on_delay()
|
||
{
|
||
#if TCFG_MC_BIAS_AUTO_ADJUST
|
||
void mic_capless_auto_adjust_init();
|
||
mic_capless_auto_adjust_init();
|
||
#endif
|
||
os_time_dly(50);
|
||
}
|
||
#endif
|
||
|
||
#define TRIM_VALUE_LR_ERR_MAX (600) // 距离参考值的差值限制
|
||
#define abs(x) ((x)>0?(x):-(x))
|
||
int audio_dac_trim_value_check(struct audio_dac_trim *dac_trim)
|
||
{
|
||
printf("audio_dac_trim_value_check %d %d\n", dac_trim->left, dac_trim->right);
|
||
s16 reference = 0;
|
||
if (TCFG_AUDIO_DAC_CONNECT_MODE != DAC_OUTPUT_MONO_R) {
|
||
if (abs(dac_trim->left - reference) > TRIM_VALUE_LR_ERR_MAX) {
|
||
log_error("dac trim channel l err\n");
|
||
return -1;
|
||
}
|
||
}
|
||
if (TCFG_AUDIO_DAC_CONNECT_MODE != DAC_OUTPUT_MONO_L) {
|
||
if (abs(dac_trim->right - reference) > TRIM_VALUE_LR_ERR_MAX) {
|
||
log_error("dac trim channel r err\n");
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
*capless模式一开始不要的数据包数量
|
||
*/
|
||
u16 get_ladc_capless_dump_num(void)
|
||
{
|
||
return 10;
|
||
}
|
||
|
||
extern struct adc_platform_data adc_data;
|
||
int read_mic_type_config(void)
|
||
{
|
||
MIC_TYPE_CONFIG mic_type;
|
||
int ret = syscfg_read(CFG_MIC_TYPE_ID, &mic_type, sizeof(MIC_TYPE_CONFIG));
|
||
if (ret > 0) {
|
||
log_info_hexdump(&mic_type, sizeof(MIC_TYPE_CONFIG));
|
||
adc_data.mic_capless = mic_type.type;
|
||
adc_data.mic_bias_res = mic_type.pull_up;
|
||
adc_data.mic_ldo_vsel = mic_type.ldo_lev;
|
||
return 0;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
|