Files
BLE-USB_Dongle/cpu/br28/audio_demo/audio_wind_detect_demo.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,
};
*/