236 lines
6.9 KiB
C
236 lines
6.9 KiB
C
|
|
/*
|
|||
|
|
*****************************************************************
|
|||
|
|
*
|
|||
|
|
* 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
|