first
This commit is contained in:
1986
cpu/br28/audio_hearing/audio_hearing_aid.c
Normal file
1986
cpu/br28/audio_hearing/audio_hearing_aid.c
Normal file
File diff suppressed because it is too large
Load Diff
127
cpu/br28/audio_hearing/audio_hearing_aid.h
Normal file
127
cpu/br28/audio_hearing/audio_hearing_aid.h
Normal file
@ -0,0 +1,127 @@
|
||||
#ifndef _AUD_HEARING_AID_H_
|
||||
#define _AUD_HEARING_AID_H_
|
||||
|
||||
#include "generic/typedef.h"
|
||||
#include "board_config.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* 可选功能模块配置(Optinal Module Define)
|
||||
************************************************************************/
|
||||
#define DHA_DATA_EXPORT_ENABLE 0 //数据导出使能, 需要先开APP_PCM_DEBUG
|
||||
#define DHA_RUN_TIME_TRACE_ENABLE 0 //运行时间log跟踪
|
||||
#define DHA_RUN_TIME_IO_DEBUG_ENABLE 0 //运行时间IO跟踪
|
||||
#ifdef DHA_RUN_TIME_IO_DEBUG_ENABLE
|
||||
#define IO_IDX 7
|
||||
#define IO_INTERVAL_IDX 4 /*DHA节奏,唤醒间隔*/
|
||||
#define DHA_IO_DEBUG_INIT() JL_PORTA->DIR &= ~BIT(IO_IDX)
|
||||
#define DHA_IO_DEBUG_1() JL_PORTA->OUT |= BIT(IO_IDX)
|
||||
#define DHA_IO_DEBUG_0() JL_PORTA->OUT &= ~BIT(IO_IDX)
|
||||
#define DHA_IO_INTERVAL() {JL_PORTA->DIR &= ~BIT(IO_INTERVAL_IDX);JL_PORTA->OUT ^= BIT(IO_INTERVAL_IDX);}
|
||||
#else
|
||||
#define DHA_IO_DEBUG_INIT(...)
|
||||
#define DHA_IO_DEBUG_1(...)
|
||||
#define DHA_IO_DEBUG_0(...)
|
||||
#define DHA_IO_INTERVAL(...)
|
||||
#endif/*DHA_RUN_TIME_IO_DEBUG_ENABLE*/
|
||||
|
||||
/*************************************************************************
|
||||
* 可选功能模块配置(Optinal Module Define)
|
||||
************************************************************************/
|
||||
#define DHA_AND_MEDIA_MUTEX_ENABLE 1 //辅听功能和多媒体播放互斥
|
||||
#define DHA_SRC_USE_HW_ENABLE 0 //SRC选择,1:使用硬件SRC,0:使用软件SRC
|
||||
#define DHA_MIC_DATA_CBUF_ENABLE 0 //是否使用cbuf缓存mic的数据
|
||||
#define DHA_DAC_OUTPUT_ENHANCE_ENABLE 0 //DAC输出音量增强使能:用来提高辅听的动态范围
|
||||
#define DHA_TDE_ENABLE 0 //辅听信号延时估计
|
||||
#define DHA_IN_LOUDNESS_TRACE_ENABLE 0 //跟踪获取当前mic输入幅值
|
||||
#define DHA_OUT_LOUDNESS_TRACE_ENABLE 0 //跟踪获取算法输出幅值
|
||||
#define DHA_USE_WDRC_ENABLE 1 //DRC选择,1:使用WDRC,0:使用普通限幅器DRC
|
||||
|
||||
/*************************************************************************
|
||||
* 验配功能定义(DHA Fitting Define)
|
||||
************************************************************************/
|
||||
|
||||
/*听力验配版本号*/
|
||||
#define DHA_FITTING_VERSION 0x01
|
||||
/*验配通道数*/
|
||||
#define DHA_FITTING_CHANNEL_MAX 6
|
||||
/*通道频率*/
|
||||
#define DHA_CH0_FREQ 250
|
||||
#define DHA_CH1_FREQ 500
|
||||
#define DHA_CH2_FREQ 1000
|
||||
#define DHA_CH3_FREQ 2000
|
||||
#define DHA_CH4_FREQ 4000
|
||||
#define DHA_CH5_FREQ 6000
|
||||
|
||||
/*
|
||||
* 1. PayLoad Format
|
||||
* +---------+---------------+------+
|
||||
* |cmd[8bit]|data_len[16bit]| data |
|
||||
* +---------+---------------+------+
|
||||
* 2.DHA Fitting Commands
|
||||
*/
|
||||
|
||||
|
||||
/*(1)验配信息交互:版本、通道数、通道频率*/
|
||||
#define DHA_FITTING_CMD_INFO 0x50
|
||||
typedef struct {
|
||||
u8 version; /*版本号:DHA_FITTING_VERSION*/
|
||||
u8 ch_num; /*通道数:DHA_FITTING_CHANNEL_MAX*/
|
||||
u16 ch_freq[DHA_FITTING_CHANNEL_MAX]; /*通道频率组:获取通道对应的freq*/
|
||||
} dha_fitting_info_t;
|
||||
|
||||
/*(2)通道验配*/
|
||||
#define DHA_FITTING_CMD_ADJUST 0x51
|
||||
typedef struct {
|
||||
u8 channel: 1; /*左右声道标识:0=左声道 1=右声道*/
|
||||
u8 sine: 2; /*开关验配单频音的标志: BIT(0) = 1 左耳播单频音,BIT(0) = 0 左耳静音
|
||||
BIT(1) = 1 右耳播单频音,BIT(1) = 0 右耳静音*/
|
||||
u8 reserve0: 5; /*保留*/
|
||||
u8 reserve1; /*保留*/
|
||||
u16 freq; /*通道频率*/
|
||||
float gain; /*通道增益*/
|
||||
} dha_fitting_adjust_t;
|
||||
|
||||
/*(3)验配结果保存更新*/
|
||||
/*
|
||||
+---------+------------+--------------------+-------------+---------------+
|
||||
|cmd[8bit]|len[16bit] | type(8bit)左/右/双耳|N个左耳[float]| N个右耳[float] |
|
||||
+---------+------------+--------------------+-------------+---------------+
|
||||
type(8bit) 0:左耳数据,1:右耳数据,2:双耳数据
|
||||
*/
|
||||
#define DHA_FITTING_CMD_UPDATE 0x52
|
||||
|
||||
/*(4)左右耳打开辅听的状态*/
|
||||
#define DHA_FITTING_CMD_STATE 0x53
|
||||
typedef struct {
|
||||
u8 state_left: 1;
|
||||
u8 state_right: 1;
|
||||
u8 reserve: 6;
|
||||
} dha_fitting_state_t;
|
||||
|
||||
/*************************************************************************
|
||||
* 辅听耳机接口声明(DHA APIs Declaration)
|
||||
************************************************************************/
|
||||
int audio_hearing_aid_open(void);
|
||||
int audio_hearing_aid_close(void);
|
||||
void audio_hearing_aid_demo(void);
|
||||
void audio_hearing_aid_resume(void);
|
||||
void audio_hearing_aid_suspend(void);
|
||||
int hearing_aid_fitting_parse(u8 *data, u16 len);
|
||||
int hearing_aid_fitting_start(u8 en);
|
||||
int get_hearing_aid_fitting_info(u8 *data);
|
||||
u8 get_hearing_aid_state(void);
|
||||
u8 get_hearing_aid_fitting_state(void);
|
||||
u8 set_hearing_aid_fitting_state(u8 state);
|
||||
void audio_dha_fitting_sync_close(void);
|
||||
int get_hearing_aid_state_cmd_info(u8 *data);
|
||||
|
||||
/*************************************************************************
|
||||
* 其他引用(Other Reference)
|
||||
************************************************************************/
|
||||
extern int aec_uart_open(u8 nch, u16 single_size);
|
||||
extern int aec_uart_fill(u8 ch, void *buf, u16 size);
|
||||
extern void aec_uart_write(void);
|
||||
extern int aec_uart_close(void);
|
||||
|
||||
#endif/*_AUD_HEARING_AID_H_*/
|
||||
352
cpu/br28/audio_hearing/audio_hearing_aid_lp.c
Normal file
352
cpu/br28/audio_hearing/audio_hearing_aid_lp.c
Normal file
@ -0,0 +1,352 @@
|
||||
/*
|
||||
****************************************************************
|
||||
* Hearing Aid Low Power
|
||||
* 检测数据能量的函数
|
||||
* File : audi_hearing_aid_lp.c
|
||||
* By :
|
||||
* Notes :
|
||||
****************************************************************
|
||||
*/
|
||||
|
||||
#include "asm/includes.h"
|
||||
#include "media/includes.h"
|
||||
#include "system/includes.h"
|
||||
#include "app_main.h"
|
||||
#include "audio_config.h"
|
||||
#include "app_action.h"
|
||||
#include "audio_hearing_aid_lp.h"
|
||||
|
||||
extern struct audio_dac_hdl dac_hdl;
|
||||
extern struct audio_adc_hdl adc_hdl;
|
||||
|
||||
#ifndef TCFG_AUDIO_DHA_MIC_SAMPLE_RATE
|
||||
#define TCFG_AUDIO_DHA_MIC_SAMPLE_RATE 32000
|
||||
#endif
|
||||
|
||||
//*********************************************************************************//
|
||||
// mic能量检测处理配置 //
|
||||
//*********************************************************************************//
|
||||
//是否开启mic 能量检测
|
||||
#define MIC_ENERGY_DETECT 1
|
||||
|
||||
//判断多少ms没有能量就进入低功耗
|
||||
#define MIC_SNIFF_TIME 2 * 60 * 1000
|
||||
//#define MIC_SNIFF_TIME 5 * 1000
|
||||
|
||||
//进入低功耗后每隔多少ms计算一次能量
|
||||
#define MIC_CHECK_INTER 1 * 1000
|
||||
|
||||
//低功耗状态下能量检测计算多少ms的能量
|
||||
#define MIC_ENERGY_TIME 20
|
||||
|
||||
//进入低功耗的能量值,小于此能量值进入低功耗
|
||||
#define enter_sniff_energy 50
|
||||
|
||||
//退出低功耗的能量值,大于退出低功耗 //从低功耗出来时adc 能量值会比较高,需要比较高的阈值
|
||||
#define exit_sniff_energy 170
|
||||
|
||||
//跳过刚上电的多少次中断数据
|
||||
#define adc_isr_ignore_cnt 8
|
||||
|
||||
//是否打开mic 能量的调试打印
|
||||
#define ENERGY_DEBUG_EN 0
|
||||
|
||||
static u8 enter_sleep = 0;
|
||||
|
||||
#if ENERGY_DEBUG_EN
|
||||
static u32 debug_size = 4096 * 2;
|
||||
/* static s16 debug_buf[4096 * 2]; */
|
||||
static u32 debug_p = 0;
|
||||
static u32 zero_cnt = 0;
|
||||
static u32 no_zero_cnt = 0;
|
||||
static u8 debug_flag = 0;
|
||||
#endif
|
||||
|
||||
struct hearing_aid_energy_detect {
|
||||
u32 exit_sniff_points; //一次检测的点数
|
||||
u32 abs_total_0; //mic0 的能量
|
||||
u32 abs_total_1; //mic1 的能量
|
||||
u32 points_count; //点数
|
||||
u32 energy_detect_flag;//是否开始计算能量的标志
|
||||
u32 enter_sniff_points; //多少个点的能量低于阈值进低功耗
|
||||
u32 exit_sniff_timer; //检测能量值定时器
|
||||
u16 dac_start_timer; //检测能量值定时器
|
||||
u16 dac_stop_timer; //检测能量值定时器
|
||||
u8 dac_start_flag; //dac 开启或关闭的标志位
|
||||
u8 isr_ignore_cnt; //跳过刚上电的多少次中断数据
|
||||
u8 adc_ch_num; //打开多少个mic通道
|
||||
struct adc_mic_ch mic_ch;
|
||||
s16 *adc_dma_buf;
|
||||
struct audio_adc_output_hdl adc_output;
|
||||
u8 dac_open;
|
||||
void (*hw_open)(void);
|
||||
void (*hw_close)(void);
|
||||
};
|
||||
|
||||
static struct hearing_aid_energy_detect *mic_aid = NULL;
|
||||
|
||||
void exit_sniff_start(void) //定时能量检测,能量检测的时候mic能不能正常工作
|
||||
{
|
||||
#if ENERGY_DEBUG_EN
|
||||
printf("enter low_power_deal.c %d\n", __LINE__);
|
||||
#endif
|
||||
|
||||
mic_aid->energy_detect_flag = 1; //开始能量计算
|
||||
mic_aid->isr_ignore_cnt = adc_isr_ignore_cnt;
|
||||
|
||||
#if 1 //重新打开mic
|
||||
extern void hearing_aid_energy_demo_open(u8 mic_idx, u8 gain, u16 sr, u8 mic_2_dac);
|
||||
hearing_aid_energy_demo_open(TCFG_AD2DA_LOW_LATENCY_MIC_CHANNEL, 12, TCFG_AUDIO_DHA_MIC_SAMPLE_RATE, 0);
|
||||
/* audio_adc_mic_aid_open(mic_aid->mic_idx, mic_aid->gain, mic_aid->sr, 0); */
|
||||
#else
|
||||
SFR(JL_ADDA->DAA_CON0, 16, 1, 1); // VBG_EN_11v
|
||||
SFR(JL_ADDA->ADA_CON0, 17, 1, 0); // CTADCA_S2_RSTB
|
||||
os_time_dly(50);
|
||||
SFR(JL_ADDA->ADA_CON0, 17, 1, 1); // CTADCA_S2_RSTB
|
||||
SFR(JL_ADDA->DAA_CON0, 12, 1, 1); //AUDIO_IBIAS_EN_11V
|
||||
#endif
|
||||
|
||||
enter_sleep = 0; //退出低功耗
|
||||
sys_timer_del(mic_aid->exit_sniff_timer);
|
||||
}
|
||||
|
||||
|
||||
void dac_start_timer(void) //启动dac
|
||||
{
|
||||
#if ENERGY_DEBUG_EN
|
||||
printf("enter low_power_deal.c%d\n", __LINE__);
|
||||
#endif
|
||||
|
||||
extern void hearing_aid_energy_demo_close(void);
|
||||
hearing_aid_energy_demo_close();
|
||||
|
||||
printf("enter low_power_deal.c%d\n", __LINE__);
|
||||
|
||||
if (mic_aid->hw_open) {
|
||||
mic_aid->hw_open();
|
||||
}
|
||||
/* sound_pcm_dev_start(NULL, 16000, 10); */
|
||||
enter_sleep = 0; //退出低功耗
|
||||
/* mic_aid->adc_2_dac = 1; */
|
||||
mic_aid->dac_start_flag = 1 ;
|
||||
sys_timer_del(mic_aid->dac_start_timer);
|
||||
}
|
||||
|
||||
|
||||
void dac_stop_timer(void) //关闭dac
|
||||
{
|
||||
#if ENERGY_DEBUG_EN
|
||||
printf("enter low_power_deal.c%d\n", __LINE__);
|
||||
#endif
|
||||
|
||||
|
||||
extern void hearing_aid_energy_demo_close(void);
|
||||
hearing_aid_energy_demo_close();
|
||||
|
||||
if (mic_aid->hw_close) {
|
||||
|
||||
printf("enter low_power_deal.c%d,%p\n", __LINE__, mic_aid->hw_close);
|
||||
mic_aid->hw_close();
|
||||
}
|
||||
/* audio_adc_del_output_handler(&adc_hdl, &mic_aid->adc_output); */
|
||||
/* audio_adc_mic_close(&mic_aid->mic_ch); */
|
||||
mic_aid->adc_ch_num = 0; //mic_aid 被关了
|
||||
//将变量清0,开始新一轮计算
|
||||
mic_aid->abs_total_0 = 0;
|
||||
mic_aid->abs_total_1 = 0;
|
||||
mic_aid->points_count = 0;
|
||||
mic_aid->energy_detect_flag = 0;
|
||||
|
||||
enter_sleep = 1; //进入低功耗
|
||||
/* mic_aid->adc_2_dac = 0; */
|
||||
mic_aid->dac_start_flag = 0 ;
|
||||
sys_timer_del(mic_aid->dac_stop_timer);
|
||||
|
||||
printf("enter low_power_deal.c%d\n", __LINE__);
|
||||
}
|
||||
|
||||
|
||||
void audio_hearing_aid_lp_open(u8 ch_num, void (*hw_open)(void), void (*hw_close)(void)) //对多少个通道做数据处理
|
||||
{
|
||||
if (!mic_aid) {
|
||||
printf("enter low_power_deal.c%d\n", __LINE__);
|
||||
mic_aid = zalloc(sizeof(struct hearing_aid_energy_detect));
|
||||
}
|
||||
|
||||
#if 0
|
||||
else {
|
||||
/* memset(mic_aid,0,sizeof(struct hearing_aid_energy_detect)); */
|
||||
}
|
||||
#endif
|
||||
mic_aid->exit_sniff_points = MIC_ENERGY_TIME * (TCFG_AUDIO_DHA_MIC_SAMPLE_RATE / 1000); //进入低功耗后一次检测的点数
|
||||
mic_aid->enter_sniff_points = MIC_SNIFF_TIME * (TCFG_AUDIO_DHA_MIC_SAMPLE_RATE / 1000); //多少个点的能量低于阈值进低功耗
|
||||
mic_aid->adc_ch_num = ch_num;
|
||||
mic_aid-> hw_open = hw_open; //正常工作打开硬件的函数(关mic,关dac)
|
||||
mic_aid-> hw_close = hw_close; //进入低功耗关硬件的函数(开mic,开dac)
|
||||
mic_aid->abs_total_0 = 0;
|
||||
mic_aid->abs_total_1 = 0;
|
||||
mic_aid->points_count = 0;
|
||||
enter_sleep = 0;
|
||||
|
||||
}
|
||||
|
||||
void audio_hearing_aid_lp_close(void)
|
||||
{
|
||||
if (mic_aid) {
|
||||
free(mic_aid);
|
||||
mic_aid = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
u8 audio_hearing_aid_lp_flag(void)
|
||||
{
|
||||
return enter_sleep;
|
||||
}
|
||||
|
||||
void audio_hearing_aid_lp_detect(void *priv, s16 *data, int len)
|
||||
{
|
||||
#if MIC_ENERGY_DETECT
|
||||
u32 points = len / 2;
|
||||
s16 *pdata = data;
|
||||
u32 i = 0;
|
||||
s32 total_0 = 0;
|
||||
s32 total_1 = 0;
|
||||
s16 diff = 0;
|
||||
u32 target_points = 0;
|
||||
u32 target_energy = 0;
|
||||
|
||||
if (enter_sleep == 0) { //低功耗期间也会进中断,不能计算能量值
|
||||
if (mic_aid->isr_ignore_cnt > 0) {
|
||||
mic_aid->isr_ignore_cnt--;
|
||||
return;
|
||||
} //跳过刚开始的一次中断数据
|
||||
|
||||
for (i = 0; i < points; i++) {
|
||||
total_0 += *pdata;
|
||||
pdata++;
|
||||
if (mic_aid->adc_ch_num == 2) {
|
||||
total_1 += *pdata;
|
||||
pdata++;
|
||||
}
|
||||
}
|
||||
|
||||
total_0 /= (len / 2 / mic_aid->adc_ch_num); //直流量
|
||||
total_1 /= (len / 2 / mic_aid->adc_ch_num);
|
||||
// printf(">> total_0 %d total_1 %d\n", total_0, total_1);
|
||||
pdata = data;
|
||||
|
||||
if (mic_aid->energy_detect_flag) { //由定时器启动的能量计算
|
||||
target_points = mic_aid->exit_sniff_points; //多少时间检测
|
||||
target_energy = exit_sniff_energy;
|
||||
} else {
|
||||
target_points = mic_aid-> enter_sniff_points; //正常工作检测多久
|
||||
target_energy = enter_sniff_energy;
|
||||
}
|
||||
|
||||
for (i = 0; i < points; i++) {
|
||||
#if ENERGY_DEBUG_EN
|
||||
#if 0
|
||||
if (debug_p < debug_size) {
|
||||
debug_buf[debug_p++] = *pdata ;
|
||||
if (*pdata == 0) {
|
||||
zero_cnt++;
|
||||
} else {
|
||||
no_zero_cnt++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
diff = *pdata - total_0;
|
||||
if (diff > 0) {
|
||||
mic_aid->abs_total_0 += diff;
|
||||
} else {
|
||||
mic_aid->abs_total_0 -= diff;
|
||||
}
|
||||
pdata++;
|
||||
if (mic_aid->adc_ch_num == 2) {
|
||||
diff = *pdata - total_1;
|
||||
if (diff > 0) {
|
||||
mic_aid->abs_total_1 += diff;
|
||||
} else {
|
||||
mic_aid->abs_total_1 -= diff;
|
||||
}
|
||||
pdata++;
|
||||
}
|
||||
mic_aid -> points_count++;
|
||||
|
||||
|
||||
#if ENERGY_DEBUG_EN
|
||||
/* printf("enter audio_adc_aid.c@@@@@@@@@@@@@@@@@@@@@@@@@@%d,%d,%d,%d\n",__LINE__,target_points,enter_sleep,mic_aid->points_count); */
|
||||
#endif
|
||||
|
||||
|
||||
if (mic_aid->points_count == target_points) {
|
||||
|
||||
#if ENERGY_DEBUG_EN
|
||||
printf("enter low_power_deal.c %d,%d,%d,%d,%d\n", __LINE__, mic_aid->abs_total_0, mic_aid->abs_total_1, mic_aid->points_count, target_points);
|
||||
#endif
|
||||
mic_aid->abs_total_0 /= target_points;
|
||||
mic_aid->abs_total_1 /= target_points;
|
||||
|
||||
#if ENERGY_DEBUG_EN
|
||||
printf("enter low_power_deal.c %d,%d,%d,%d\n", __LINE__, mic_aid->abs_total_0, mic_aid->abs_total_1, target_energy);
|
||||
#endif
|
||||
|
||||
#if ENERGY_DEBUG_EN
|
||||
extern void audio_adda_dump(void); //打印所有的dac,adc寄存器
|
||||
extern void audio_gain_dump();
|
||||
audio_adda_dump();
|
||||
audio_gain_dump();
|
||||
#endif
|
||||
|
||||
if ((mic_aid->abs_total_0 < target_energy) && (mic_aid->abs_total_1 < target_energy)) { //
|
||||
|
||||
|
||||
|
||||
|
||||
mic_aid->dac_stop_timer = sys_timer_add(NULL, dac_stop_timer, 1);
|
||||
mic_aid->exit_sniff_timer = sys_timer_add(NULL, exit_sniff_start, MIC_CHECK_INTER); //退出低功耗计算能量值
|
||||
#if ENERGY_DEBUG_EN
|
||||
debug_p = 0;
|
||||
zero_cnt = no_zero_cnt = 0;
|
||||
/* memset(debug_buf, 0, debug_size * 2); */
|
||||
printf("enter low_power_deal.c %d,%d,%d\n", __LINE__, mic_aid->abs_total_0, mic_aid->abs_total_1);
|
||||
#endif
|
||||
break;
|
||||
} else {
|
||||
//将变量清0,开始新一轮计算
|
||||
mic_aid->abs_total_0 = 0;
|
||||
mic_aid->abs_total_1 = 0;
|
||||
mic_aid->points_count = 0;
|
||||
mic_aid->energy_detect_flag = 0;
|
||||
enter_sleep = 0;
|
||||
|
||||
#if ENERGY_DEBUG_EN
|
||||
debug_p = 0;
|
||||
/* memset(debug_buf, 0, debug_size * 2); */
|
||||
zero_cnt = no_zero_cnt = 0;
|
||||
#endif
|
||||
|
||||
if (!audio_dac_is_working(&dac_hdl)) {
|
||||
|
||||
mic_aid->dac_start_timer = sys_timer_add(NULL, dac_start_timer, 1);
|
||||
}
|
||||
}
|
||||
|
||||
} //end of if 点数等于 enter_sniff_points
|
||||
}//endf of for
|
||||
} //end of 低功耗期间也会进中断,不能计算能量值
|
||||
|
||||
if (mic_aid->dac_open == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
58
cpu/br28/audio_hearing/audio_hearing_aid_lp.h
Normal file
58
cpu/br28/audio_hearing/audio_hearing_aid_lp.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef _AUD_HEARING_AID_LOW_POWER_H_
|
||||
#define _AUD_HEARING_AID_LOW_POWER_H_
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Energy Detect Open
|
||||
* Description: 打开低功耗能量检测功能
|
||||
* Arguments : ch_num 要处理的数据的通道数
|
||||
* hw_open 注册进去在出低功耗正常工作时会执行的回调
|
||||
a hw_close 注册进去在进低功耗时会执行的回调
|
||||
* Return : None.
|
||||
* Note(s) : None.
|
||||
*********************************************************************
|
||||
*/
|
||||
|
||||
void audio_hearing_aid_lp_open(u8 ch_num, void (*hw_open)(void), void (*hw_close)(void));
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Energy Detect Run
|
||||
* Description: 对传进去的数据进行能量检测,并根据结果决定进出低功耗
|
||||
* Arguments : priv 私有参数
|
||||
* data 要做处理的数据地址
|
||||
a len 要做处理的数据单个声道的数据长度
|
||||
* Return : None.
|
||||
* Note(s) : None.
|
||||
*********************************************************************
|
||||
*/
|
||||
|
||||
void audio_hearing_aid_lp_detect(void *priv, s16 *data, int len);
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Energy Detect Close
|
||||
* Description: 关闭能量检测
|
||||
* Arguments : NULL
|
||||
* Return : None.
|
||||
* Note(s) : None.
|
||||
*********************************************************************
|
||||
*/
|
||||
|
||||
void audio_hearing_aid_lp_close(void);
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Get Low Power Flag
|
||||
* Description: 获取是否能进低功耗的标志位
|
||||
* Arguments : NULL
|
||||
* Return : 1:代表可以进入低功耗
|
||||
0:代表不能进入低功耗
|
||||
* Note(s) : None.
|
||||
*********************************************************************
|
||||
*/
|
||||
|
||||
u8 audio_hearing_aid_lp_flag(void);
|
||||
|
||||
#endif/*_AUD_HEARING_AID_LOW_POWER_H_*/
|
||||
169
cpu/br28/audio_hearing/audio_sidetone.c
Normal file
169
cpu/br28/audio_hearing/audio_sidetone.c
Normal file
@ -0,0 +1,169 @@
|
||||
#include "generic/typedef.h"
|
||||
#include "board_config.h"
|
||||
#include "media/includes.h"
|
||||
#include "audio_config.h"
|
||||
#include "sound_device.h"
|
||||
#include "audio_sidetone.h"
|
||||
#include "system/task.h"
|
||||
|
||||
#if TCFG_SIDETONE_ENABLE
|
||||
|
||||
extern struct audio_dac_hdl dac_hdl;
|
||||
#define SIDETONE_BUF_LEN 256
|
||||
#define SIDETONE_READBUF_LEN 64 //中断点数设为32,则每次数据长度为64
|
||||
static struct audio_sidetone_hdl {
|
||||
s16 *sidetone_buf;
|
||||
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)
|
||||
s16 *sidetone_buf_lr;
|
||||
#endif/*(TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)*/
|
||||
cbuffer_t cbuf;
|
||||
OS_SEM sem;
|
||||
bool busy; //检测任务是否在阻塞态
|
||||
bool suspend; //暂停监听
|
||||
struct audio_dac_channel dac_ch;
|
||||
struct audio_dac_channel_attr attr;
|
||||
};
|
||||
static struct audio_sidetone_hdl *sidetone_hdl = NULL;
|
||||
|
||||
static inline void audio_pcm_mono_to_dual(s16 *dual_pcm, s16 *mono_pcm, int points)
|
||||
{
|
||||
s16 *mono = mono_pcm;
|
||||
int i = 0;
|
||||
u8 j = 0;
|
||||
|
||||
for (i = 0; i < points; i++, mono++) {
|
||||
*dual_pcm++ = *mono;
|
||||
*dual_pcm++ = *mono;
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_sidetone_task(void)
|
||||
{
|
||||
if (!sidetone_hdl) {
|
||||
sidetone_hdl = zalloc(sizeof(struct audio_sidetone_hdl));
|
||||
if (!sidetone_hdl) {
|
||||
printf("zalloc sidetone_hdl err\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
sidetone_hdl->suspend = 1;
|
||||
sidetone_hdl->sidetone_buf = zalloc(SIDETONE_BUF_LEN);
|
||||
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)
|
||||
sidetone_hdl->sidetone_buf_lr = zalloc(SIDETONE_READBUF_LEN * 2);
|
||||
#endif/*(TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)*/
|
||||
cbuf_init(&sidetone_hdl->cbuf, sidetone_hdl->sidetone_buf, SIDETONE_BUF_LEN);
|
||||
os_sem_create(&sidetone_hdl->sem, 0);
|
||||
|
||||
audio_dac_new_channel(&dac_hdl, &sidetone_hdl->dac_ch);
|
||||
sidetone_hdl->attr.delay_time = 6;
|
||||
sidetone_hdl->attr.protect_time = 8;
|
||||
sidetone_hdl->attr.write_mode = WRITE_MODE_BLOCK;
|
||||
audio_dac_channel_set_attr(&sidetone_hdl->dac_ch, &sidetone_hdl->attr);
|
||||
sound_pcm_dev_start(&sidetone_hdl->dac_ch, 16000, app_audio_get_volume(APP_AUDIO_STATE_CALL));
|
||||
|
||||
while (1) {
|
||||
sidetone_hdl->busy = 0;
|
||||
os_sem_pend(&sidetone_hdl->sem, 0);
|
||||
sidetone_hdl->busy = 1;
|
||||
u16 rlen = cbuf_read(&sidetone_hdl->cbuf, sidetone_hdl->sidetone_buf, SIDETONE_READBUF_LEN);
|
||||
if (rlen != SIDETONE_READBUF_LEN) {
|
||||
printf("rlen err : %d\n", rlen);
|
||||
}
|
||||
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)
|
||||
audio_pcm_mono_to_dual(sidetone_hdl->sidetone_buf_lr, sidetone_hdl->sidetone_buf, rlen >> 1);
|
||||
u16 wlen = sound_pcm_dev_write(&sidetone_hdl->dac_ch, sidetone_hdl->sidetone_buf_lr, rlen <<= 1);
|
||||
#else
|
||||
u16 wlen = sound_pcm_dev_write(&sidetone_hdl->dac_ch, sidetone_hdl->sidetone_buf, rlen);
|
||||
#endif
|
||||
if (wlen != rlen) {
|
||||
printf("wlen err : %d\n", wlen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Audio Sidetone Inbuf
|
||||
* Description: 通话监听数据流输入
|
||||
* Arguments : data 输入数据地址
|
||||
* len 输入数据长度
|
||||
* Return : None.
|
||||
* Note(s) : None.
|
||||
*********************************************************************
|
||||
*/
|
||||
void audio_sidetone_inbuf(s16 *data, u16 len)
|
||||
{
|
||||
if (sidetone_hdl && sidetone_hdl->suspend) {
|
||||
os_sem_post(&sidetone_hdl->sem);
|
||||
u16 wlen = cbuf_write(&sidetone_hdl->cbuf, data, len);
|
||||
if (wlen != len) {
|
||||
printf("wlen = %d, len = %d\n", wlen, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Audio Sidetone Open
|
||||
* Description: 打开通话监听
|
||||
* Arguments : None.
|
||||
* Return : 0成功 其他失败
|
||||
* Note(s) : None.
|
||||
*********************************************************************
|
||||
*/
|
||||
int audio_sidetone_open(void)
|
||||
{
|
||||
if (!sidetone_hdl) {
|
||||
task_create(audio_sidetone_task, NULL, "sidetone");//创建监听任务
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Audio Sidetone Close
|
||||
* Description: 关闭通话监听
|
||||
* Arguments : None.
|
||||
* Return : 0成功 其他失败
|
||||
* Note(s) : None.
|
||||
*********************************************************************
|
||||
*/
|
||||
int audio_sidetone_close(void)
|
||||
{
|
||||
if (!sidetone_hdl) {
|
||||
printf("sidetone already close\n");
|
||||
return -1;
|
||||
}
|
||||
if (!sidetone_hdl->busy) { //任务处于挂起态
|
||||
sound_pcm_dev_stop(&sidetone_hdl->dac_ch); //关闭监听
|
||||
task_kill("sidetone");
|
||||
free(sidetone_hdl->sidetone_buf);
|
||||
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)
|
||||
free(sidetone_hdl->sidetone_buf_lr);
|
||||
#endif/*(TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)*/
|
||||
free(sidetone_hdl);
|
||||
sidetone_hdl = NULL;
|
||||
return 0;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
* Audio Sidetone Suspend
|
||||
* Description: 暂停通话监听
|
||||
* Arguments : None.
|
||||
* Return : 0成功 其他失败
|
||||
* Note(s) : None.
|
||||
*********************************************************************
|
||||
*/
|
||||
int audio_sidetone_suspend(void)
|
||||
{
|
||||
if (sidetone_hdl) {
|
||||
sidetone_hdl->suspend ? (sidetone_hdl->suspend = 0) : (sidetone_hdl->suspend = 1);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif/*TCFG_SIDETONE_ENABLE*/
|
||||
12
cpu/br28/audio_hearing/audio_sidetone.h
Normal file
12
cpu/br28/audio_hearing/audio_sidetone.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _AUD_SIDETONE_H_
|
||||
#define _AUD_SIDETONE_H_
|
||||
|
||||
#include "generic/typedef.h"
|
||||
#include "board_config.h"
|
||||
|
||||
void audio_sidetone_inbuf(s16 *data, u16 len);
|
||||
int audio_sidetone_open(void);
|
||||
int audio_sidetone_close(void);
|
||||
int audio_sidetone_suspend(void);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user