基於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服務也要求能實時合成,一般從收到請求到第一個字合成音出來會有一定延時,這時可以先填充空白音。