342 lines
10 KiB
C
342 lines
10 KiB
C
/*
|
|
****************************************************************
|
|
* AUDIO_WIND_DETECT_DEMO
|
|
* File : audio_wind_detect_demo.c
|
|
* By :
|
|
* Notes :风噪检测使用,请不要修改本demo,如有需求,请拷贝副
|
|
* 本,自行修改!
|
|
* Usage :
|
|
*(1)需要打开双麦的宏 TCFG_AUDIO_DUAL_MIC_ENABLE
|
|
*(2)需要使用第二版双麦算法 CONST_DMS_GLOBAL_VERSION = DMS_GLOBAL_V200
|
|
*(3)调用audio_wind_detect_demo_open();使用
|
|
****************************************************************
|
|
*/
|
|
#include "audio_wind_detect_demo.h"
|
|
#include "system/includes.h"
|
|
#include "app_config.h"
|
|
#include "audio_adc.h"
|
|
#include "audio_enc.h"
|
|
#include "aec_user.h"
|
|
#include "task.h"
|
|
#include "cvp/cvp_common.h"
|
|
#include "lib_h/jlsp_ns.h"
|
|
#include "online_db_deal.h"
|
|
#include "spp_user.h"
|
|
#include "overlay_code.h"
|
|
#include "app_main.h"
|
|
|
|
|
|
#define WIND_DETECT_TASK_NAME "WindDetect"
|
|
/* 通过蓝牙spp发送风噪信息
|
|
* 需要同时打开USER_SUPPORT_PROFILE_SPP和APP_ONLINE_DEBUG*/
|
|
#define WIND_DETECT_INFO_SPP_DEBUG_ENABLE 0
|
|
|
|
#define AUDIO_ADC_BUF_NUM 3 //mic_adc采样buf个数
|
|
#define AUDIO_ADC_IRQ_POINTS 256 //mic_adc采样长度(单位:点数)
|
|
#if TCFG_AUDIO_TRIPLE_MIC_ENABLE
|
|
#define AUDIO_ADC_CH 3 //3mic通话
|
|
#elif TCFG_AUDIO_DUAL_MIC_ENABLE
|
|
#define AUDIO_ADC_CH 2 //双mic通话
|
|
#else
|
|
#define AUDIO_ADC_CH 1 //单mic通话
|
|
#endif/*TCFG_AUDIO_DUAL_MIC_ENABLE*/
|
|
#define AUDIO_ADC_BUFS_SIZE (AUDIO_ADC_BUF_NUM * AUDIO_ADC_IRQ_POINTS * AUDIO_ADC_CH)
|
|
|
|
struct audio_mic_hdl {
|
|
struct audio_adc_output_hdl adc_output;
|
|
struct adc_mic_ch mic_ch;
|
|
int adc_dump_cnt;
|
|
s16 adc_buf[AUDIO_ADC_BUFS_SIZE]; //align 2Bytes
|
|
#if (AUDIO_ADC_CH > 1)
|
|
s16 tmp_buf[AUDIO_ADC_IRQ_POINTS];
|
|
#endif/*AUDIO_ADC_CH*/
|
|
#if (AUDIO_ADC_CH > 2)
|
|
s16 tmp_buf_1[AUDIO_ADC_IRQ_POINTS];
|
|
#endif/*AUDIO_ADC_CH*/
|
|
};
|
|
static struct audio_mic_hdl *audio_mic = NULL;
|
|
extern struct audio_adc_hdl adc_hdl;
|
|
|
|
struct audio_wind_detect_hdl {
|
|
int wd_flag;
|
|
int wd_val;
|
|
int wd_lev;
|
|
#if WIND_DETECT_INFO_SPP_DEBUG_ENABLE
|
|
struct spp_operation_t *spp_opt;
|
|
#endif
|
|
};
|
|
static struct audio_wind_detect_hdl *audio_wd = NULL;
|
|
|
|
void audio_mic_dump_set(u16 dump_cnt)
|
|
{
|
|
printf("adc_dump_cnt:%d\n", dump_cnt);
|
|
if (audio_mic) {
|
|
audio_mic->adc_dump_cnt = dump_cnt;
|
|
}
|
|
}
|
|
/*adc_mic采样输出接口*/
|
|
static void adc_mic_output_handler(void *priv, s16 *data, int len)
|
|
{
|
|
if (audio_mic) {
|
|
if (audio_mic->adc_dump_cnt) {
|
|
audio_mic->adc_dump_cnt--;
|
|
//printf("[%d]",audio_mic->adc_dump_cnt);
|
|
memset(data, 0, len);
|
|
return;
|
|
}
|
|
|
|
#if (AUDIO_ADC_CH == 3)/*3 Mic*/
|
|
s16 *mic0_data = data;
|
|
s16 *mic1_data = data + (len / 2);
|
|
s16 *mic2_data = data + (len / 2) * 2;
|
|
int offset = 0;
|
|
|
|
s16 *mic1_data_pos = audio_mic->tmp_buf;
|
|
s16 *mic2_data_pos = audio_mic->tmp_buf_1;
|
|
//printf("mic_data:%x,%x,%d\n",data,mic1_data_pos,len);
|
|
for (u16 i = 0; i < (len >> 1); i++) {
|
|
mic0_data[i] = data[i * 3];
|
|
mic1_data[i] = data[i * 3 + 1];
|
|
mic2_data[i] = data[i * 3 + 2];
|
|
}
|
|
memcpy(mic1_data, mic1_data_pos, len);
|
|
memcpy(mic2_data, mic2_data_pos, len);
|
|
|
|
offset = (len / 2) * app_var.talk_ref_mic_ch;
|
|
audio_aec_inbuf_ref(data + offset, len);
|
|
offset = (len / 2) * app_var.talk_fb_mic_ch;
|
|
audio_aec_inbuf_ref_1(data + offset, len);
|
|
offset = (len / 2) * app_var.talk_mic_ch;
|
|
audio_aec_inbuf(data + offset, len);
|
|
return;
|
|
|
|
#elif (AUDIO_ADC_CH == 2)/*DualMic*/
|
|
s16 *mic0_data = data;
|
|
s16 *mic1_data = audio_mic->tmp_buf;
|
|
s16 *mic1_data_pos = data + (len / 2);
|
|
//printf("mic_data:%x,%x,%d\n",data,mic1_data_pos,len);
|
|
for (u16 i = 0; i < (len >> 1); i++) {
|
|
mic0_data[i] = data[i * 2];
|
|
mic1_data[i] = data[i * 2 + 1];
|
|
}
|
|
memcpy(mic1_data_pos, mic1_data, len);
|
|
|
|
#if (TCFG_AUDIO_DMS_MIC_MANAGE == DMS_MASTER_MIC0)
|
|
audio_aec_inbuf_ref(mic1_data_pos, len);
|
|
audio_aec_inbuf(data, len);
|
|
#else
|
|
audio_aec_inbuf_ref(data, len);
|
|
audio_aec_inbuf(mic1_data_pos, len);
|
|
#endif/*TCFG_AUDIO_DMS_MIC_MANAGE*/
|
|
|
|
#else/*SingleMic*/
|
|
audio_aec_inbuf(data, len);
|
|
#endif/*ESCO_ADC_CH*/
|
|
}
|
|
}
|
|
|
|
/*mic初始化*/
|
|
static int audio_mic_en(u8 en, u16 sr, u16 mic0_gain, u16 mic1_gain, u16 mic2_gain, u16 mic3_gain)
|
|
{
|
|
printf("audio_mic_en:%d\n", en);
|
|
u8 mic_ch = en;
|
|
if (en) {
|
|
if (audio_mic) {
|
|
printf("audio_mic re-malloc error\n");
|
|
return -1;
|
|
}
|
|
audio_mic = zalloc(sizeof(struct audio_mic_hdl));
|
|
if (audio_mic == NULL) {
|
|
printf("audio mic zalloc failed\n");
|
|
return -1;
|
|
}
|
|
audio_mic_pwr_ctl(MIC_PWR_ON);
|
|
|
|
audio_mic_dump_set(3);/*处理开mic后在短时间起3次中断影响aec的问题*/
|
|
if (en & AUDIO_ADC_MIC_0) {
|
|
printf("adc_mic0 open,gain:%d\n", mic0_gain);
|
|
audio_adc_mic_open(&audio_mic->mic_ch, mic_ch, &adc_hdl);
|
|
audio_adc_mic_set_gain(&audio_mic->mic_ch, mic0_gain);
|
|
}
|
|
if (en & AUDIO_ADC_MIC_1) {
|
|
printf("adc_mic1 open,gain:%d\n", mic1_gain);
|
|
audio_adc_mic1_open(&audio_mic->mic_ch, mic_ch, &adc_hdl);
|
|
audio_adc_mic1_set_gain(&audio_mic->mic_ch, mic1_gain);
|
|
}
|
|
if (en & AUDIO_ADC_MIC_2) {
|
|
printf("adc_mic2 open,gain:%d\n", mic2_gain);
|
|
audio_adc_mic2_open(&audio_mic->mic_ch, mic_ch, &adc_hdl);
|
|
audio_adc_mic2_set_gain(&audio_mic->mic_ch, mic2_gain);
|
|
}
|
|
if (en & AUDIO_ADC_MIC_3) {
|
|
printf("adc_mic3 open,gain:%d\n", mic3_gain);
|
|
audio_adc_mic3_open(&audio_mic->mic_ch, mic_ch, &adc_hdl);
|
|
audio_adc_mic3_set_gain(&audio_mic->mic_ch, mic3_gain);
|
|
}
|
|
audio_adc_mic_set_sample_rate(&audio_mic->mic_ch, sr);
|
|
audio_adc_mic_set_buffs(&audio_mic->mic_ch, audio_mic->adc_buf,
|
|
AUDIO_ADC_IRQ_POINTS * 2, AUDIO_ADC_BUF_NUM);
|
|
audio_mic->adc_output.handler = adc_mic_output_handler;
|
|
audio_adc_add_output_handler(&adc_hdl, &audio_mic->adc_output);
|
|
audio_adc_mic_start(&audio_mic->mic_ch);
|
|
} else {
|
|
if (audio_mic) {
|
|
audio_adc_mic_close(&audio_mic->mic_ch);
|
|
audio_adc_del_output_handler(&adc_hdl, &audio_mic->adc_output);
|
|
audio_mic_pwr_ctl(MIC_PWR_OFF);
|
|
free(audio_mic);
|
|
audio_mic = NULL;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int audio_wind_detect_output_hdl(s16 *data, int len)
|
|
{
|
|
return len;
|
|
}
|
|
|
|
/*打开风噪检测*/
|
|
int audio_wind_detect_open(u32 sr, u16 mic0_gain, u16 mic1_gain, u16 mic2_gain, u16 mic3_gain)
|
|
{
|
|
int err = 0;
|
|
overlay_load_code(OVERLAY_AEC);
|
|
audio_aec_open(sr, -1, audio_wind_detect_output_hdl);
|
|
/* audio_aec_open(sr, WNC_EN | ENC_EN | AEC_EN, audio_wind_detect_output_hdl); */
|
|
audio_mic_en(TCFG_AUDIO_ADC_MIC_CHA, sr, mic0_gain, mic1_gain, mic2_gain, mic3_gain);
|
|
return 0;
|
|
}
|
|
|
|
/*关闭风噪检测*/
|
|
int audio_wind_detect_close()
|
|
{
|
|
audio_aec_close();
|
|
audio_mic_en(0, 0, 0, 0, 0, 0);
|
|
return 0;
|
|
}
|
|
|
|
/*风噪检测信息获取任务*/
|
|
static void audio_wind_detect_task(void *p)
|
|
{
|
|
while (1) {
|
|
os_time_dly(10);
|
|
audio_get_wind_detect_info();
|
|
}
|
|
}
|
|
|
|
/*打开获取风噪信息的任务*/
|
|
int audio_wind_info_task_open()
|
|
{
|
|
int err = 0;
|
|
if (audio_wd) {
|
|
printf("[err] audio_wd re-malloc !!!");
|
|
return -1;
|
|
}
|
|
audio_wd = zalloc(sizeof(struct audio_wind_detect_hdl));
|
|
if (audio_wd == NULL) {
|
|
printf("[err] audio_wd malloc fail !!!");
|
|
return 0;
|
|
}
|
|
#if WIND_DETECT_INFO_SPP_DEBUG_ENABLE
|
|
spp_get_operation_table(&audio_wd->spp_opt);
|
|
#endif
|
|
overlay_load_code(OVERLAY_AEC);
|
|
err = os_task_create(audio_wind_detect_task, NULL, 2, 256, 128, WIND_DETECT_TASK_NAME);
|
|
/* err = task_create(audio_wind_detect_task, NULL, WIND_DETECT_TASK_NAME); */
|
|
if (err != OS_NO_ERR) {
|
|
printf("task create error!");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*关闭获取风噪信息的任务*/
|
|
int audio_wind_info_task_close(void)
|
|
{
|
|
if (audio_wd) {
|
|
/* task_kill(WIND_DETECT_TASK_NAME); */
|
|
os_task_del(WIND_DETECT_TASK_NAME);
|
|
free(audio_wd);
|
|
audio_wd = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*打开风噪检测的demo*/
|
|
int audio_wind_detect_demo_open(void)
|
|
{
|
|
/*打开风噪检测*/
|
|
audio_wind_detect_open(16000, 4, 4, 1, 1);
|
|
/*获取风噪的信息*/
|
|
audio_wind_info_task_open();
|
|
return 0;
|
|
}
|
|
|
|
/*关闭风噪检测的demo*/
|
|
int audio_wind_detect_demo_close(void)
|
|
{
|
|
audio_wind_detect_close();
|
|
audio_wind_info_task_close();
|
|
return 0;
|
|
}
|
|
|
|
/*获取风噪信息*/
|
|
int audio_get_wind_detect_info(void)
|
|
{
|
|
if (audio_wd) {
|
|
#if TCFG_AUDIO_TRIPLE_MIC_ENABLE
|
|
jlsp_tms_get_wind_detect_info(&audio_wd->wd_flag, &audio_wd->wd_val, &audio_wd->wd_lev);
|
|
#elif TCFG_AUDIO_DUAL_MIC_ENABLE
|
|
jlsp_get_wind_detect_info(&audio_wd->wd_flag, &audio_wd->wd_val, &audio_wd->wd_lev);
|
|
#endif
|
|
printf("wd_flag:%d, wd_val:%d, wd_lev:%d", audio_wd->wd_flag, audio_wd->wd_val, audio_wd->wd_lev);
|
|
|
|
#if WIND_DETECT_INFO_SPP_DEBUG_ENABLE
|
|
if (audio_wd->spp_opt && audio_wd->spp_opt->send_data) {
|
|
char tmpbuf[25];
|
|
memset(tmpbuf, 0x20, sizeof(tmpbuf));
|
|
sprintf(tmpbuf, "falg:%d, val:%d, lev:%d", audio_wd->wd_flag, audio_wd->wd_val, audio_wd->wd_lev);
|
|
audio_wd->spp_opt->send_data(NULL, tmpbuf, sizeof(tmpbuf));
|
|
}
|
|
#endif
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*获取是否有风,0:无风,1:有风*/
|
|
int audio_get_wd_flag(void)
|
|
{
|
|
if (audio_wd) {
|
|
return audio_wd->wd_flag;
|
|
}
|
|
return -1;
|
|
}
|
|
/*获取风强*/
|
|
int audio_get_wd_val(void)
|
|
{
|
|
if (audio_wd) {
|
|
return audio_wd->wd_val;
|
|
}
|
|
return -1;
|
|
}
|
|
/*获取预设的风噪等级, 0:弱风,1:中风:2:强风*/
|
|
int audio_get_wd_lev(void)
|
|
{
|
|
if (audio_wd) {
|
|
return audio_wd->wd_lev;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static u8 audio_wind_detect_idle_query()
|
|
{
|
|
return (audio_wd == NULL) ? 1 : 0;
|
|
}
|
|
/*
|
|
REGISTER_LP_TARGET(audio_wind_detect_lp_target) = {
|
|
.name = "audio_wind_detect",
|
|
.is_idle = audio_wind_detect_idle_query,
|
|
};
|
|
|
|
*/
|