基于UNIMRCP1.5.0的代码走读 与 填坑记录
1. server启动配置加载
入口:unimrcp_server.c
static apt_bool_t unimrcp_server_load(mrcp_server_t *mrcp_server, apt_dir_layout_t *dir_layout, apr_pool_t *pool);
通过root下的几个主要字节点分别进行处理,对应处理函数如下:
unimrcp_server_properties_load : properties加载
unimrcp_server_components_load :componets加载,包括各个功能的plugin
unimrcp_server_settings_load :
unimrcp_server_profiles_load :
unimrcp_server_misc_load :
2.消息处理链路
系统启动时会为每个plugin启动一个任务处理线程,循环函数在: apt_consumer_task.c:apt_consumer_task_run()
具体消息处理在 : apt_task.c : apt_task_msg_process() ——》apt_task_vtable_t.process_msg() ——》会调用到每个plugin定时时注册的函数
MRCP消息解析 : apt_text_message.c:apt_message_parser_run()
ASR与TTS实现
UNIMRCP是MRCP协议的封装,并没有真实实现ASR或TTS的能力。基于UNIMRCP提供ASR或TTS服务,用户需要自己实现能提供真实ASR和TTS能力的plugin。UNIMRCP提供了ASR和TTS的plugin的demo示例,基于demo开发更加方便快捷。
3. ASR实现
UNIMRCP的ASR实现demo在文件plugins路径下demorecog模块,demo_recog_engine.c文件中。
a.SIP交互: SIP交互用于协商ASR过程中双方进行MRCP消息交互和媒体交互使用的端口和媒体格式等信息。 这一块一般无需改动,如果存在格式限制,可在配置文件 conf/unimrcpserver.xml 中配置 settings -> rtp-settings -> codecs ,如:
<codecs own-preference="false">PCMU PCMA L16/96/8000 PCMU/97/16000 PCMA/98/16000 L16/99/16000</codecs>
b.MRCP消息交互: MRCP服务器收到RECOGNIZE消息以接受语音识别请求,进入ASR流程。demo_recog_channel_recognize 方法封装了RECOGNIZE消息的处理。进入这个函数,表示收到一个语音识别请求,此请求处理成功后,会进入语音回调流程。
c.rtp交互: rtp交互也即媒体的交互。进入语音回调流程后,rtp交互也随之开始。UNIMRCP的demo中语音回调入口是:
static apt_bool_t demo_recog_stream_write(mpf_audio_stream_t *stream, const mpf_frame_t *frame)
demo中的主要处理流程是
(1)检查语音有效性,进行状态转换。调用 mpf_activity_detector.c 中如下方法:
MPF_DECLARE(mpf_detector_event_e) mpf_activity_detector_process(mpf_activity_detector_t *detector, const mpf_frame_t *frame)
(2)状态转换成功后返回发送ASR识别响应。调用如下方法(demo中返回固定识别结果)
static apt_bool_t demo_recog_recognition_complete(demo_recog_channel_t *recog_channel, mrcp_recog_completion_cause_e cause)
业务基于UNIMRCP进行ASR开发时,在demo基础上,至少需做两点
(1) 在 demo_recog_stream_write 回调中取出音频,提供给识别服务进行识别。注意这里的回调是基于帧的概念回调的。(一次回调拿到的数据是10ms的数据)
(2) 再 demo_recog_recognition_complete 调用时,将识别结果的值设置为真实的ASR识别服务的识别结果。
4.TTS实现
UNIMRCP的ASR实现demo在文件plugins路径下 demosynth 模块,demo_synth_engine.c 文件中。
a.SIP交互: SIP交互用于协商ASR过程中双方进行MRCP消息交互和媒体交互使用的端口和媒体格式等信息。 这一块一般无需改动,如果存在格式限制,可在配置文件 conf/unimrcpserver.xml 中配置 settings -> rtp-settings -> codecs ,如:
<codecs own-preference="false">PCMU PCMA L16/96/8000 PCMU/97/16000 PCMA/98/16000 L16/99/16000</codecs>
b.MRCP消息交互: MRCP服务器收到SPEAK消息以接受语音合成请求,进入TTS流程。
static apt_bool_t demo_synth_channel_speak(mrcp_engine_channel_t *channel, mrcp_message_t *request, mrcp_message_t *response)
方法封装了SPEAK消息的处理。进入这个函数,表示收到一个语音识别请求,此请求处理成功后,会进入语音回调流程。
c.rtp交互: rtp交互也即媒体的交互。进入语音回调流程后,rtp交互也随之开始。UNIMRCP的demo中语音回调入口是:
static apt_bool_t demo_synth_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *frame)
demo中的主要处理流程是
(1)从固定音频中读取一帧内容,并填充到 frame 中,由系统将这一帧数据转换为RTP消息发送出去。
(2)音频读取完后发送完成消息,以结束TTS语音流程
/* send asynch event */
mrcp_engine_channel_message_send(synth_channel->channel,message);
业务基于UNIMRCP进行TTS开发时,在demo基础上,至少需做两点
(1) 在 demo_synth_channel_speak 回调中读取出要合成语音的文本内容,提交给TTS服务进行合成。
(2) 在 demo_synth_stream_read 回调中,将合成得到的语音按帧顺序填充到buffer中。由于MRCP是实时协议,因此TTS服务也要求能实时合成,一般从收到请求到第一个字合成音出来会有一定延时,这时可以先填充空白音。