1824 lines
54 KiB
C
1824 lines
54 KiB
C
#include "system/includes.h"
|
||
#include "media/includes.h"
|
||
|
||
#include "app_config.h"
|
||
#include "app_action.h"
|
||
#include "app_main.h"
|
||
|
||
#include "audio_config.h"
|
||
|
||
#include "audio_dec.h"
|
||
|
||
#include "application/audio_output_dac.h"
|
||
#include "application/audio_dig_vol.h"
|
||
struct audio_dac_hdl dac_hdl;
|
||
|
||
#if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_FM)
|
||
#include "fm_emitter/fm_emitter_manage.h"
|
||
#endif
|
||
|
||
#include "update.h"
|
||
|
||
#if (defined(AUDIO_OUTPUT_WAY) && AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_BT)
|
||
extern void bt_emitter_set_vol(u8 vol);
|
||
#endif
|
||
|
||
#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;
|
||
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 save_vol_timer;
|
||
volatile u8 save_vol_cnt;
|
||
s16 digital_volume;
|
||
atomic_t ref;
|
||
s16 max_volume[APP_AUDIO_MAX_STATE];
|
||
u8 sys_cvol_max;
|
||
u8 call_cvol_max;
|
||
unaligned_u16 *sys_cvol;
|
||
unaligned_u16 *call_cvol;
|
||
};
|
||
static const char *audio_state[] = {
|
||
"idle",
|
||
"music",
|
||
"call",
|
||
"tone",
|
||
"linein",
|
||
"err",
|
||
};
|
||
|
||
struct dac_ch_delay_config {
|
||
u32 delay_time;
|
||
u32 protect_time;
|
||
u32 start_delay;
|
||
};
|
||
|
||
static struct app_audio_config app_audio_cfg = {0};
|
||
static struct dac_ch_delay_config dac_ch_delay_cfg = {0};
|
||
|
||
#define __this (&app_audio_cfg)
|
||
extern struct dac_platform_data dac_data;
|
||
extern struct audio_dac_hdl dac_hdl;
|
||
extern struct audio_adc_hdl adc_hdl;
|
||
OS_SEM dac_sem;
|
||
|
||
#if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_DONGLE)
|
||
s16 dac_buff[1 * 1024] SEC(.dac_buff);
|
||
#elif (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_IIS)
|
||
s16 dac_buff[1 * 1024] SEC(.dac_buff);
|
||
#elif AUDIO_OUTPUT_INCLUDE_DAC
|
||
s16 dac_buff[4 * 1024] SEC(.dac_buff);
|
||
/* s16 dac_buff[128] SEC(.dac_buff); */
|
||
#endif
|
||
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Set Dac Channel Delay Time
|
||
* Description: 设置DAC 通道的启动延时
|
||
* Arguments : dac_delay_ms 启动延时(单位:ms,传0代表使用默认配置)
|
||
* save_last_config_en 是否保存上一次DAC的延时配置(1:保存,0:不保存)
|
||
* Return : NULL
|
||
* Note(s) : 该接口用于设置DAC通道启动的延时
|
||
*********************************************************************
|
||
*/
|
||
void set_dac_start_delay_time(u16 dac_delay_ms, u8 save_last_config_en)
|
||
{
|
||
struct audio_dac_channel_attr attr;
|
||
audio_dac_channel_get_attr(&default_dac, &attr);
|
||
if (save_last_config_en) {
|
||
dac_ch_delay_cfg.delay_time = attr.delay_time;
|
||
dac_ch_delay_cfg.start_delay = attr.start_delay;
|
||
dac_ch_delay_cfg.protect_time = attr.protect_time;
|
||
}
|
||
if (dac_delay_ms) {
|
||
attr.start_delay = dac_delay_ms;
|
||
attr.protect_time = 0;
|
||
audio_dac_channel_set_attr(&default_dac, &attr);
|
||
} else {
|
||
attr.delay_time = dac_ch_delay_cfg.delay_time;
|
||
attr.protect_time = dac_ch_delay_cfg.protect_time;
|
||
attr.start_delay = dac_ch_delay_cfg.start_delay;
|
||
audio_dac_channel_set_attr(&default_dac, &attr);
|
||
}
|
||
}
|
||
|
||
/*从audio中申请一块空间给use使用*/
|
||
void *app_audio_alloc_use_buff(int use_len)
|
||
{
|
||
void *buf = NULL;
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
printf("uselen:%d, total:%d \n", use_len, sizeof(dac_buff));
|
||
if (use_len + (2 * 1024) > sizeof(dac_buff)) {
|
||
y_printf("dac buff < uselen\n");
|
||
return NULL;
|
||
}
|
||
int dac_len = ((sizeof(dac_buff) - use_len) * 4) / 4;
|
||
audio_dac_reset_buf(&dac_hdl, dac_buff, dac_len, 0);
|
||
return (u8 *)dac_buff + dac_len;
|
||
#endif
|
||
return buf;
|
||
}
|
||
|
||
/*释放从audio中申请的空间*/
|
||
void app_audio_release_use_buff(void *buf)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
printf("app_audio_release_use_buff \n");
|
||
if (buf) {
|
||
audio_dac_reset_buf(&dac_hdl, dac_buff, sizeof(dac_buff), 1);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
/*关闭audio相关模块使能*/
|
||
void audio_disable_all(void)
|
||
{
|
||
//DAC:DACEN
|
||
JL_AUDIO->DAC_CON &= ~BIT(4);
|
||
//ADC:ADCEN
|
||
JL_AUDIO->ADC_CON &= ~BIT(4);
|
||
//EQ:
|
||
JL_EQ->CON0 &= ~BIT(0);
|
||
//FFT:
|
||
JL_FFT->CON = BIT(1);//置1强制关闭模块,不管是否已经运算完成
|
||
}
|
||
|
||
REGISTER_UPDATE_TARGET(audio_update_target) = {
|
||
.name = "audio",
|
||
.driver_close = audio_disable_all,
|
||
};
|
||
/*
|
||
*************************************************************
|
||
*
|
||
* audio volume save
|
||
*
|
||
*************************************************************
|
||
*/
|
||
|
||
static void app_audio_volume_save_do(void *priv)
|
||
{
|
||
/* log_info("app_audio_volume_save_do %d\n", __this->save_vol_cnt); */
|
||
local_irq_disable();
|
||
if (++__this->save_vol_cnt >= 5) {
|
||
sys_timer_del(__this->save_vol_timer);
|
||
__this->save_vol_timer = 0;
|
||
__this->save_vol_cnt = 0;
|
||
local_irq_enable();
|
||
log_info("VOL_SAVE\n");
|
||
syscfg_write(CFG_MUSIC_VOL, &app_var.music_volume, 1);//中断里不能操作vm 关中断不能操作vm
|
||
return;
|
||
}
|
||
local_irq_enable();
|
||
}
|
||
|
||
static void app_audio_volume_change(void)
|
||
{
|
||
local_irq_disable();
|
||
__this->save_vol_cnt = 0;
|
||
if (__this->save_vol_timer == 0) {
|
||
__this->save_vol_timer = sys_timer_add(NULL, app_audio_volume_save_do, 1000);//中断里不能操作vm 关中断不能操作vm
|
||
}
|
||
local_irq_enable();
|
||
}
|
||
|
||
#if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_BT)
|
||
__attribute__((weak))
|
||
void bt_emitter_set_vol(u8 vol)
|
||
{
|
||
|
||
}
|
||
#endif
|
||
|
||
static int audio_vol_set(u8 gain_l, u8 gain_r, u8 fade)
|
||
{
|
||
#if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_FM)
|
||
return 0;
|
||
#endif
|
||
|
||
#if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_IIS)
|
||
extern void *iis_digvol_last;
|
||
if (iis_digvol_last) {
|
||
audio_dig_vol_set(iis_digvol_last, AUDIO_DIG_VOL_ALL_CH, gain_l);
|
||
}
|
||
#endif
|
||
|
||
#if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_BT)
|
||
bt_emitter_set_vol(gain_l);
|
||
#endif
|
||
local_irq_disable();
|
||
__this->fade_gain_l = gain_l;
|
||
__this->fade_gain_r = gain_r;
|
||
|
||
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_MONO_L)
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(0), gain_l, fade);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, BIT(0), gain_l ? DEFAULT_DIGTAL_VOLUME : 0, fade);
|
||
#elif (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_MONO_R)
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(1), gain_r, fade);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, BIT(0), gain_r ? DEFAULT_DIGTAL_VOLUME : 0, fade);
|
||
#else
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(0), gain_l, fade);
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(1), gain_r, fade);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, BIT(0), gain_l ? DEFAULT_DIGTAL_VOLUME : 0, fade);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, BIT(1), gain_r ? DEFAULT_DIGTAL_VOLUME : 0, fade);
|
||
#endif
|
||
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[31][2] = {
|
||
{ 0, 0}, //0: None
|
||
{ 0, 16384}, // 1:-40.92 db
|
||
{ 2, 14124}, // 2:-39.51 db
|
||
{ 3, 14240}, // 3:-38.10 db
|
||
{ 4, 14326}, // 4:-36.69 db
|
||
{ 5, 14427}, // 5:-35.28 db
|
||
{ 6, 14562}, // 6:-33.87 db
|
||
{ 7, 14681}, // 7:-32.46 db
|
||
{ 8, 14802}, // 8:-31.05 db
|
||
{ 9, 14960}, // 9:-29.64 db
|
||
{10, 15117}, // 10:-28.22 db
|
||
{11, 15276}, // 11:-26.81 db
|
||
{12, 15366}, // 12:-25.40 db
|
||
{13, 15528}, // 13:-23.99 db
|
||
{14, 15675}, // 14:-22.58 db
|
||
{15, 15731}, // 15:-21.17 db
|
||
{16, 15535}, // 16:-19.76 db
|
||
{17, 15609}, // 17:-18.35 db
|
||
{18, 15684}, // 18:-16.93 db
|
||
{19, 15777}, // 19:-15.52 db
|
||
{20, 15851}, // 20:-14.11 db
|
||
{21, 15945}, // 21:-12.70 db
|
||
{22, 16002}, // 22:-11.29 db
|
||
{23, 16006}, // 23:-9.88 db
|
||
{24, 16050}, // 24:-8.47 db
|
||
{25, 16089}, // 25:-7.06 db
|
||
{26, 16154}, // 26:-5.64 db
|
||
{27, 16230}, // 27:-4.23 db
|
||
{28, 16279}, // 28:-2.82 db
|
||
{29, 16328}, // 29:-1.41 db
|
||
{30, 16384}, // 30:0.00 db
|
||
};
|
||
static unsigned short call_combined_vol_list[16][2] = {
|
||
{ 0, 0}, //0: None
|
||
{ 0, 16384}, // 1:-40.92 db
|
||
{ 2, 15345}, // 2:-38.79 db
|
||
{ 4, 14374}, // 3:-36.66 db
|
||
{ 5, 15726}, // 4:-34.53 db
|
||
{ 7, 14782}, // 5:-32.40 db
|
||
{ 8, 16191}, // 6:-30.27 db
|
||
{10, 15271}, // 7:-28.14 db
|
||
{12, 14336}, // 8:-26.00 db
|
||
{13, 15739}, // 9:-23.87 db
|
||
{15, 14725}, // 10:-21.74 db
|
||
{16, 15799}, // 11:-19.61 db
|
||
{18, 14731}, // 12:-17.48 db
|
||
{19, 16098}, // 13:-15.35 db
|
||
{21, 15027}, // 14:-13.22 db
|
||
{22, 16384}, // 15:-11.09 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;
|
||
s16 *cvol;
|
||
|
||
log_info("audio_combined_vol_init\n");
|
||
__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);
|
||
if (sys_cvol && sys_cvol_len) {
|
||
__this->sys_cvol = (unaligned_u16 *)sys_cvol;
|
||
__this->sys_cvol_max = sys_cvol_len / 4 - 1;
|
||
printf("read sys_cvol ok\n");
|
||
} else {
|
||
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);
|
||
if (call_cvol && call_cvol_len) {
|
||
__this->call_cvol = (unaligned_u16 *)call_cvol;
|
||
__this->call_cvol_max = call_cvol_len / 4 - 1;
|
||
printf("read call_cvol ok\n");
|
||
} else {
|
||
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_vol_set(u8 gain_l, u8 gain_r, u8 fade)
|
||
{
|
||
#if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_FM)
|
||
return 0;
|
||
#endif
|
||
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]);
|
||
}
|
||
y_printf("[l]v:%d,Av:%d,Dv:%d", gain_l, target_again_l, target_dgain_l);
|
||
|
||
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 (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_MONO_L)
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(0), __this->fade_gain_l, fade);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, BIT(0), __this->fade_dgain_l, fade);
|
||
#elif (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_MONO_R)
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(1), __this->fade_gain_r, fade);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, BIT(0), __this->fade_dgain_r, fade);
|
||
#else
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(0), __this->fade_gain_l, fade);
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(1), __this->fade_gain_r, fade);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, BIT(0), __this->fade_dgain_l, fade);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, BIT(1), __this->fade_dgain_r, fade);
|
||
#endif
|
||
|
||
local_irq_enable();
|
||
|
||
return 0;
|
||
}
|
||
|
||
#endif // (SYS_VOL_TYPE == VOL_TYPE_AD)
|
||
|
||
|
||
void volume_up_down_direct(s8 value)
|
||
{
|
||
// reserve
|
||
}
|
||
|
||
void audio_fade_in_fade_out(u8 left_gain, u8 right_gain, u8 fade)
|
||
{
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_AD)
|
||
audio_combined_vol_set(left_gain, right_gain, fade);
|
||
#else
|
||
audio_vol_set(left_gain, right_gain, fade);
|
||
#endif/*SYS_VOL_TYPE == VOL_TYPE_AD*/
|
||
}
|
||
|
||
|
||
|
||
extern char *music_dig_logo[];
|
||
|
||
extern void *sys_digvol_group;
|
||
|
||
|
||
void app_audio_set_volume(u8 state, s8 volume, u8 fade)
|
||
{
|
||
|
||
char *digvol_type = NULL ;
|
||
|
||
#if (SMART_BOX_EN)
|
||
extern bool smartbox_set_volume(s8 volume);
|
||
if (smartbox_set_volume(volume)) {
|
||
return;
|
||
}
|
||
#endif/*SMART_BOX_EN*/
|
||
|
||
switch (state) {
|
||
case APP_AUDIO_STATE_IDLE:
|
||
case APP_AUDIO_STATE_MUSIC:
|
||
case APP_AUDIO_STATE_LINEIN:
|
||
#if SYS_DIGVOL_GROUP_EN
|
||
digvol_type = "music_type";
|
||
#endif/*SYS_DIGVOL_GROUP_EN*/
|
||
app_var.music_volume = volume;
|
||
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:
|
||
#if SYS_DIGVOL_GROUP_EN
|
||
digvol_type = "call_esco";
|
||
#endif/*SYS_DIGVOL_GROUP_EN*/
|
||
app_var.call_volume = volume;
|
||
if (app_var.call_volume > 15) {
|
||
app_var.call_volume = 15;
|
||
}
|
||
#if (SYS_VOL_TYPE == VOL_TYPE_ANALOG)
|
||
/*
|
||
*SYS_VOL_TYPE == VOL_TYPE_ANALOG的时候,
|
||
*将通话音量最大值按照手机通话的音量等级进行等分
|
||
*由于等级不匹配,会出现对应有些等级没有一一对应
|
||
*的情况,如果在意,建议使用以下其中一种:
|
||
*#define TCFG_CALL_USE_DIGITAL_VOLUME 1
|
||
*#define SYS_VOL_TYPE VOL_TYPE_AD
|
||
*#define SYS_VOL_TYPE VOL_TYPE_DIGITAL
|
||
*/
|
||
volume = app_var.aec_dac_gain * app_var.call_volume / 15;
|
||
#endif/*SYS_VOL_TYPE == VOL_TYPE_ANALOG*/
|
||
|
||
#if TCFG_CALL_USE_DIGITAL_VOLUME
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, \
|
||
BIT(0) | BIT(1), \
|
||
16384L * (s32)app_var.call_volume / (s32)__this->max_volume[APP_AUDIO_STATE_CALL], \
|
||
1);
|
||
return;
|
||
#endif/*TCFG_CALL_USE_DIGITAL_VOLUME*/
|
||
break;
|
||
case APP_AUDIO_STATE_WTONE:
|
||
#if SYS_DIGVOL_GROUP_EN
|
||
digvol_type = "tone_tone";
|
||
#endif/*SYS_DIGVOL_GROUP_EN*/
|
||
|
||
#if TONE_MODE_DEFAULE_VOLUME != 0
|
||
app_var.wtone_volume = TONE_MODE_DEFAULE_VOLUME;
|
||
volume = app_var.wtone_volume;
|
||
break;
|
||
#endif
|
||
|
||
#if APP_AUDIO_STATE_WTONE_BY_MUSIC == 1
|
||
|
||
|
||
app_var.wtone_volume = app_var.music_volume;
|
||
if (app_var.wtone_volume < 5) {
|
||
app_var.wtone_volume = 5;
|
||
}
|
||
#else
|
||
app_var.wtone_volume = volume;
|
||
#endif
|
||
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;
|
||
}
|
||
if (state == __this->state) {
|
||
#if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_FM)
|
||
fm_emitter_manage_set_vol(volume);
|
||
#else
|
||
#if defined (VOL_TYPE_DIGGROUP) && defined (SYS_DIGVOL_GROUP_EN)
|
||
if (state == APP_AUDIO_STATE_LINEIN) {
|
||
//printf("linein analog vol:%d\n",volume);
|
||
audio_fade_in_fade_out(volume, volume, fade);
|
||
return;
|
||
}
|
||
if (SYS_VOL_TYPE == VOL_TYPE_DIGGROUP && SYS_DIGVOL_GROUP_EN) {
|
||
if (sys_digvol_group == NULL) {
|
||
/* printf("the sys_digvol_group is NULL\n-------------------------------------------------------------"); */
|
||
return;
|
||
}
|
||
if (strcmp(digvol_type, "music_type") == 0) {
|
||
for (int i = 0; strcmp(music_dig_logo[i], "NULL") != 0; i++) {
|
||
/* printf("%s\n", music_dig_logo[i]); */
|
||
if (audio_dig_vol_group_hdl_get(sys_digvol_group, music_dig_logo[i]) == NULL) {
|
||
continue;
|
||
}
|
||
audio_dig_vol_set(audio_dig_vol_group_hdl_get(sys_digvol_group, music_dig_logo[i]), AUDIO_DIG_VOL_ALL_CH, volume);
|
||
}
|
||
} else {
|
||
if (audio_dig_vol_group_hdl_get(sys_digvol_group, digvol_type) == NULL) {
|
||
return;
|
||
}
|
||
audio_dig_vol_set(audio_dig_vol_group_hdl_get(sys_digvol_group, digvol_type), AUDIO_DIG_VOL_ALL_CH, volume);
|
||
}
|
||
}
|
||
|
||
else {
|
||
audio_fade_in_fade_out(volume, volume, fade);
|
||
}
|
||
|
||
#else
|
||
|
||
audio_fade_in_fade_out(volume, volume, fade);
|
||
#endif //vol_type_diggroup
|
||
|
||
|
||
|
||
#endif //audio_output_way
|
||
}
|
||
app_audio_volume_change();
|
||
}
|
||
|
||
void app_audio_set_volume_each_channel(u8 state, s8 volume_l, s8 volume_r, u8 fade)
|
||
{
|
||
char *digvol_type = NULL ;
|
||
switch (state) {
|
||
case APP_AUDIO_STATE_IDLE:
|
||
case APP_AUDIO_STATE_MUSIC:
|
||
case APP_AUDIO_STATE_LINEIN:
|
||
#if SYS_DIGVOL_GROUP_EN
|
||
digvol_type = "music_type";
|
||
#endif
|
||
app_var.music_volume = volume_l;
|
||
app_var.music_volume_r = volume_r;
|
||
if (app_var.music_volume > get_max_sys_vol()) {
|
||
app_var.music_volume = get_max_sys_vol();
|
||
}
|
||
if (app_var.music_volume_r > get_max_sys_vol()) {
|
||
app_var.music_volume_r = get_max_sys_vol();
|
||
}
|
||
|
||
volume_l = app_var.music_volume;
|
||
volume_r = app_var.music_volume_r;
|
||
break;
|
||
case APP_AUDIO_STATE_CALL:
|
||
#if SYS_DIGVOL_GROUP_EN
|
||
digvol_type = "call_esco";
|
||
#endif
|
||
|
||
app_var.call_volume = volume_l;
|
||
app_var.call_volume_r = volume_r;
|
||
if (app_var.call_volume > 15) {
|
||
app_var.call_volume = 15;
|
||
}
|
||
if (app_var.call_volume_r > 15) {
|
||
app_var.call_volume_r = 15;
|
||
}
|
||
|
||
volume_l = app_var.aec_dac_gain * app_var.call_volume / 15;
|
||
volume_r = app_var.aec_dac_gain * app_var.call_volume_r / 15;
|
||
#if TCFG_CALL_USE_DIGITAL_VOLUME
|
||
audio_digital_vol_set(volume_l);
|
||
return;
|
||
#endif
|
||
break;
|
||
case APP_AUDIO_STATE_WTONE:
|
||
#if SYS_DIGVOL_GROUP_EN
|
||
digvol_type = "tone_tone";
|
||
#endif
|
||
|
||
|
||
#if (TONE_MODE_DEFAULE_VOLUME != 0)
|
||
app_var.wtone_volume = TONE_MODE_DEFAULE_VOLUME;
|
||
volume_l = volume_r = app_var.wtone_volume;
|
||
break;
|
||
#endif
|
||
#if (APP_AUDIO_STATE_WTONE_BY_MUSIC == 1)
|
||
app_var.wtone_volume = app_var.music_volume;
|
||
app_var.wtone_volume_r = app_var.music_volume_r;
|
||
if (app_var.wtone_volume < 5) {
|
||
app_var.wtone_volume = 5;
|
||
}
|
||
if (app_var.wtone_volume_r < 5) {
|
||
app_var.wtone_volume_r = 5;
|
||
}
|
||
|
||
#else
|
||
app_var.wtone_volume = volume_l;
|
||
app_var.wtone_volume_r = volume_r;
|
||
#endif
|
||
if (app_var.wtone_volume > get_max_sys_vol()) {
|
||
app_var.wtone_volume = get_max_sys_vol();
|
||
}
|
||
if (app_var.wtone_volume_r > get_max_sys_vol()) {
|
||
app_var.wtone_volume_r = get_max_sys_vol();
|
||
}
|
||
|
||
volume_l = app_var.wtone_volume;
|
||
volume_r = app_var.wtone_volume_r;
|
||
break;
|
||
default:
|
||
return;
|
||
}
|
||
|
||
if (state == __this->state) {
|
||
#if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_FM)
|
||
fm_emitter_manage_set_vol(volume);
|
||
#else
|
||
#if defined (VOL_TYPE_DIGGROUP) && defined (SYS_DIGVOL_GROUP_EN)
|
||
if (state == APP_AUDIO_STATE_LINEIN) {
|
||
//printf("linein analog vol:%d\n",volume);
|
||
audio_fade_in_fade_out(volume_l, volume_r, fade);
|
||
return;
|
||
}
|
||
|
||
if (SYS_VOL_TYPE == VOL_TYPE_DIGGROUP && SYS_DIGVOL_GROUP_EN) {
|
||
if (sys_digvol_group == NULL) {
|
||
/* printf("the sys_digvol_group is NULL\n-------------------------------------------------------------"); */
|
||
return;
|
||
}
|
||
if (strcmp(digvol_type, "music_type") == 0) {
|
||
for (int i = 0; music_dig_logo[i] != "NULL"; i++) {
|
||
/* printf("%s\n", music_dig_logo[i]); */
|
||
if (audio_dig_vol_group_hdl_get(sys_digvol_group, music_dig_logo[i]) == NULL) {
|
||
continue;
|
||
}
|
||
|
||
audio_dig_vol_set(audio_dig_vol_group_hdl_get(sys_digvol_group, digvol_type), AUDIO_DIG_VOL_CH(0), volume_l);
|
||
audio_dig_vol_set(audio_dig_vol_group_hdl_get(sys_digvol_group, digvol_type), AUDIO_DIG_VOL_CH(1), volume_r);
|
||
|
||
/* audio_dig_vol_group_vol_set(sys_digvol_group, music_dig_logo[i], AUDIO_DIG_VOL_ALL_CH, volume); */
|
||
}
|
||
} else {
|
||
if (audio_dig_vol_group_hdl_get(sys_digvol_group, digvol_type) == NULL) {
|
||
return;
|
||
}
|
||
|
||
audio_dig_vol_set(audio_dig_vol_group_hdl_get(sys_digvol_group, digvol_type), AUDIO_DIG_VOL_CH(0), volume_l);
|
||
audio_dig_vol_set(audio_dig_vol_group_hdl_get(sys_digvol_group, digvol_type), AUDIO_DIG_VOL_CH(1), volume_r);
|
||
|
||
/* audio_dig_vol_group_vol_set(sys_digvol_group, digvol_type, AUDIO_DIG_VOL_ALL_CH, volume); */
|
||
}
|
||
} else {
|
||
audio_fade_in_fade_out(volume_l, volume_r, fade);
|
||
}
|
||
|
||
#else
|
||
audio_fade_in_fade_out(volume_l, volume_r, fade);
|
||
#endif //vol_type_diggroup
|
||
|
||
#endif //audio_output_way
|
||
|
||
}
|
||
app_audio_volume_change();
|
||
}
|
||
|
||
|
||
void app_audio_volume_init(void)
|
||
{
|
||
app_audio_set_volume(APP_AUDIO_STATE_MUSIC, app_var.music_volume, 1);
|
||
}
|
||
|
||
s8 app_audio_get_volume(u8 state)
|
||
{
|
||
s8 volume = 0;
|
||
switch (state) {
|
||
case APP_AUDIO_STATE_IDLE:
|
||
case APP_AUDIO_STATE_MUSIC:
|
||
case APP_AUDIO_STATE_LINEIN:
|
||
volume = app_var.music_volume;
|
||
break;
|
||
case APP_AUDIO_STATE_CALL:
|
||
volume = app_var.call_volume;
|
||
break;
|
||
case APP_AUDIO_STATE_WTONE:
|
||
#if TONE_MODE_DEFAULE_VOLUME != 0
|
||
app_var.wtone_volume = TONE_MODE_DEFAULE_VOLUME;
|
||
volume = app_var.wtone_volume;
|
||
break;
|
||
#endif
|
||
#if APP_AUDIO_STATE_WTONE_BY_MUSIC == 1
|
||
volume = app_var.music_volume;
|
||
break;
|
||
#else
|
||
volume = app_var.wtone_volume;
|
||
/* if (!volume) { */
|
||
/* volume = app_var.music_volume; */
|
||
/* } */
|
||
break;
|
||
#endif
|
||
case APP_AUDIO_CURRENT_STATE:
|
||
volume = app_audio_get_volume(__this->state);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
/* printf("app_audio_get_volume %d %d\n", state, volume); */
|
||
return volume;
|
||
}
|
||
|
||
|
||
static const char *audio_mute_string[] = {
|
||
"mute_default",
|
||
"unmute_default",
|
||
"mute_L",
|
||
"unmute_L",
|
||
"mute_R",
|
||
"unmute_R",
|
||
};
|
||
|
||
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_OUTPUT_WAY == AUDIO_OUTPUT_WAY_FM)
|
||
fm_emitter_manage_set_vol(0);
|
||
#else
|
||
audio_dac_vol_mute(1, 1);
|
||
#endif
|
||
break;
|
||
case AUDIO_UNMUTE_DEFAULT:
|
||
#if (AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_FM)
|
||
volume = app_audio_get_volume(APP_AUDIO_CURRENT_STATE);
|
||
fm_emitter_manage_set_vol(volume);
|
||
#else
|
||
audio_dac_vol_mute(0, 1);
|
||
#endif
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
void app_audio_volume_up(u8 value)
|
||
{
|
||
#if (SMART_BOX_EN)
|
||
extern bool smartbox_key_volume_up(u8 value);
|
||
if (smartbox_key_volume_up(value)) {
|
||
return;
|
||
}
|
||
#endif
|
||
s16 volume = 0;
|
||
switch (__this->state) {
|
||
case APP_AUDIO_STATE_IDLE:
|
||
case APP_AUDIO_STATE_MUSIC:
|
||
case APP_AUDIO_STATE_LINEIN:
|
||
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 (app_var.call_volume > 15) {
|
||
app_var.call_volume = 15;
|
||
}
|
||
volume = app_var.call_volume;
|
||
break;
|
||
case APP_AUDIO_STATE_WTONE:
|
||
#if TONE_MODE_DEFAULE_VOLUME != 0
|
||
app_var.wtone_volume = TONE_MODE_DEFAULE_VOLUME;
|
||
volume = app_var.wtone_volume;
|
||
break;
|
||
#endif
|
||
#if APP_AUDIO_STATE_WTONE_BY_MUSIC == 1
|
||
app_var.wtone_volume = app_var.music_volume;
|
||
#endif
|
||
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;
|
||
#if APP_AUDIO_STATE_WTONE_BY_MUSIC == 1
|
||
app_var.music_volume = app_var.wtone_volume;
|
||
#endif
|
||
break;
|
||
default:
|
||
return;
|
||
}
|
||
|
||
app_audio_set_volume(__this->state, volume, 1);
|
||
}
|
||
|
||
void app_audio_volume_down(u8 value)
|
||
{
|
||
#if (SMART_BOX_EN)
|
||
extern bool samrtbox_key_volume_down(u8 value);
|
||
if (smartbox_key_volume_up(value)) {
|
||
return;
|
||
}
|
||
#endif
|
||
s16 volume = 0;
|
||
switch (__this->state) {
|
||
case APP_AUDIO_STATE_IDLE:
|
||
case APP_AUDIO_STATE_MUSIC:
|
||
case APP_AUDIO_STATE_LINEIN:
|
||
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;
|
||
break;
|
||
case APP_AUDIO_STATE_WTONE:
|
||
#if TONE_MODE_DEFAULE_VOLUME != 0
|
||
app_var.wtone_volume = TONE_MODE_DEFAULE_VOLUME;
|
||
volume = app_var.wtone_volume;
|
||
break;
|
||
#endif
|
||
#if APP_AUDIO_STATE_WTONE_BY_MUSIC == 1
|
||
app_var.wtone_volume = app_var.music_volume;
|
||
#endif
|
||
app_var.wtone_volume -= value;
|
||
if (app_var.wtone_volume < 0) {
|
||
app_var.wtone_volume = 0;
|
||
}
|
||
volume = app_var.wtone_volume;
|
||
#if APP_AUDIO_STATE_WTONE_BY_MUSIC == 1
|
||
app_var.music_volume = app_var.wtone_volume;
|
||
#endif
|
||
break;
|
||
default:
|
||
return;
|
||
}
|
||
|
||
app_audio_set_volume(__this->state, volume, 1);
|
||
}
|
||
|
||
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);
|
||
|
||
__this->prev_state = __this->state;
|
||
__this->state = state;
|
||
#if TCFG_CALL_USE_DIGITAL_VOLUME
|
||
if (__this->state == APP_AUDIO_STATE_CALL) {
|
||
/*调数字音量的时候,模拟音量定最大*/
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(0) | BIT(1), max_volume, 1);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, BIT(0) | BIT(1), 0, 1);
|
||
}
|
||
#endif
|
||
|
||
/*限制最大音量*/
|
||
__this->digital_volume = DEFAULT_DIGTAL_VOLUME;
|
||
__this->max_volume[state] = max_volume;
|
||
|
||
if (__this->state == APP_AUDIO_STATE_CALL) {
|
||
__this->max_volume[state] = 15;
|
||
}
|
||
|
||
|
||
|
||
#if (SYS_VOL_TYPE ==VOL_TYPE_DIGGROUP)
|
||
u8 dac_connect_mode = app_audio_output_mode_get();
|
||
switch (dac_connect_mode) {
|
||
case DAC_OUTPUT_MONO_L :
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(0), 30, 1);
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(1), 0, 1);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, BIT(0) | BIT(1), 16384, 1);
|
||
break;
|
||
case DAC_OUTPUT_MONO_R :
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(1), 30, 1);
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(0), 0, 1);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, BIT(0) | BIT(1), 16384, 1);
|
||
break;
|
||
|
||
default :
|
||
audio_dac_vol_set(TYPE_DAC_AGAIN, BIT(0) | BIT(1), 30, 1);
|
||
audio_dac_vol_set(TYPE_DAC_DGAIN, BIT(0) | BIT(1), 16384, 1);
|
||
|
||
}
|
||
#endif
|
||
|
||
|
||
app_audio_set_volume(__this->state, app_audio_get_volume(__this->state), 1);
|
||
}
|
||
|
||
void app_audio_state_exit(u8 state)
|
||
{
|
||
#if TCFG_CALL_USE_DIGITAL_VOLUME
|
||
if (__this->state == APP_AUDIO_STATE_CALL) {
|
||
}
|
||
#endif
|
||
|
||
r_printf("audio state now:%s,prev:%s\n", audio_state[__this->state], audio_state[__this->prev_state]);
|
||
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;
|
||
}
|
||
app_audio_set_volume(__this->state, app_audio_get_volume(__this->state), 1);
|
||
}
|
||
u8 app_audio_get_state(void)
|
||
{
|
||
return __this->state;
|
||
}
|
||
|
||
s16 app_audio_get_max_volume(void)
|
||
{
|
||
if (__this->state == APP_AUDIO_STATE_IDLE) {
|
||
return get_max_sys_vol();
|
||
}
|
||
return __this->max_volume[__this->state];
|
||
}
|
||
|
||
void dac_power_on(void)
|
||
{
|
||
log_info(">>>dac_power_on:%d", __this->ref.counter);
|
||
if (atomic_inc_return(&__this->ref) == 1) {
|
||
audio_dac_open(&dac_hdl);
|
||
}
|
||
|
||
}
|
||
void dac_sniff_power_off(void)
|
||
{
|
||
audio_dac_close(&dac_hdl);
|
||
}
|
||
|
||
void dac_power_off(void)
|
||
{
|
||
/* log_info(">>>dac_power_off:%d", __this->ref.counter); */
|
||
/* if (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);
|
||
}
|
||
/*
|
||
*自定义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/*TCFG_MC_BIAS_AUTO_ADJUST*/
|
||
os_time_dly(50);
|
||
}
|
||
#endif
|
||
|
||
#if TCFG_MIC_CAPLESS_ENABLE
|
||
|
||
//#define LADC_CAPLESS_INFO_DEBUG
|
||
#ifdef LADC_CAPLESS_INFO_DEBUG
|
||
/*
|
||
* adcdso:正负1000之内
|
||
* dacr32(正常范围:稳定在正负28000之内)
|
||
*/
|
||
void ladc_capless_info(s16 adcdso, s32 dacr32, s32 pout, s32 tmps8)
|
||
{
|
||
printf("[%d, %d, %d, %d]\n", adcdso, dacr32, pout, tmps8);
|
||
}
|
||
#endif
|
||
|
||
static void mic_capless_feedback_toggle(u8 toggle);
|
||
|
||
#define LADC_CAPLESS_ADJUST_SAVE
|
||
#ifdef LADC_CAPLESS_ADJUST_SAVE
|
||
#define DIFF_RANGE 50
|
||
#define CFG_DIFF_RANGE 200
|
||
#define CHECK_INTERVAL 7
|
||
#define DACR32_DEFAULT 32767
|
||
|
||
#define MIC_CAPLESS_ADJUST_BUD_DEFAULT 0
|
||
#define MIC_CAPLESS_ADJUST_BUD 100
|
||
/*不支持自动校准,使用快速收敛*/
|
||
#if TCFG_MC_BIAS_AUTO_ADJUST
|
||
u8 mic_capless_adjust_bud = MIC_CAPLESS_ADJUST_BUD_DEFAULT;
|
||
#else
|
||
u8 mic_capless_adjust_bud = MIC_CAPLESS_ADJUST_BUD;
|
||
#endif
|
||
|
||
s16 read_capless_DTB(void)
|
||
{
|
||
s16 dacr32 = 32767;
|
||
int ret = syscfg_read(CFG_DAC_DTB, &dacr32, 2);
|
||
printf("cfg DAC_DTB:%d,ret = %d\n", dacr32, ret);
|
||
/*没有记忆值,使用默认值*/
|
||
if (ret != 2) {
|
||
/*没有收敛值的时候,使用快速收敛*/
|
||
//printf("DAC_DTB NULL,use fast feedback");
|
||
mic_capless_adjust_bud = MIC_CAPLESS_ADJUST_BUD;
|
||
/*
|
||
*未初始化状态,返回默认收敛值。可以通过修改默认收敛值,使其
|
||
*接近最终收敛值,来加快预收敛时间。比如最终收敛值是-2500,则
|
||
*可以把默认收敛值设置成-2000左右,因为不同的样机稍微有点小差
|
||
*异,所以这个值不用那么精确,只要差不多就行了。
|
||
*/
|
||
return 32767;
|
||
}
|
||
return dacr32;
|
||
}
|
||
|
||
s16 read_vm_capless_DTB(void)
|
||
{
|
||
s16 vm_dacr32 = 32767;
|
||
int ret = syscfg_read(CFG_DAC_DTB, &vm_dacr32, 2);
|
||
printf("vm DAC_DTB:%d,ret = %d\n", vm_dacr32, ret);
|
||
if (ret != 2) {
|
||
return DACR32_DEFAULT;
|
||
}
|
||
return vm_dacr32;
|
||
}
|
||
|
||
s16 save_dacr32 = DACR32_DEFAULT;
|
||
static u8 adjust_complete = 0;
|
||
static u16 dtb_step_limit = 0; /*dtb收敛步进限制*/
|
||
void save_capless_DTB()
|
||
{
|
||
s16 diff;
|
||
//printf("save_capless_DTB\n");
|
||
if ((save_dacr32 != DACR32_DEFAULT) && adjust_complete) {
|
||
/*比较是否需要更新配置*/
|
||
s16 cfg_dacr32 = read_vm_capless_DTB();
|
||
adjust_complete = 0;
|
||
diff = save_dacr32 - cfg_dacr32;
|
||
if ((cfg_dacr32 == DACR32_DEFAULT) || ((diff < -CFG_DIFF_RANGE) || (diff > CFG_DIFF_RANGE))) {
|
||
log_info("dacr32 write:%d\n", save_dacr32);
|
||
syscfg_write(CFG_DAC_DTB, &save_dacr32, 2);
|
||
|
||
/* s16 tmp_dacr32;
|
||
syscfg_read(CFG_DAC_DTB,&tmp_dacr32,2);
|
||
printf("dacr32 read:%d\n",tmp_dacr32); */
|
||
} else {
|
||
log_info("dacr32 need't update:%d,diff:%d\n", save_dacr32, diff);
|
||
}
|
||
} else {
|
||
log_info("dacr32 adjust uncomplete:%d,complete:%d\n", save_dacr32, adjust_complete);
|
||
}
|
||
}
|
||
|
||
void ladc_capless_adjust_post(s32 dacr32, u8 begin)
|
||
{
|
||
static s32 last_dacr32 = 0;
|
||
static u8 check_cnt = 0;
|
||
|
||
s32 dacr32_diff;
|
||
|
||
/*adjust_begin,clear*/
|
||
if (begin) {
|
||
printf("dtb_step_limit = %d\n", dtb_step_limit);
|
||
last_dacr32 = 0;
|
||
adjust_complete = 0;
|
||
check_cnt = 0;
|
||
save_dacr32 = DACR32_DEFAULT;
|
||
return;
|
||
}
|
||
|
||
#if TCFG_MC_CONVERGE_TRACE
|
||
printf("<%d>", dacr32);
|
||
#endif/*MIC_CAPLESS_CONVERGE_TRACE*/
|
||
if (adjust_complete == 0) {
|
||
if (++check_cnt > CHECK_INTERVAL) {
|
||
check_cnt = 0;
|
||
dacr32_diff = dacr32 - last_dacr32;
|
||
//printf("[capless:%d-%d-%d]",dacr32,last_dacr32,dacr32_diff);
|
||
last_dacr32 = dacr32;
|
||
if (adjust_complete == 0) {
|
||
save_dacr32 = dacr32;
|
||
}
|
||
/*调整稳定*/
|
||
if ((dacr32_diff > -DIFF_RANGE) && (dacr32_diff < DIFF_RANGE)) {
|
||
log_info("adjust_OK:%d\n", dacr32);
|
||
adjust_complete = 1;
|
||
#if TCFG_MC_BIAS_AUTO_ADJUST
|
||
mic_capless_feedback_toggle(0);
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
*dac快速校准
|
||
*/
|
||
//#define DAC_TRIM_FAST_EN
|
||
#ifdef DAC_TRIM_FAST_EN
|
||
u8 dac_trim_fast_en()
|
||
{
|
||
return 1;
|
||
}
|
||
#endif
|
||
|
||
|
||
/*
|
||
*capless模式一开始不要的数据包数量
|
||
*/
|
||
u16 get_ladc_capless_dump_num(void)
|
||
{
|
||
return 10;
|
||
}
|
||
|
||
/*
|
||
*mic省电容模式自动收敛
|
||
*/
|
||
u8 mic_capless_feedback_sw = 0;
|
||
static u8 audio_mc_idle_query(void)
|
||
{
|
||
return (mic_capless_feedback_sw ? 0 : 1);
|
||
}
|
||
REGISTER_LP_TARGET(audio_mc_device_lp_target) = {
|
||
.name = "audio_mc_device",
|
||
.is_idle = audio_mc_idle_query,
|
||
};
|
||
|
||
/*快调慢调边界*/
|
||
u16 get_ladc_capless_bud(void)
|
||
{
|
||
//printf("mc_bud:%d",mic_capless_adjust_bud);
|
||
return mic_capless_adjust_bud;
|
||
}
|
||
|
||
extern int audio_adc_mic_init(u16 sr);
|
||
extern void audio_adc_mic_exit(void);
|
||
int audio_mic_capless_feedback_control(u8 en, u16 sr)
|
||
{
|
||
int ret = 0;
|
||
if (en) {
|
||
ret = audio_adc_mic_init(sr);
|
||
} else {
|
||
audio_adc_mic_exit();
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
OS_SEM mc_sem;
|
||
/*收敛的前提是偏置电压合法*/
|
||
static void mic_capless_feedback_toggle(u8 toggle)
|
||
{
|
||
int ret = 0;
|
||
log_info("mic_capless_feedback_toggle:%d-%d\n", mic_capless_feedback_sw, toggle);
|
||
if (toggle && (mic_capless_feedback_sw == 0)) {
|
||
mic_capless_feedback_sw = 1;
|
||
ret = audio_mic_capless_feedback_control(1, 32000);
|
||
if (ret == 0) {
|
||
mic_capless_adjust_bud = MIC_CAPLESS_ADJUST_BUD;
|
||
}
|
||
os_sem_create(&mc_sem, 0);
|
||
} else if (mic_capless_feedback_sw) {
|
||
os_sem_post(&mc_sem);
|
||
mic_capless_adjust_bud = MIC_CAPLESS_ADJUST_BUD_DEFAULT;
|
||
} else {
|
||
log_info("Nothing to do\n");
|
||
}
|
||
}
|
||
|
||
extern struct adc_platform_data adc_data;
|
||
|
||
#if TCFG_MC_BIAS_AUTO_ADJUST
|
||
static const u8 mic_bias_tab[] = {0, 20, 12, 28, 4, 18, 10, 26, 2, 22, 14, 30, 17, 21, 6, 25, 29, 27, 31, 5, 3, 7};
|
||
extern void delay_2ms(int cnt);
|
||
extern void wdt_clear(void);
|
||
extern void mic_analog_init(u8 mic_ldo_vsel, u8 mic_bias);
|
||
extern void mic_analog_close(struct adc_platform_data *pd);
|
||
void mic_capless_auto_adjust_init()
|
||
{
|
||
if (adc_data.mic_capless == 0) {
|
||
return;
|
||
}
|
||
log_info("mic_capless_bias_adjust_init:%d-%d\n", adc_data.mic_ldo_vsel, adc_data.mic_bias_res);
|
||
mic_analog_init(adc_data.mic_ldo_vsel, adc_data.mic_bias_res);
|
||
}
|
||
|
||
void mic_capless_auto_adjust_exit()
|
||
{
|
||
if (adc_data.mic_capless == 0) {
|
||
return;
|
||
}
|
||
log_info("mic_capless_bias_adjust_exit\n");
|
||
mic_analog_close(&adc_data);
|
||
}
|
||
|
||
/*AC696x系列只支持高压模式*/
|
||
#define MIC_BIAS_HIGH_UPPER_LIMIT 200 /*高压上限:2.00v*/
|
||
#define MIC_BIAS_HIGH_LOWER_LIMIT 135 /*高压下限:1.35v*/
|
||
|
||
#define ADC_MIC_IO IO_PORTA_01
|
||
#define ADC_MIC_CH AD_CH_PA1
|
||
#define MIC_BIAS_RSEL(x) SFR(JL_ANA->ADA_CON0, 6, 5, x)
|
||
#define MIC_LDO_SEL(x) SFR(JL_ANA->ADA_CON0, 2, 2, x)
|
||
|
||
|
||
/*
|
||
*return -1:非省电容模式
|
||
*return -2:校准失败
|
||
*return -3:麦掉线(坏了或者没焊接)
|
||
*return 0:默认值合法,不用校准
|
||
*return 1:默认值非法,启动校准
|
||
*/
|
||
#define MC_ERR_MODE -1
|
||
#define MC_ERR_TRIM_FAIL -2
|
||
#define MC_ERR_MIC_OFFLINE -3
|
||
#define MC_ERR_VALID 0
|
||
#define MC_ERR_INVALID 1
|
||
s8 mic_capless_auto_adjust(void)
|
||
{
|
||
u16 mic_bias_val = 0;
|
||
u8 mic_bias_idx = adc_data.mic_bias_res;
|
||
u8 mic_bias_compare = 0;
|
||
u16 bias_upper_limit = MIC_BIAS_HIGH_UPPER_LIMIT;
|
||
u16 bias_lower_limit = MIC_BIAS_HIGH_LOWER_LIMIT;
|
||
s8 ret = 0;
|
||
u8 err_cnt = 0;
|
||
u8 mic_ldo_idx = 0;
|
||
|
||
//printf("mic_capless_bias_adjust:%d\n",adc_data.mic_capless);
|
||
|
||
if (adc_data.mic_capless == 0) {
|
||
return -1;
|
||
}
|
||
|
||
log_info("mic_bias idx:%d,rsel:%d\n", mic_bias_idx, mic_bias_tab[mic_bias_idx]);
|
||
|
||
/*采样MIC_port(PA1)的偏置电压值*/
|
||
JL_PORTA->DIE &= ~BIT(1);
|
||
JL_PORTA->DIR |= BIT(1);
|
||
JL_PORTA->PU &= ~BIT(1);
|
||
JL_PORTA->PD &= ~BIT(1);
|
||
adc_add_sample_ch(ADC_MIC_CH);
|
||
|
||
#if 0
|
||
/*
|
||
*调试使用
|
||
*如果mic的偏置电压mic_bias_val稳定,则表示延时足够,否则加大延时知道电压值稳定
|
||
*/
|
||
while (1) {
|
||
wdt_clear();
|
||
MIC_BIAS_RSEL(mic_bias_tab[mic_bias_idx]);
|
||
delay_2ms(50);//延时等待偏置电压稳定
|
||
mic_bias_val = adc_get_voltage(ADC_MIC_CH) / 10;
|
||
log_info("mic_bias_val:%d,idx:%d,rsel:%d\n", mic_bias_val, mic_bias_idx, mic_bias_tab[mic_bias_idx]);
|
||
}
|
||
#endif
|
||
|
||
|
||
#if TCFG_MC_MIC_ONLINE_CHECK_EN
|
||
u8 tmp_rsel_idx = 1;
|
||
MIC_BIAS_RSEL(mic_bias_tab[tmp_rsel_idx]);
|
||
delay_2ms(25);//延时等待偏置电压稳定
|
||
u16 mic_bias_val_0 = adc_get_voltage(ADC_MIC_CH);
|
||
log_info("mic_bias_val:%d,idx:%d,rsel:%d\n", mic_bias_val_0, tmp_rsel_idx, mic_bias_tab[mic_bias_idx]);
|
||
|
||
tmp_rsel_idx = 16;
|
||
MIC_BIAS_RSEL(mic_bias_tab[tmp_rsel_idx]);
|
||
delay_2ms(25);//延时等待偏置电压稳定
|
||
u16 mic_bias_val_1 = adc_get_voltage(ADC_MIC_CH);
|
||
log_info("mic_bias_val:%d,idx:%d,rsel:%d\n", mic_bias_val_1, tmp_rsel_idx, mic_bias_tab[mic_bias_idx]);
|
||
u16 mic_bias_val_diff = __builtin_abs(mic_bias_val_0 - mic_bias_val_1);
|
||
log_info("mic_bias_val_diff:%d\n", mic_bias_val_diff);
|
||
if (mic_bias_val_diff < 500) {
|
||
printf("MIC_offline,Please check your layout!\n");
|
||
mic_capless_auto_adjust_exit();
|
||
return MC_ERR_MIC_OFFLINE;
|
||
}
|
||
#endif/*TCFG_MC_MIC_ONLEIN_CHECK_EN*/
|
||
|
||
while (1) {
|
||
wdt_clear();
|
||
MIC_BIAS_RSEL(mic_bias_tab[mic_bias_idx]);
|
||
delay_2ms(50);
|
||
|
||
mic_bias_val = adc_get_voltage(ADC_MIC_CH) / 10;
|
||
log_info("mic_bias_val:%d,idx:%d,rsel:%d\n", mic_bias_val, mic_bias_idx, mic_bias_tab[mic_bias_idx]);
|
||
|
||
if (mic_bias_val < bias_lower_limit) {
|
||
/*电压偏小,调小内部上拉偏置*/
|
||
mic_bias_compare |= BIT(0);
|
||
mic_bias_idx++;
|
||
if (mic_bias_idx >= sizeof(mic_bias_tab)) {
|
||
log_error("mic_bias_auto_adjust faild 0\n");
|
||
/*校准失败,使用快速收敛*/
|
||
//mic_capless_adjust_bud = MIC_CAPLESS_ADJUST_BUD;
|
||
ret = -2;
|
||
//break;
|
||
}
|
||
} else if (mic_bias_val > bias_upper_limit) {
|
||
/*电压偏大,调大内部上拉偏置*/
|
||
mic_bias_compare |= BIT(1);
|
||
if (mic_bias_idx) {
|
||
mic_bias_idx--;
|
||
} else {
|
||
log_error("mic_bias_auto_adjust faild 1\n");
|
||
/*校准失败,使用快速收敛*/
|
||
//mic_capless_adjust_bud = MIC_CAPLESS_ADJUST_BUD;
|
||
ret = -2;
|
||
//break;
|
||
}
|
||
} else {
|
||
if (mic_bias_compare) {
|
||
/*超出范围,调整过的值,保存*/
|
||
adc_data.mic_bias_res = mic_bias_idx;
|
||
log_info("mic_bias_adjust ok,idx:%d,rsel:%d\n", mic_bias_idx, mic_bias_tab[mic_bias_idx]);
|
||
/*记住校准过的值*/
|
||
ret = syscfg_write(CFG_MC_BIAS, &adc_data.mic_bias_res, 1);
|
||
log_info("mic_bias_adjust save ret = %d\n", ret);
|
||
ret = 1;
|
||
}
|
||
|
||
/*原本的MICLDO档位不合适,保存新的MICLDO档位*/
|
||
if (err_cnt) {
|
||
adc_data.mic_ldo_vsel = mic_ldo_idx;
|
||
log_info("mic_ldo_vsel fix:%d\n", adc_data.mic_ldo_vsel);
|
||
//log_info("mic_bias:%d,idx:%d\n",adc_data.mic_bias_res,mic_bias_idx);
|
||
ret = syscfg_write(CFG_MIC_LDO_VSEL, &mic_ldo_idx, 1);
|
||
log_info("mic_ldo_vsel save ret = %d\n", ret);
|
||
ret = 1;
|
||
}
|
||
log_info("mic_bias valid:%d,idx:%d,res:%d\n", mic_bias_val, mic_bias_idx, mic_bias_tab[mic_bias_idx]);
|
||
break;
|
||
}
|
||
|
||
/*
|
||
*当前MICLDO分不出合适的偏置电压
|
||
* 选择1、修改MICLDO档位,重新校准
|
||
* 选择2、直接退出,跳出自动校准
|
||
*/
|
||
if ((mic_bias_compare == (BIT(0) | BIT(1))) || (ret == -2)) {
|
||
log_info("mic_bias_trim err,adjust micldo vsel\n");
|
||
ret = 0;
|
||
#if 1 /*选择1*/
|
||
/*从0开始遍历查询*/
|
||
if (err_cnt) {
|
||
mic_ldo_idx++;
|
||
}
|
||
err_cnt++;
|
||
/*跳过默认的ldo电压档*/
|
||
if (mic_ldo_idx == adc_data.mic_ldo_vsel) {
|
||
mic_ldo_idx++;
|
||
}
|
||
/*遍历结束,没有合适的MICLDO电压档*/
|
||
if (mic_ldo_idx > 3) {
|
||
log_info("mic_bias_adjust tomeout\n");
|
||
mic_capless_adjust_bud = MIC_CAPLESS_ADJUST_BUD;
|
||
ret = -3;
|
||
break;
|
||
}
|
||
log_info("mic_ldo_idx:%d", mic_ldo_idx);
|
||
MIC_LDO_SEL(mic_ldo_idx);
|
||
/*修改MICLDO电压档,等待电压稳定*/
|
||
os_time_dly(20);
|
||
/*复位偏置电阻档位*/
|
||
mic_bias_idx = adc_data.mic_bias_res;
|
||
/*复位校准标志位*/
|
||
mic_bias_compare = 0;
|
||
#else /*选择2*/
|
||
log_info("mic_bias_trim err,break loop\n");
|
||
mic_capless_adjust_bud = MIC_CAPLESS_ADJUST_BUD;
|
||
ret = -3;
|
||
break;
|
||
#endif
|
||
}
|
||
}
|
||
mic_capless_auto_adjust_exit();
|
||
return ret;
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
*检查mic偏置是否需要校准,以下情况需要重新校准:
|
||
*1、power on reset
|
||
*2、vm被擦除
|
||
*3、每次开机都校准
|
||
*/
|
||
extern u8 power_reset_src;
|
||
u8 mc_bias_adjust_check()
|
||
{
|
||
#if(TCFG_MC_BIAS_AUTO_ADJUST == MC_BIAS_ADJUST_ALWAYS)
|
||
return 1;
|
||
#elif (TCFG_MC_BIAS_AUTO_ADJUST == MC_BIAS_ADJUST_ONE)
|
||
return 0;
|
||
#endif
|
||
u8 por_flag = 0;
|
||
int ret = syscfg_read(CFG_POR_FLAG, &por_flag, 1);
|
||
if (ret == 1) {
|
||
if (por_flag == 0xA5) {
|
||
log_info("power on reset 1");
|
||
por_flag = 0;
|
||
ret = syscfg_write(CFG_POR_FLAG, &por_flag, 1);
|
||
return 1;
|
||
}
|
||
}
|
||
if (power_reset_src & BIT(0)) {
|
||
log_info("power on reset 2");
|
||
return 1;
|
||
}
|
||
if (read_vm_capless_DTB() == DACR32_DEFAULT) {
|
||
log_info("vm format");
|
||
return 1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
#if TCFG_MC_DTB_STEP_LIMIT
|
||
/*获取省电容mic收敛信息配置*/
|
||
int get_mc_dtb_step_limit(void)
|
||
{
|
||
return dtb_step_limit;
|
||
}
|
||
#endif /*TCFG_MC_DTB_STEP_LIMIT*/
|
||
|
||
/*
|
||
*pos = 1:dac trim begin
|
||
*pos = 2:dac trim end
|
||
*pos = 3:dac已经trim过(开机)
|
||
*pos = 4:dac已经读取过变量(过程)
|
||
*pos = 5:dac已经trim过(开机,dac模块初始化)
|
||
*/
|
||
extern void audio_dac2micbias_en(struct audio_dac_hdl *dac, u8 en);
|
||
void _audio_dac_trim_hook(u8 pos)
|
||
{
|
||
#if TCFG_MC_BIAS_AUTO_ADJUST
|
||
int ret = 0;
|
||
log_info("dac_trim_hook:%d\n", pos);
|
||
if ((adc_data.mic_capless == 0) || (pos == 0xFF)) {
|
||
return;
|
||
}
|
||
|
||
if (pos == 1) {
|
||
ret = mic_capless_auto_adjust();
|
||
if (ret >= 0) {
|
||
mic_capless_feedback_toggle(1);
|
||
} else {
|
||
/*校准出错的时候不做预收敛*/
|
||
log_info("auto_adjust err:%d\n", ret);
|
||
}
|
||
return;
|
||
} else if (pos == 2) {
|
||
if (mic_capless_feedback_sw) {
|
||
ret = os_sem_pend(&mc_sem, 250);
|
||
audio_mic_capless_feedback_control(0, 16000);
|
||
if (ret == OS_TIMEOUT) {
|
||
log_info("mc_trim1 timeout!\n");
|
||
} else {
|
||
dtb_step_limit = TCFG_MC_DTB_STEP_LIMIT;
|
||
}
|
||
} else {
|
||
log_info("auto_feedback disable");
|
||
}
|
||
} else if (pos == 5) {
|
||
if (mc_bias_adjust_check()) {
|
||
//printf("MC_BIAS_ADJUST...");
|
||
void mic_capless_auto_adjust_init();
|
||
mic_capless_auto_adjust_init();
|
||
os_time_dly(25);
|
||
ret = mic_capless_auto_adjust();
|
||
if (ret == MC_ERR_MIC_OFFLINE) {
|
||
log_info("mic offline,return\n");
|
||
return;
|
||
}
|
||
/*
|
||
*预收敛条件:
|
||
*1、开机检查发现mic的偏置非法,则校准回来,同时重新收敛,比如中途更换mic头的情况
|
||
*2、收敛值丢失(vm被擦除),重新收敛一次(前提是校准成功)
|
||
*/
|
||
if ((ret == 1) || ((ret == 0) && (read_vm_capless_DTB() == DACR32_DEFAULT))) {
|
||
audio_dac2micbias_en(&dac_hdl, 1);
|
||
mic_capless_feedback_toggle(1);
|
||
ret = os_sem_pend(&mc_sem, 250);
|
||
audio_mic_capless_feedback_control(0, 16000);
|
||
audio_dac2micbias_en(&dac_hdl, 0);
|
||
if (ret == OS_TIMEOUT) {
|
||
log_info("mc_trim2 timeout!\n");
|
||
} else {
|
||
dtb_step_limit = TCFG_MC_DTB_STEP_LIMIT;
|
||
}
|
||
} else {
|
||
log_info("auto_adjust err:%d\n", ret);
|
||
if (ret == 0) {
|
||
dtb_step_limit = TCFG_MC_DTB_STEP_LIMIT;
|
||
}
|
||
}
|
||
} else {
|
||
log_info("MC_BIAS_OK...\n");
|
||
dtb_step_limit = TCFG_MC_DTB_STEP_LIMIT;
|
||
}
|
||
}
|
||
mic_capless_feedback_sw = 0;
|
||
#endif/*TCFG_MC_BIAS_AUTO_ADJUST*/
|
||
}
|
||
#endif/*TCFG_MIC_CAPLESS_ENABLE*/
|
||
|
||
|
||
////////////////////////////////// audio_output_api //////////////////////////////////////////////
|
||
#if 1
|
||
|
||
void _audio_dac_irq_hook(void)
|
||
{
|
||
/* putbyte('d'); */
|
||
extern struct audio_stream_dac_out *dac_last;
|
||
audio_stream_resume(&dac_last->entry);
|
||
}
|
||
|
||
void _audio_adc_irq_hook(void)
|
||
{
|
||
/* putbyte('a'); */
|
||
extern struct audio_adc_hdl adc_hdl;
|
||
audio_adc_irq_handler(&adc_hdl);
|
||
}
|
||
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_init
|
||
* Description : 音频输出设备初始化
|
||
* Return : None
|
||
********************* -HB ******************************/
|
||
void app_audio_output_init(void)
|
||
{
|
||
#if (AUDIO_OUTPUT_INCLUDE_DAC|| TCFG_AUDIO_ADC_ENABLE)
|
||
audio_dac_init(&dac_hdl, &dac_data);
|
||
#endif
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
#if TCFG_MIC_CAPLESS_ENABLE
|
||
/*初始化DAC_DTB*/
|
||
s16 dacr32 = read_capless_DTB();
|
||
audio_dac_set_capless_DTB(&dac_hdl, dacr32);
|
||
#endif/*TCFG_MIC_CAPLESS_ENABLE*/
|
||
|
||
audio_dac_set_buff(&dac_hdl, dac_buff, sizeof(dac_buff));
|
||
|
||
struct audio_dac_trim dac_trim;
|
||
int len = syscfg_read(CFG_DAC_TRIM_INFO, (void *)&dac_trim, sizeof(dac_trim));
|
||
if (len != sizeof(dac_trim) || dac_trim.left == 0 || dac_trim.right == 0) {
|
||
audio_dac_do_trim(&dac_hdl, &dac_trim, 0);
|
||
syscfg_write(CFG_DAC_TRIM_INFO, (void *)&dac_trim, sizeof(dac_trim));
|
||
} else {
|
||
#if TCFG_MIC_CAPLESS_ENABLE
|
||
_audio_dac_trim_hook(5);
|
||
#endif/*TCFG_MIC_CAPLESS_ENABLE*/
|
||
}
|
||
|
||
audio_dac_set_trim_value(&dac_hdl, &dac_trim);
|
||
audio_dac_set_delay_time(&dac_hdl, 30, 50);
|
||
#endif
|
||
}
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_sync_buff_init
|
||
* Description : 设置音频输出设备同步功能 buf
|
||
* Parameter :
|
||
* @sync_buff buf 起始地址
|
||
* @len buf 长度
|
||
* Return : None
|
||
********************* -HB ******************************/
|
||
void app_audio_output_sync_buff_init(void *sync_buff, int len)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
/*音频同步DA端buffer设置*/
|
||
/*audio_output_dac_sync_buff_init(sync_buff, len);*/
|
||
#endif
|
||
}
|
||
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_samplerate_select
|
||
* Description : 将输入采样率与输出采样率进行匹配对比
|
||
* Parameter :
|
||
* @sample_rate 输入采样率
|
||
* @high: 0 - 低一级采样率,1 - 高一级采样率
|
||
* Return : 匹配后的采样率
|
||
********************* -HB ******************************/
|
||
int app_audio_output_samplerate_select(u32 sample_rate, u8 high)
|
||
{
|
||
return audio_dac_sample_rate_select(&dac_hdl, sample_rate, high);
|
||
}
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_samplerate_set
|
||
* Description : 设置音频输出设备的采样率
|
||
* Parameter :
|
||
* @sample_rate 采样率
|
||
* Return : 0 success, other fail
|
||
********************* -HB ******************************/
|
||
int app_audio_output_samplerate_set(int sample_rate)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_set_sample_rate(&dac_hdl, sample_rate);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_samplerate_get
|
||
* Description : 获取音频输出设备的采样率
|
||
* Return : 音频输出设备的采样率
|
||
********************* -HB ******************************/
|
||
int app_audio_output_samplerate_get(void)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_get_sample_rate(&dac_hdl);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_mode_get
|
||
* Description : 获取当前硬件输出模式
|
||
* Return : 输出模式
|
||
********************* -HB ******************************/
|
||
int app_audio_output_mode_get(void)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_get_pd_output(&dac_hdl);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_mode_set
|
||
* Description : 设置当前硬件输出模式
|
||
* Return : 0 success, other fail
|
||
********************* -HB ******************************/
|
||
int app_audio_output_mode_set(u8 output)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_set_pd_output(&dac_hdl, output);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_channel_get
|
||
* Description : 获取音频输出设备输出通道数
|
||
* Return : 通道数
|
||
********************* -HB ******************************/
|
||
int app_audio_output_channel_get(void)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_get_channel(&dac_hdl);
|
||
#endif
|
||
#if AUDIO_OUTPUT_INCLUDE_IIS
|
||
return 2;
|
||
#endif
|
||
}
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_channel_set
|
||
* Description : 设置音频输出设备输出通道数
|
||
* Parameter :
|
||
* @channel 通道数
|
||
* Return : 0 success, other fail
|
||
********************* -HB ******************************/
|
||
int app_audio_output_channel_set(u8 channel)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_set_channel(&dac_hdl, channel);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_write
|
||
* Description : 向音频输出设备写入需要输出的音频数据
|
||
* Parameter :
|
||
* @buf 写入音频数据的起始地址
|
||
* @len 写入音频数据的长度
|
||
* Return : 成功写入的长度
|
||
********************* -HB ******************************/
|
||
int app_audio_output_write(void *buf, int len)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_write(&default_dac, buf, len);
|
||
#elif AUDIO_OUTPUT_WAY == AUDIO_OUTPUT_WAY_FM
|
||
return fm_emitter_cbuf_write(buf, len);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_start
|
||
* Description : 音频输出设备输出打开
|
||
* Return : 0 success, other fail
|
||
********************* -HB ******************************/
|
||
int app_audio_output_start(void)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
audio_dac_start(&dac_hdl);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_stop
|
||
* Description : 音频输出设备输出停止
|
||
* Return : 0 success, other fail
|
||
********************* -HB ******************************/
|
||
int app_audio_output_stop(void)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
audio_dac_channel_stop(&default_dac);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_reset
|
||
* Description : 音频输出设备重启
|
||
* Parameter :
|
||
* @msecs 重启时间 ms
|
||
* Return : 0 success, other fail
|
||
********************* -HB ******************************/
|
||
int app_audio_output_reset(u32 msecs)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_sound_reset(&dac_hdl, msecs);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
/*******************************************************
|
||
* Function name : app_audio_output_get_cur_buf_points
|
||
* Description : 获取当前音频输出buf还可以输出的点数
|
||
* Parameter :
|
||
* Return : 还可以输出的点数
|
||
********************* -HB ******************************/
|
||
int app_audio_output_get_cur_buf_points(void)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
int app_audio_output_ch_analog_gain_set(u8 ch, u8 again)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_ch_analog_gain_set(&dac_hdl, ch, again);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
int app_audio_output_ch_digital_gain_set(u8 ch, u32 dgain)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_ch_digital_gain_set(&dac_hdl, ch, dgain);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
int app_audio_output_state_get(void)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_get_status(&dac_hdl);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
void app_audio_output_ch_mute(u8 ch, u8 mute)
|
||
{
|
||
audio_dac_ch_mute(&dac_hdl, ch, mute);
|
||
}
|
||
|
||
int audio_output_buf_time(void)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_data_time(&dac_hdl);
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
int audio_output_dev_is_working(void)
|
||
{
|
||
#if AUDIO_OUTPUT_INCLUDE_DAC
|
||
return audio_dac_is_working(&dac_hdl);
|
||
#endif
|
||
return 1;
|
||
}
|
||
|
||
int audio_output_sync_start(void)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
int audio_output_sync_stop(void)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
#endif
|
||
|