#include "asm/includes.h" #include "media/includes.h" #include "system/includes.h" #include "audio_enc.h" #include "app_main.h" #include "app_config.h" #include "audio_splicing.h" #include "media/audio_echo_reverb.h" /*usb mic的数据是否经过AEC,包括里面的ANS模块*/ #define USB_MIC_AEC_EN 0 /*AEC模块只能处理16k数据,如果经过aec,就需要对输出数据做变采样*/ #define USB_MIC_SRC_ENABLE 1 #if USB_MIC_AEC_EN #include "aec_user.h" #endif/*USB_MIC_AEC_EN*/ #if TCFG_APP_PC_EN #include "device/uac_stream.h" #define PCM_ENC2USB_OUTBUF_LEN (4 * 1024) /* #define USB_MIC_BUF_NUM 3 */ /* #define USB_MIC_CH_NUM 1 */ /* #define USB_MIC_IRQ_POINTS 1//256 */ /* #define USB_MIC_BUFS_SIZE (USB_MIC_CH_NUM * USB_MIC_BUF_NUM * USB_MIC_IRQ_POINTS) */ #define USB_MIC_STOP 0x00 #define USB_MIC_START 0x01 extern struct audio_adc_hdl adc_hdl; extern u16 uac_get_mic_vol(const u8 usb_id); struct _usb_mic_hdl { struct audio_adc_output_hdl adc_output; struct adc_mic_ch mic_ch; struct audio_adc_ch linein_ch; #if SOUNDCARD_ENABLE //4取1 s16 *temp_buf; u32 temp_buf_len; #endif enum enc_source source; cbuffer_t output_cbuf; u8 *output_buf;//[PCM_ENC2USB_OUTBUF_LEN]; u8 rec_tx_channels; u8 mic_data_ok;/*mic数据等到一定长度再开始发送*/ u8 status; u8 mic_busy; #if TCFG_USB_MIC_ECHO_ENABLE ECHO_API_STRUCT *p_echo_hdl; #endif }; static struct _usb_mic_hdl *usb_mic_hdl = NULL; #if TCFG_USB_MIC_ECHO_ENABLE ECHO_PARM_SET usbmic_echo_parm_default = { .delay = 200, //回声的延时时间 0-300ms .decayval = 50, // 0-70% .direct_sound_enable = 1, //直达声使能 0/1 .filt_enable = 1, //发散滤波器使能 }; EF_REVERB_FIX_PARM usbmic_echo_fix_parm_default = { .wetgain = 2048, ////湿声增益:[0:4096] .drygain = 4096, ////干声增益: [0:4096] .sr = MIC_EFFECT_SAMPLERATE, ////采样率 .max_ms = 200, ////所需要的最大延时,影响 need_buf 大小 }; #endif static int usb_audio_mic_sync(u32 data_size) { #if 0 int change_point = 0; if (data_size > __this->rec_top_size) { change_point = -1; } else if (data_size < __this->rec_bottom_size) { change_point = 1; } if (change_point) { struct audio_pcm_src src; src.resample = 0; src.ratio_i = (1024) * 2; src.ratio_o = (1024 + change_point) * 2; src.convert = 1; dev_ioctl(__this->rec_dev, AUDIOC_PCM_RATE_CTL, (u32)&src); } #endif return 0; } static int usb_audio_mic_tx_handler(int event, void *data, int len) { if (usb_mic_hdl == NULL) { return 0; } if (usb_mic_hdl->status == USB_MIC_STOP) { return 0; } int i = 0; int r_len = 0; u8 ch = 0; u8 double_read = 0; int rlen = 0; if (usb_mic_hdl->mic_data_ok == 0) { if (usb_mic_hdl->output_cbuf.data_len > (PCM_ENC2USB_OUTBUF_LEN / 4)) { usb_mic_hdl->mic_data_ok = 1; } else { //y_printf("mic_tx NULL\n"); memset(data, 0, len); return 0; } } /* usb_audio_mic_sync(size); */ if (usb_mic_hdl->rec_tx_channels == 2) { rlen = cbuf_get_data_size(&usb_mic_hdl->output_cbuf); if (rlen) { rlen = rlen > (len / 2) ? (len / 2) : rlen; rlen = cbuf_read(&usb_mic_hdl->output_cbuf, data, rlen); } else { /* printf("uac read err1\n"); */ usb_mic_hdl->mic_data_ok = 0; return 0; } len = rlen * 2; s16 *tx_pcm = (s16 *)data; int cnt = len / 2; for (cnt = len / 2; cnt >= 2;) { tx_pcm[cnt - 1] = tx_pcm[cnt / 2 - 1]; tx_pcm[cnt - 2] = tx_pcm[cnt / 2 - 1]; cnt -= 2; } rlen = len; } else { rlen = cbuf_get_data_size(&usb_mic_hdl->output_cbuf); if (rlen) { rlen = rlen > len ? len : rlen; rlen = cbuf_read(&usb_mic_hdl->output_cbuf, data, rlen); } else { /* printf("uac read err2\n"); */ usb_mic_hdl->mic_data_ok = 0; return 0; } } return rlen; } int usb_audio_mic_write_do(void *data, u16 len) { int wlen = len; if (usb_mic_hdl && usb_mic_hdl->status == USB_MIC_START) { usb_mic_hdl->mic_busy = 1; #if SOUNDCARD_ENABLE //4取1 if (usb_mic_hdl->temp_buf) { if (usb_mic_hdl->temp_buf_len < len / 4) { free(usb_mic_hdl->temp_buf); usb_mic_hdl->temp_buf = NULL; } } if (!usb_mic_hdl->temp_buf) { usb_mic_hdl->temp_buf_len = len / 4; usb_mic_hdl->temp_buf = (s16 *) zalloc(usb_mic_hdl->temp_buf_len); } s16 *temp_pcm = (s16 *)data; for (int cnt = 0; cnt < len / 8; cnt++) { usb_mic_hdl->temp_buf[cnt] = temp_pcm[cnt * 4 + 2];//取RL通道 } len = len / 4; wlen = cbuf_write(&usb_mic_hdl->output_cbuf, usb_mic_hdl->temp_buf, len); #else wlen = cbuf_write(&usb_mic_hdl->output_cbuf, data, len); #endif //SOUNDCARD_ENABLE #if 0 static u32 usb_mic_data_max = 0; if (usb_mic_data_max < usb_mic_hdl->output_cbuf.data_len) { usb_mic_data_max = usb_mic_hdl->output_cbuf.data_len; y_printf("usb_mic_max:%d", usb_mic_data_max); } #endif if (wlen != (len)) { putchar('L'); //r_printf("usb_mic write full:%d-%d\n", wlen, len); } usb_mic_hdl->mic_busy = 0; } return wlen; } int usb_audio_mic_write(void *data, u16 len) { pcm_dual_to_single(data, data, len); int wlen = usb_audio_mic_write_do(data, len / 2); return wlen; } static void adc_output_to_cbuf(void *priv, s16 *data, int len) { if (usb_mic_hdl == NULL) { return ; } if (usb_mic_hdl->status == USB_MIC_STOP) { return ; } switch (usb_mic_hdl->source) { case ENCODE_SOURCE_MIC: case ENCODE_SOURCE_LINE0_LR: case ENCODE_SOURCE_LINE1_LR: case ENCODE_SOURCE_LINE2_LR: { #if USB_MIC_AEC_EN audio_aec_inbuf(data, len); #else #if TCFG_USB_MIC_ECHO_ENABLE if (usb_mic_hdl->p_echo_hdl) { run_echo(usb_mic_hdl->p_echo_hdl, data, data, len); } #endif int wlen = cbuf_write(&usb_mic_hdl->output_cbuf, data, len); if (wlen != len) { printf("wlen %d len %d\n", wlen, len); } #endif } break; default: break; } } #if USB_MIC_SRC_ENABLE #include "common/Resample_api.h" typedef struct { u8 start; u8 busy; u16 output_rate; u32 *runbuf; s16 output[320 * 3 + 16]; RS_STUCT_API *ops; } usb_mic_sw_src_t; static usb_mic_sw_src_t *usb_mic_src = NULL; static int sw_src_init(u32 in_sr, u32 out_sr) { usb_mic_src = zalloc(sizeof(usb_mic_sw_src_t)); ASSERT(usb_mic_src); usb_mic_src->ops = get_rs16_context(); ASSERT(usb_mic_src->ops); u32 need_buf = usb_mic_src->ops->need_buf(); printf("sw_src need_buf:%d\n", need_buf); usb_mic_src->runbuf = zalloc(need_buf); ASSERT(usb_mic_src->runbuf); RS_PARA_STRUCT rs_para_obj; rs_para_obj.nch = 1; rs_para_obj.new_insample = in_sr; rs_para_obj.new_outsample = out_sr; printf("sw src,in = %d,out = %d\n", rs_para_obj.new_insample, rs_para_obj.new_outsample); usb_mic_src->ops->open(usb_mic_src->runbuf, &rs_para_obj); usb_mic_src->start = 1; return 0; } static int sw_src_exit(void) { if (usb_mic_src) { usb_mic_src->start = 0; while (usb_mic_src->busy) { putchar('w'); os_time_dly(2); } local_irq_disable(); if (usb_mic_src->runbuf) { free(usb_mic_src->runbuf); } free(usb_mic_src); local_irq_enable(); printf("sw_src_exit\n"); } printf("sw_src_exit ok\n"); return 0; } #endif/*USB_MIC_SRC_ENABLE*/ static int usb_mic_aec_output(s16 *data, u16 len) { //putchar('k'); if (usb_mic_hdl == NULL) { return len ; } if (usb_mic_hdl->status == USB_MIC_STOP) { return len; } u16 olen = len; s16 *obuf = data; #if USB_MIC_SRC_ENABLE if (usb_mic_src && usb_mic_src->start) { usb_mic_src->busy = 1; int outlen = usb_mic_src->ops->run(usb_mic_src->runbuf, data, len >> 1, usb_mic_src->output); usb_mic_src->busy = 0; ASSERT(outlen <= (sizeof(usb_mic_src->output) >> 1)); /* printf("16->48k:%d,%d,%d\n",len >> 1,outlen,sizeof(sw_src->output)); */ obuf = usb_mic_src->output; olen = outlen << 1; } #endif/*USB_MIC_SRC_ENABLE*/ usb_audio_mic_write_do(obuf, olen); return len; } int uac_mic_vol_switch(int vol) { return vol * 14 / 100; } int usb_audio_mic_open(void *_info) { printf("usb_audio_mic_open -----------------------------------------------------\n"); if (usb_mic_hdl) { return 0; } struct _usb_mic_hdl *hdl = NULL; hdl = zalloc(sizeof(struct _usb_mic_hdl)); if (!hdl) { return -EFAULT; } local_irq_disable(); usb_mic_hdl = hdl; local_irq_enable(); hdl->status = USB_MIC_STOP; #if 0 hdl->adc_buf = zalloc(USB_MIC_BUFS_SIZE * 2); if (!hdl->adc_buf) { printf("hdl->adc_buf NULL\n"); if (hdl) { free(hdl); hdl = NULL; } return -EFAULT; } #endif hdl->output_buf = zalloc(PCM_ENC2USB_OUTBUF_LEN); if (!hdl->output_buf) { printf("hdl->output_buf NULL\n"); /* if (hdl->adc_buf) { */ /* free(hdl->adc_buf); */ /* } */ if (hdl) { free(hdl); hdl = NULL; } return -EFAULT; } u32 sample_rate = (u32)_info & 0xFFFFFF; u32 output_rate = sample_rate; hdl->rec_tx_channels = (u32)_info >> 24; hdl->source = ENCODE_SOURCE_MIC; printf("usb mic sr:%d ch:%d\n", sample_rate, hdl->rec_tx_channels); #if USB_MIC_AEC_EN printf("usb mic sr[aec]:%d\n", sample_rate); sample_rate = 16000; #if USB_MIC_SRC_ENABLE sw_src_init(sample_rate, output_rate); #endif/*USB_MIC_SRC_ENABLE*/ //audio_aec_init(sample_rate); audio_aec_open(sample_rate, ANS_EN, usb_mic_aec_output); #endif/*USB_MIC_AEC_EN*/ cbuf_init(&hdl->output_cbuf, hdl->output_buf, PCM_ENC2USB_OUTBUF_LEN); #if (SOUNDCARD_ENABLE) ///从mix output哪里获取usb mic上行数据 #if(TCFG_USB_MIC_DATA_FROM_DAC) mic_effect_to_usbmic_onoff(1); #endif//TCFG_USB_MIC_DATA_FROM_DAC #else #if TCFG_MIC_EFFECT_ENABLE app_var.usb_mic_gain = mic_effect_get_micgain(); #else app_var.usb_mic_gain = uac_mic_vol_switch(uac_get_mic_vol(0)); #endif//TCFG_MIC_EFFECT_ENABLE #if (TCFG_USB_MIC_DATA_FROM_MICEFFECT) mic_effect_to_usbmic_onoff(1); #else #if 0 audio_adc_mic_open(&hdl->mic_ch, AUDIO_ADC_MIC_CH, &adc_hdl); audio_adc_mic_set_sample_rate(&hdl->mic_ch, sample_rate); audio_adc_mic_set_gain(&hdl->mic_ch, app_var.usb_mic_gain); audio_adc_mic_set_buffs(&hdl->mic_ch, hdl->adc_buf, USB_MIC_IRQ_POINTS * 2, USB_MIC_BUF_NUM); hdl->adc_output.handler = adc_output_to_cbuf; audio_adc_add_output_handler(&adc_hdl, &hdl->adc_output); audio_adc_mic_start(&hdl->mic_ch); #else audio_mic_open(&hdl->mic_ch, sample_rate, app_var.usb_mic_gain); hdl->adc_output.handler = adc_output_to_cbuf; audio_mic_add_output(&hdl->adc_output); audio_mic_start(&hdl->mic_ch); #endif #endif//TCFG_USB_MIC_DATA_FROM_MICEFFECT #endif//SOUNDCARD_ENABLE #if TCFG_USB_MIC_ECHO_ENABLE hdl->p_echo_hdl = open_echo(&usbmic_echo_parm_default, &usbmic_echo_fix_parm_default); #endif set_uac_mic_tx_handler(NULL, usb_audio_mic_tx_handler); hdl->status = USB_MIC_START; hdl->mic_busy = 0; /* __this->rec_begin = 0; */ return 0; } u32 usb_mic_is_running() { if (usb_mic_hdl) { return SPK_AUDIO_RATE; } return 0; } /* ************************************************************* * * usb mic gain save * ************************************************************* */ static int usb_mic_gain_save_timer; static u8 usb_mic_gain_save_cnt; static void usb_audio_mic_gain_save_do(void *priv) { //printf(" usb_audio_mic_gain_save_do %d\n", usb_mic_gain_save_cnt); local_irq_disable(); if (++usb_mic_gain_save_cnt >= 5) { sys_hi_timer_del(usb_mic_gain_save_timer); usb_mic_gain_save_timer = 0; usb_mic_gain_save_cnt = 0; local_irq_enable(); printf("USB_GAIN_SAVE\n"); syscfg_write(VM_USB_MIC_GAIN, &app_var.usb_mic_gain, 1); return; } local_irq_enable(); } static void usb_audio_mic_gain_change(u8 gain) { local_irq_disable(); app_var.usb_mic_gain = gain; usb_mic_gain_save_cnt = 0; if (usb_mic_gain_save_timer == 0) { usb_mic_gain_save_timer = sys_hi_timer_add(NULL, usb_audio_mic_gain_save_do, 1000); } local_irq_enable(); } int usb_audio_mic_get_gain(void) { return app_var.usb_mic_gain; } void usb_audio_mic_set_gain(int gain) { #if (SOUNDCARD_ENABLE) return ; #endif//SOUNDCARD_ENABLE if (usb_mic_hdl == NULL) { r_printf("usb_mic_hdl NULL gain"); return; } gain = uac_mic_vol_switch(gain); audio_adc_mic_set_gain(&usb_mic_hdl->mic_ch, gain); usb_audio_mic_gain_change(gain); } int usb_audio_mic_close(void *arg) { if (usb_mic_hdl == NULL) { r_printf("usb_mic_hdl NULL close"); return 0; } printf("usb_mic_hdl->status %x\n", usb_mic_hdl->status); if (usb_mic_hdl && usb_mic_hdl->status == USB_MIC_START) { printf("usb_audio_mic_close in\n"); usb_mic_hdl->status = USB_MIC_STOP; #if USB_MIC_AEC_EN audio_aec_close(); #endif/*USB_MIC_AEC_EN*/ #if USB_MIC_SRC_ENABLE sw_src_exit(); #endif/*USB_MIC_SRC_ENABLE*/ #if (SOUNDCARD_ENABLE) //从声卡输出端获取, 没有打开mic, 所以这里不需要关 #if (TCFG_USB_MIC_DATA_FROM_DAC) mic_effect_to_usbmic_onoff(0); #endif//TCFG_USB_MIC_DATA_FROM_DAC #else #if (TCFG_USB_MIC_DATA_FROM_MICEFFECT) mic_effect_to_usbmic_onoff(0); #else #if 0 audio_adc_mic_close(&usb_mic_hdl->mic_ch); audio_adc_del_output_handler(&adc_hdl, &usb_mic_hdl->adc_output); #else audio_mic_close(&usb_mic_hdl->mic_ch, &usb_mic_hdl->adc_output); #endif #endif//TCFG_USB_MIC_DATA_FROM_MICEFFECT #endif//SOUNDCARD_ENABLE #if TCFG_USB_MIC_ECHO_ENABLE if (usb_mic_hdl->p_echo_hdl) { close_echo(usb_mic_hdl->p_echo_hdl); } #endif cbuf_clear(&usb_mic_hdl->output_cbuf); if (usb_mic_hdl) { while (usb_mic_hdl->mic_busy) { os_time_dly(3); } local_irq_disable(); #if SOUNDCARD_ENABLE //4取1 if (usb_mic_hdl->temp_buf) { free(usb_mic_hdl->temp_buf); usb_mic_hdl->temp_buf = NULL; } usb_mic_hdl->temp_buf_len = 0; #endif if (usb_mic_hdl->output_buf) { free(usb_mic_hdl->output_buf); usb_mic_hdl->output_buf = NULL; } free(usb_mic_hdl); usb_mic_hdl = NULL; local_irq_enable(); } } printf("usb_audio_mic_close out\n"); return 0; } #endif