KT25-1015_AC695x_SDK310/cpu/br23/audio_enc/audio_adc_demo.c

236 lines
6.9 KiB
C
Raw Normal View History

2025-10-15 07:18:43 +00:00
/*
*****************************************************************
*
* 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,1linein或者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,1linein和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,2linein 1mic
* 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