#ifdef SUPPORT_MS_EXTENSIONS #pragma bss_seg(".ai_voice_recoder.data.bss") #pragma data_seg(".ai_voice_recoder.data") #pragma const_seg(".ai_voice_recoder.text.const") #pragma code_seg(".ai_voice_recoder.text") #endif #include "jlstream.h" #include "system/includes.h" #include "ai_voice_recoder.h" #include "encoder_node.h" #include "asm/dac.h" #include "audio_cvp.h" #if TCFG_AI_VOICE_ENABLE struct ai_voice_recoder { struct jlstream *stream; }; extern struct audio_dac_hdl dac_hdl; static struct ai_voice_recoder *g_ai_voice_recoder = NULL; static void ai_voice_recoder_callback(void *private_data, int event) { struct ai_voice_recoder *recoder = g_ai_voice_recoder; struct jlstream *stream = (struct jlstream *)private_data; switch (event) { case STREAM_EVENT_START: break; } } void ai_voice_recoder_set_ai_tx_node_func(int (*func)(u8 *, u32)) { struct ai_voice_recoder *recoder = g_ai_voice_recoder; if (recoder && recoder->stream) { jlstream_node_ioctl(recoder->stream, NODE_UUID_AI_TX, NODE_IOC_SET_PRIV_FMT, (int)func); } } int ai_voice_recoder_open(u32 code_type, u8 ai_type) { int err; struct stream_fmt fmt; struct encoder_fmt enc_fmt; struct ai_voice_recoder *recoder; u16 source_uuid = 0; if (g_ai_voice_recoder) { return -EBUSY; } u16 uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"ai_voice"); if (uuid == 0) { return -EFAULT; } recoder = malloc(sizeof(*recoder)); if (!recoder) { return -ENOMEM; } recoder->stream = jlstream_pipeline_parse(uuid, NODE_UUID_ADC); if (!recoder->stream) { err = -ENOMEM; goto __exit0; } switch (code_type) { case AUDIO_CODING_OPUS: // bitrate // 16000,32000,64000 这三个码率分别对应非ogg解码库 // 的 OPUS_SRINDEX 值为0,1,2 // format // 0:百度_无头. // 1:酷狗_eng+range. // 2:ogg封装,pc软件可播放. // 3:size+rangeFinal. 源码可兼容版本. // complexity // 0|1|2|3 3质量最好.速度要求最高. // frame_ms (由frame_dms / 10得出) // 20|40|60|80|100 ms. // sample_rate // sample_rate=16k ignore // // 注意 // 1. struct encoder_fmt是配置编码器私有参数 // 有效的参数: // complexity, format, frame_dms // 不起效的参数: // bit_rate, sample_rate, ch_num, bit_width // 不起效参数只用作阅读,需要修改请到音频流程图的”编码器“节点修改 enc_fmt.bit_rate = 16000; enc_fmt.complexity = 0; enc_fmt.sample_rate = 16000; /* enc_fmt.format = (ai_type >> 6); //传入的ai_type实参是bit7:6,用于选择封装格式,兼容以前调用的接口 */ enc_fmt.format = (ai_type); //传入的ai_type实参是bit7:6,用于选择封装格式,兼容以前调用的接口 printf("[msg]%s-%d>>>>>>>>>>>enc_fmt.format=%d", __FUNCTION__, __LINE__, enc_fmt.format); enc_fmt.frame_dms = 20 * 10;//与工具保持一致,要乘以10,表示20ms fmt.coding_type = AUDIO_CODING_OPUS; fmt.sample_rate = 16000; fmt.bit_rate = 16000; fmt.channel_mode = AUDIO_CH_MIX; break; case AUDIO_CODING_SPEEX: enc_fmt.quality = 5; enc_fmt.complexity = 2; enc_fmt.sample_rate = 16000; fmt.sample_rate = 16000; fmt.coding_type = AUDIO_CODING_SPEEX; break; case AUDIO_CODING_PCM: fmt.sample_rate = 16000; fmt.coding_type = AUDIO_CODING_PCM; break; default: printf("do not support this type !!!\n"); err = -ENOMEM; goto __exit1; break; } printf("coding_type %x", code_type); err = jlstream_node_ioctl(recoder->stream, NODE_UUID_ENCODER, NODE_IOC_SET_PRIV_FMT, (int)(&enc_fmt)); err += jlstream_node_ioctl(recoder->stream, NODE_UUID_AI_TX, NODE_IOC_SET_FMT, (int)(&fmt)); //设置ADC的中断点数 if (code_type == AUDIO_CODING_PCM) { err += jlstream_node_ioctl(recoder->stream, NODE_UUID_SOURCE, NODE_IOC_SET_PRIV_FMT, 80); } else { err += jlstream_node_ioctl(recoder->stream, NODE_UUID_SOURCE, NODE_IOC_SET_PRIV_FMT, 320); } if (err) { goto __exit1; } u16 node_uuid = get_cvp_node_uuid(); u32 ref_sr = audio_dac_get_sample_rate(&dac_hdl); if (node_uuid) { #if !(TCFG_AUDIO_CVP_OUTPUT_WAY_IIS_ENABLE && (defined TCFG_IIS_NODE_ENABLE)) #if (TCFG_ESCO_DL_CVSD_SR_USE_16K > 1) jlstream_node_ioctl(recoder->stream, node_uuid, NODE_IOC_SET_FMT, (int)ref_sr); #endif #endif err = jlstream_node_ioctl(recoder->stream, node_uuid, NODE_IOC_SET_PRIV_FMT, source_uuid); if (err && (err != -ENOENT)) { //兼容没有cvp节点的情况 goto __exit1; } jlstream_node_ioctl(recoder->stream, NODE_UUID_SOURCE, NODE_IOC_SET_PRIV_FMT, 256); } jlstream_set_callback(recoder->stream, recoder->stream, ai_voice_recoder_callback); jlstream_set_scene(recoder->stream, STREAM_SCENE_AI_VOICE); err = jlstream_start(recoder->stream); if (err) { goto __exit1; } printf("ai voice recoder open succ\n"); g_ai_voice_recoder = recoder; return 0; __exit1: jlstream_release(recoder->stream); __exit0: free(recoder); return err; } void ai_voice_recoder_close() { struct ai_voice_recoder *recoder = g_ai_voice_recoder; if (!recoder) { return; } jlstream_stop(recoder->stream, 0); jlstream_release(recoder->stream); free(recoder); g_ai_voice_recoder = NULL; jlstream_event_notify(STREAM_EVENT_CLOSE_RECODER, (int)"ai_voice"); } static u8 ai_voice_record_idle_query(void) { return g_ai_voice_recoder ? 0 : 1; } REGISTER_LP_TARGET(ai_voice_record_lp_target) = { .name = "ai_voice", .is_idle = ai_voice_record_idle_query, }; #endif