KT25-1015_AC695x_SDK310/cpu/br23/audio_enc/audio_adc_demo.c
2025-10-15 15:18:43 +08:00

236 lines
6.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
*****************************************************************
*
* 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