/* ***************************************************************** * * Audio ADC 多通道使用demo * ***************************************************************** */ #include "asm/includes.h" #include "media/includes.h" #include "system/includes.h" #include "asm/audio_src.h" #include "audio_enc.h" #include "app_main.h" //#include "app_task.h" #include "audio_config.h" extern struct audio_adc_hdl adc_hdl; /*总共使能多少个通道*/ #define LADC_CH_NUM 1 #define LADC_BUF_NUM 2 #define LADC_IRQ_POINTS 256 /*中断点数*/ #define LADC_BUFS_SIZE (LADC_CH_NUM * LADC_BUF_NUM * LADC_IRQ_POINTS) /*调试使用,推mic数据/linein数据/mic&line混合数据到dac*/ #define LADC_2_DAC_ENABLE 1 #define LADC_MIC_2_DAC BIT(0) #define LADC_LIN_2_DAC BIT(1) #define LADC_2_DAC (LADC_MIC_2_DAC | LADC_LIN_2_DAC) typedef struct { struct audio_adc_output_hdl output; struct audio_adc_ch linein_ch; struct adc_mic_ch mic_ch; s16 adc_buf[LADC_BUFS_SIZE]; //align 4Bytes s16 temp_buf[LADC_IRQ_POINTS * 3]; } audio_adc_t; static audio_adc_t *ladc_var = NULL; /* * 使能1个通道,1个linein或者1个mic: * 数据结构:DAT0 DAT1 DAT2 */ static void audio_adc1_output_demo(void *priv, s16 *data, int len) { struct audio_adc_hdl *hdl = priv; int wlen = 0; putchar('1'); if (ladc_var == NULL) { return; } /* printf("linein:%x,len:%d,ch:%d",data,len,hdl->channel); */ #if LADC_2_DAC_ENABLE #if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)//双声道数据结构 for (int i = 0; i < (len / 2); i++) { ladc_var->temp_buf[i * 2] = data[i]; ladc_var->temp_buf[i * 2 + 1] = data[i]; } wlen = app_audio_output_write(ladc_var->temp_buf, len * 2); #else //单声道数据结构 //TODO wlen = app_audio_output_write(data, len * hdl->channel); #endif/*TCFG_AUDIO_DAC_CONNECT_MODE*/ #endif/*LADC_2_DAC_ENABLE*/ } /* * 使能2个通道,1个linein和1个mic: * 数据结构:LIN0 MIC0 LIN1 MIC1 LIN2 MIC2 */ static void audio_adc2_output_demo(void *priv, s16 *data, int len) { struct audio_adc_hdl *hdl = priv; int wlen = 0; putchar('2'); if (ladc_var == NULL) { return; } /* printf("linein:%x,len:%d,ch:%d",data,len,hdl->channel); */ #if LADC_2_DAC_ENABLE #if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)//双声道数据结构 wlen = app_audio_output_write(data, len * 2); #else //单声道数据结构 //TODO #endif/*TCFG_AUDIO_DAC_CONNECT_MODE*/ #endif/*LADC_2_DAC_ENABLE*/ } /* * 使能3个通道,2个linein 和 1个mic: * 数据结构:LINL0 LINR0 MIC0 LINL1 LINR1 MIC1 LINL2 LINR2 MIC2... */ static void audio_adc3_output_demo(void *priv, s16 *data, int len) { struct audio_adc_hdl *hdl = priv; int wlen = 0; putchar('3'); if (ladc_var == NULL) { return; } /* printf("linein:%x,len:%d,ch:%d",data,len,hdl->channel); */ #if LADC_2_DAC_ENABLE #if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)//双声道数据结构 #if (LADC_2_DAC == LADC_LIN_2_DAC) for (u16 i = 0; i < len / 2; i++) { data[2 * i] = data[3 * i]; data[2 * i + 1] = data[3 * i + 1]; } #elif (LADC_2_DAC == LADC_MIC_2_DAC) for (u16 i = 0; i < len / 2; i++) { data[2 * i] = data[3 * i + 2]; data[2 * i + 1] = data[3 * i + 2]; } #else //linein data and mic data mix int tmp_data; for (u16 i = 0; i < len / 2; i++) { tmp_data = data[3 * i]; tmp_data += data[3 * i + 2]; if (tmp_data > 32767) { tmp_data = 32767; } else if (tmp_data < -32768) { tmp_data = -32768; } data[2 * i] = tmp_data; tmp_data = data[3 * i + 1]; tmp_data += data[3 * i + 2]; if (tmp_data > 32767) { tmp_data = 32767; } else if (tmp_data < -32768) { tmp_data = -32768; } data[2 * i + 1] = tmp_data; } #endif/*LADC_2_DAC*/ wlen = app_audio_output_write(data, len * 2); #else //单声道数据结构 #endif/*TCFG_AUDIO_DAC_CONNECT_MODE*/ #endif/*LADC_2_DAC_ENABLE*/ } int audio_adc_open_demo(void) { u16 ladc_sr = 16000; u8 mic_gain = 5; u8 linein_gain = 3; r_printf("audio_adc_open_demo,sr:%d,mic_gain:%d,linein_gain:%d\n", ladc_sr, mic_gain, linein_gain); if (ladc_var) { r_printf("ladc already open \n"); return 0; } ladc_var = zalloc(sizeof(audio_adc_t)); if (ladc_var) { #if (LADC_CH_NUM == 1) audio_adc_mic_open(&ladc_var->mic_ch, AUDIO_ADC_MIC_CH, &adc_hdl); audio_adc_mic_set_sample_rate(&ladc_var->mic_ch, ladc_sr); audio_adc_mic_set_gain(&ladc_var->mic_ch, mic_gain); audio_adc_mic_set_buffs(&ladc_var->mic_ch, ladc_var->adc_buf, LADC_CH_NUM * LADC_IRQ_POINTS * 2, LADC_BUF_NUM); ladc_var->output.handler = audio_adc1_output_demo; ladc_var->output.priv = &adc_hdl; audio_adc_add_output_handler(&adc_hdl, &ladc_var->output); audio_adc_mic_start(&ladc_var->mic_ch); #else audio_adc_mic_open(&ladc_var->mic_ch, AUDIO_ADC_MIC_CH, &adc_hdl); audio_adc_mic_set_sample_rate(&ladc_var->mic_ch, ladc_sr); audio_adc_mic_set_gain(&ladc_var->mic_ch, mic_gain); #if (LADC_CH_NUM ==2 ) audio_adc_linein_open(&ladc_var->linein_ch, AUDIO_ADC_LINE0_L, &adc_hdl); //audio_adc_linein_open(&ladc_var->linein_ch, AUDIO_ADC_LINE0_R, &adc_hdl); #else audio_adc_linein_open(&ladc_var->linein_ch, AUDIO_ADC_LINE0_LR, &adc_hdl); #endif audio_adc_linein_set_sample_rate(&ladc_var->linein_ch, ladc_sr); audio_adc_linein_set_gain(&ladc_var->linein_ch, linein_gain); printf("adc_buf_size:%d", sizeof(ladc_var->adc_buf)); audio_adc_set_buffs(&ladc_var->linein_ch, ladc_var->adc_buf, LADC_CH_NUM * LADC_IRQ_POINTS * 2, LADC_BUF_NUM); #if (LADC_CH_NUM == 2) ladc_var->output.handler = audio_adc2_output_demo; #else ladc_var->output.handler = audio_adc3_output_demo; #endif/*LADC_CH_NUM*/ ladc_var->output.priv = &adc_hdl; audio_adc_add_output_handler(&adc_hdl, &ladc_var->output); audio_adc_start(&ladc_var->linein_ch, &ladc_var->mic_ch); #endif #if LADC_2_DAC_ENABLE app_audio_output_samplerate_set(ladc_sr); app_audio_output_start(); #endif/*LADC_2_DAC_ENABLE*/ return 0; } else { return -1; } } void audio_adc_close_demo() { if (ladc_var) { audio_adc_mic_close(&ladc_var->mic_ch); audio_adc_del_output_handler(&adc_hdl, &ladc_var->output); local_irq_disable(); free(ladc_var); ladc_var = NULL; local_irq_enable(); extern void audio_output_stop(void); audio_output_stop(); } } #if 1 static u8 audio_adc_demo_idle_query(void) { if (ladc_var) { return 0; } return 1; } REGISTER_LP_TARGET(audio_adc_demo) = { .name = "audio_adc_demo", .is_idle = audio_adc_demo_idle_query, }; #endif