KT24-1110_65E-HA-651B/cpu/br25/audio_enc/audio_mic_codec.c

265 lines
7.1 KiB
C
Raw Normal View History

2024-11-10 10:44:17 +00:00
#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 "btstack/avctp_user.h"
#include "app_config.h"
#ifndef CONFIG_LITE_AUDIO
#include "aec_user.h"
#endif/*CONFIG_LITE_AUDIO*/
#if (TCFG_ENC_OPUS_ENABLE) || (TCFG_ENC_SPEEX_ENABLE)
extern struct audio_encoder_task *encode_task;
//static struct audio_encoder_task *encode_task = NULL;
#define ENC_ADC_BUF_NUM (2)
#define ENC_ADC_IRQ_POINTS (320)
#define ENC_ADC_BUFS_SIZE (ENC_ADC_BUF_NUM * ENC_ADC_IRQ_POINTS)
#define MIC_USE_MIC_CHANNEL (1)
#define MIC_ENC_IN_SIZE (ENC_ADC_IRQ_POINTS * 2)
#define MIC_ENC_OUT_SIZE (ENC_ADC_IRQ_POINTS)
struct mic_enc_hdl {
struct audio_encoder encoder;
OS_SEM pcm_frame_sem;
u8 output_frame[MIC_ENC_OUT_SIZE];
u8 pcm_frame[MIC_ENC_IN_SIZE];
u8 frame_size;
u8 in_cbuf_buf[MIC_ENC_IN_SIZE * 4];
cbuffer_t pcm_in_cbuf;
int (*mic_output)(void *priv, void *buf, int len);
#if mic_ENC_PACK_ENABLE
u16 cp_type;
u16 packet_head_sn;
#endif
#if MIC_USE_MIC_CHANNEL
struct audio_adc_output_hdl adc_output;
struct adc_mic_ch mic_ch;
s16 adc_buf[ENC_ADC_BUFS_SIZE]; //align 4Bytes
#endif
};
static struct mic_enc_hdl *mic_enc = NULL;
static void mic_enc_output_func_register(int (*output_func)(void *priv, void *buf, int len))
{
if (mic_enc) {
mic_enc->mic_output = output_func;
}
}
void mic_enc_resume(void)
{
if (mic_enc) {
os_sem_post(&mic_enc->pcm_frame_sem);
}
}
static int mic_enc_pcm_get(struct audio_encoder *encoder, s16 **frame, u16 frame_len)
{
int pcm_len = 0;
if (mic_enc == NULL) {
r_printf("mic_enc NULL\n");
return 0;
}
/* putchar('!'); */
if ((&mic_enc->pcm_in_cbuf)->data_len < frame_len) {
/* putchar('#'); */
os_sem_set(&mic_enc->pcm_frame_sem, 0);
os_sem_pend(&mic_enc->pcm_frame_sem, 5);
if (mic_enc == NULL) {
printf("mic_enc is NULL\n");
return 0;
}
}
pcm_len = cbuf_read(&mic_enc->pcm_in_cbuf, mic_enc->pcm_frame, frame_len);
if (pcm_len != frame_len) {
putchar('L');
}
/* putchar('D'); */
*frame = mic_enc->pcm_frame;
return pcm_len;
}
static void mic_enc_pcm_put(struct audio_encoder *encoder, s16 *frame)
{
}
static const struct audio_enc_input mic_enc_input = {
.fget = mic_enc_pcm_get,
.fput = mic_enc_pcm_put,
};
static int mic_enc_probe_handler(struct audio_encoder *encoder)
{
return 0;
}
static int mic_enc_output_handler(struct audio_encoder *encoder, u8 *frame, int len)
{
if (encoder == NULL) {
r_printf("encoder NULL");
}
wdt_clear();
/* printf("mic frame len:%d \n",len); */
if (mic_enc && mic_enc->mic_output) {
mic_enc->mic_output(NULL, frame, len);
}
/* put_buf(frame, 16); */
return len;
}
const static struct audio_enc_handler mic_enc_handler = {
.enc_probe = mic_enc_probe_handler,
.enc_output = mic_enc_output_handler,
};
static void mic_enc_event_handler(struct audio_decoder *decoder, int argc, int *argv)
{
printf("mic_enc_event_handler:0x%x,%d\n", argv[0], argv[0]);
switch (argv[0]) {
case AUDIO_ENC_EVENT_END:
puts("AUDIO_ENC_EVENT_END\n");
break;
}
}
static void adc_mic_output_handler(void *priv, s16 *data, int len)
{
if (mic_enc) {
u16 wlen = cbuf_write(&mic_enc->pcm_in_cbuf, data, len);
if (wlen != len) {
putchar('@');
}
audio_encoder_resume(&mic_enc->encoder);
mic_enc_resume();
}
}
#define HIGHT_COMPLEX 0
#define LOW_COMPLEX (BIT(4))
extern struct audio_adc_hdl adc_hdl;
int audio_mic_enc_open(int (*mic_output)(void *priv, void *buf, int len), u32 code_type, u8 ai_type)
{
int err;
struct audio_fmt fmt;
switch (code_type) {
case AUDIO_CODING_OPUS:
//1. quality:bitrate 0:16kbps 1:32kbps 2:64kbps
// quality: MSB_2:(bit7_bit6) format_mode //0:百度_无头. 1:酷狗_eng+range.
// quality:LMSB_2:(bit5_bit4) low_complexity //0:高复杂度,高质量.兼容之前库. 1:低复杂度,低质量.
//2. sample_rate sample_rate=16k ignore
fmt.quality = 0 | ai_type /*| LOW_COMPLEX*/;
fmt.sample_rate = 16000;
fmt.coding_type = AUDIO_CODING_OPUS;
break;
case AUDIO_CODING_SPEEX:
fmt.quality = 5;
fmt.complexity = 2;
fmt.sample_rate = 16000;
fmt.coding_type = AUDIO_CODING_SPEEX;
break;
default:
printf("do not support this type !!!\n");
return -1;
break;
}
audio_encoder_task_open();
/* if (!encode_task) { */
/* encode_task = zalloc(sizeof(*encode_task)); */
/* if (!encode_task) { */
/* printf("encode_task NULL !!!\n"); */
/* } */
/* audio_encoder_task_create(encode_task, "audio_enc"); */
/* } */
if (!mic_enc) {
mic_enc = zalloc(sizeof(*mic_enc));
if (!mic_enc) {
printf("mic_enc NULL !!!\n");
}
memset(mic_enc, 0x00, sizeof(*mic_enc));
}
mic_enc_output_func_register(mic_output);
cbuf_init(&mic_enc->pcm_in_cbuf, mic_enc->in_cbuf_buf, MIC_ENC_IN_SIZE * 4);
os_sem_create(&mic_enc->pcm_frame_sem, 0);
audio_encoder_open(&mic_enc->encoder, &mic_enc_input, encode_task);
audio_encoder_set_handler(&mic_enc->encoder, &mic_enc_handler);
audio_encoder_set_fmt(&mic_enc->encoder, &fmt);
audio_encoder_set_event_handler(&mic_enc->encoder, mic_enc_event_handler, 0);
audio_encoder_set_output_buffs(&mic_enc->encoder, mic_enc->output_frame,
sizeof(mic_enc->output_frame), 1);
int start_err = audio_encoder_start(&mic_enc->encoder);
#if MIC_USE_MIC_CHANNEL
fmt.sample_rate = 16000;
audio_adc_mic_open(&mic_enc->mic_ch, AUDIO_ADC_MIC_CH, &adc_hdl);
audio_adc_mic_set_sample_rate(&mic_enc->mic_ch, fmt.sample_rate);
app_var.aec_mic_gain = 15;
printf(">>>>>>>>>mic gain:%d \n", app_var.aec_mic_gain);
audio_adc_mic_set_gain(&mic_enc->mic_ch, app_var.aec_mic_gain);
audio_adc_mic_set_buffs(&mic_enc->mic_ch, mic_enc->adc_buf,
ENC_ADC_IRQ_POINTS * 2, ENC_ADC_BUF_NUM);
mic_enc->adc_output.handler = adc_mic_output_handler;
audio_adc_add_output_handler(&adc_hdl, &mic_enc->adc_output);
//app_audio_output_samplerate_set(44100);
//app_audio_output_start();
audio_adc_mic_start(&mic_enc->mic_ch);
#endif
printf("mic_enc_open ok %d\n", start_err);
return 0;
}
int audio_mic_enc_close()
{
if (!mic_enc) {
return -1;
}
printf("audio_mic_enc_close\n");
#if MIC_USE_MIC_CHANNEL
audio_adc_mic_close(&mic_enc->mic_ch);
audio_adc_del_output_handler(&adc_hdl, &mic_enc->adc_output);
#endif
mic_enc_resume();
audio_encoder_close(&mic_enc->encoder);
audio_encoder_task_close();
/* if (encode_task) { */
/* audio_encoder_task_del(encode_task); */
/* free(encode_task); */
/* encode_task = NULL; */
/* } */
free(mic_enc);
mic_enc = NULL;
printf("audio_mic_enc_close end\n");
return 0;
}
#endif