#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