基於VoiceXML技術的可視化IVR系統設計和實現(三)
上海易谷網絡科技有限公司 查瑋 2009/12/29
基於VoiceXML技術的可視化IVR系統設計和實現(一)
基於VoiceXML技術的可視化IVR系統設計和實現(二)
在系統分析和系統總體設計之後,就進入了系統實現階段。該階段主要是對IVR系統業務編輯工具和執行引擎部分進行實現。
4.1可視化流程定義工具實現Windows作業系統具有友好的圖形界面,越來越被國內外眾多的用戶所喜歡[30],因而開發Windows應用程式將具有廣泛的市場。可用於開發Windows應用程式的語言較多,其中Visual C++是眾多軟體開發人員所喜歡的語言之一,它是一種可視化的面向對象程序語言,其MFC基類封裝了Windows API函數,提供了許多功能模塊,使得開發人員可以利用MFC快速、高效地開發Windows應用程式,減少了許多重複勞動,提高了代碼利用率和程序開發效率,縮短了軟體開發周期,使開發人員有更多的時間去研究新的問題。
完成了基礎類的設計之後,整個IVR系統的流程工具都是基於這個基礎類包來完成的。作為流程編輯工具,流程編輯器的設計應當遵循如下原則:方便簡便,便於開發人員掌握,適合與不同的業務不同行業IVR系統的工作流程。所以在設計中,以樹形結構反映工作流程的概念,如圖4.1所示。
從圖4.4所示結構中,通過主窗體可以訪問其它窗體操作,同時控制窗體與類模塊的信息交互。系統中的各個窗口的實現均是基於基礎類包的。下面詳細介紹IVR系統流程工具各個部分的實現。其實現工具的內容詳見文獻[31]。
主程序是IVR系統流程定義工具的主體,它包括各個窗口的定義、流程類的定義、節點類定義等。主程序通過主窗體類定義將其它各個類窗體組織在一起,同時負責各子窗體之間的信息交互。主窗體類則定義了流程間的組織結構,它通過用戶界面操作協助用戶完成流程製作,同時生成含有VoiceXML標籤的Web頁面交給執行引擎進行解釋執行。
主窗體主要負責各個窗體和類模塊之間的信息交互和訪問控制。圖4.2描述IVR系統業務流程定義工具的主窗體界面。分為工具箱窗體、菜單窗體、流程編輯(畫布)窗體、屬性窗體,同時包括流程節點的訪問控制。
圖4.2 IVR系統流程定義工具主窗體
工具箱窗體:工具箱窗體提供系統支持節點類型控制項的選擇,用戶通過拖拽方式添加節點以製作流程。工具箱窗體類主要包括工具箱窗體的事件響應和主窗體交互部分,提供每種實現方法。
菜單窗體:菜單窗體是提供關於整個系統流程的打開、編輯等操作。
屬性設置窗體:屬性窗體為每一類節點提供屬性設置功能,其中包括屬性窗體操作、與主窗體信息交互兩大類,提供各個節點所涉及到的每種屬性窗體的實現方法。
流程編輯(畫布)窗體:此窗體類提供了製作流程的畫布操作。在此窗口定義了一個畫布控制項;流程編輯窗體接收畫布對象的事件,提交給主窗體,同時通過與主窗體的信息交互控制在畫布上確保正確製作流程。
主程序除了上述4種主要的模塊定義之外,還有一些窗體類和類模塊定義,主要負責各種屬性的設置和操作:同時為使流程製作更加人性化,主程序增加了一些通用編輯功能。
以上為主程序的設計及其部分實現。在實現中通過引用窗體控制項和畫布窗體類定義,集成了對畫布控制項和節點控制項的訪問操作。
4.2 IVR系統執行引擎的實現
IVR系統執行引擎是整個IVR系統的核心系統,它負責對之前由IVR系統流程定義工具生成的中間文件(含有VoiceXML標籤的Web頁面)解釋和驅動。本文設計的IVR系統是基於VoiceXML技術,以開源OpenVXI項目為基礎,設計並實現的IVR系統執行引擎部分。
OpenVXI[32] 是一種簡便的開源庫,用來解釋VoiceXML對話標記語言(dialog markup language)。為了避免其它私有的標準,它嚴格支持VoiceXML 2.0 草案(現在已經支持部分3.0的標準),同時OpenVXI是一個跨平臺的開發系統。
OpenVXI本身只是VoiceXML平臺的一個組件[32],它只是提供了簡單的語音識別、語音提示和TTS(text-to-speech)功能。而對於電話功能,由於語音卡的種類繁多,同時VoIP(Voice over IP)技術的快速發展,就需要使用者自己提供實際的組件和函數進行整合。既便如此,OpenVXI還是提供一個強大的基本框架讓使用者構建自己的語音平臺。
4.4.1 OpenVXI的系統架構
根據圖2.3描述的VoiceXML平臺的基本體系結構分析,OpenVXI符合基本架構,具體的系統架構圖如圖4.3所示。整個平臺執行VoiceXML頁面,並提供與電話網絡連接的服務,平臺總共分4個部分:
1.主進程、操作管理和維護系統:一個收集系統管理和錯誤報告的工具。這個核心組件通過創建線程的方式來喚醒VoiceXML瀏覽器。
2.OpenVXI:負責解釋VoiceXML標記語言和語音平臺返回的呼叫標誌信息(通過返回相應的事件信息)。
3.OpenSpeech Browser PIK:提供了為系統運行所必要的高層次(high-level)服務,包括識別引擎、語音引導引擎、Internet fetch庫(提供通過URL對web伺服器訪問的庫)、ECMA Script[32]引擎。OpenVXI通過系統提供的函數接口來訪問這些組件,這些接口不需要定義和實現各種機制來滿足與底層電話系統軟體系統之間的通訊,而是通過使用支持Client/Server模式的TCP/IP協議來實現。
4.Telephony and base services:需要能接收到電話的基本作業系統服務和電話服務。
圖4.3 OpenVXI系統架構圖
4.4.2 OpenSpeech Browser PIK組件結構
圖4.4描述了OpenSpeech Browser PIK 的架構和組件構成,包括為完成語音識別和TTS功能整合的產品SpeechWorks。 所有的組件都被設計成很容易的去訪問。這個語音瀏覽器(Speech Browser)包括:
1.VXI:解析所有的VoiceXML標記,並且擔當程序中的主控作用。VXI實現了VoiceXML 1.0中所有必需(mandatory)的部分和大部分的可選功能。
2.XML Parser Interface:提供對XML DOM解析器的訪問,現在的實現方式是通過直接調用開源的Apache Xerces SAX and DOM parse解析接口。
3.Internet Interface:通過http://和file://的方式訪問應用文檔(即URL的方式訪問Web頁面),同時也支持POST的方式給應用伺服器返回數據。這方面的實現是整合了開源W3C Libwww開發庫。
4.ECMAScript(JavaScript) Interface :提供了對ECMAScript執行服務的訪問。相關的實現整合了Mozilla SpiderMonkey開源引擎。
5.Logging Interface:用來報告系統級別的錯誤、事件和診斷信息。它是將日誌存儲成日誌文件,並且可以選擇進行標準的輸出。
核心瀏覽器中與語音平臺相關的API主要包括:
1.Recognizer Interface:提供語法管理和由VoiceXML指定的識別服務(例如:收取DTMF碼),包括動態語法創建和語法構建。它通過Telephony Service來獲取呼叫信息,並且已經在OpenSpeech Browser中整合。
2.Prompting Interface:提供完整的放音服務,包括播放可變語音。它必須處理語音文件並且提供語音服務。OpenSpeech Browser PIK已經整合了支持幾種語言的TTS。
3.Telephony Interface:提供呼叫控制服務,包括發送語音平臺的時間、轉接和掛斷電話。OpenSpeech Browser PIK已經實現了與底層的語音平臺交互,並抽象了API來提供呼叫控制服務。
4.Object Interface:提供了對對象的訪問。通過對象元素,平臺可以訪問定義的那些對VoiceXML語音的擴展。對象可以很容易的被定義成適合語音平臺需要的呼叫控制擴展、CTI系統的彈屏顯示或者其它一些需求。
圖4.4 OpenSpeech Browser PIK 組件構成圖
通過對OpenVXI的描述,可以看出:模塊化和分層次的設計使得在平臺裡的各個組件之間即相對獨立,又相互聯繫、互相協作來完成整個平臺的功能。使用者可以通過實現平臺提供的各種接口來實現對基於各種硬體或者軟體的語音系統的整合。本文設計的IVR系統所涉及到的是模擬語音卡,所以對與錄音、放音、取鍵都由語音卡所提供的API來完成即可。
4.4.3 接口實現(取鍵、錄音、放音、轉接)
OpenSpeech Browser PIK自身就是支持標準的VoiceXML 2.0的標準,同時對VoiceXML的解析能力比較強大,又同時整合了Apache的XML解析器、W3C的LIBWWW進行Web訪問和Mozilla Spider Monkey作為ECMA Script的執行器,本文主要是通過實現相應的語音平臺接口來實現IVR系統的執行引擎。沒有對VoiceXML解析功能做過多的修改。
Recognizer Interface(識別接口)的實現
對應Recognizer的接口,OpenVXI分別針對收取用戶按鍵(DTMF碼)和語音識別(speech recognize)的接口,但是由於現在語音識別的技術並不是很成熟,特別是對中文的識別率不是很高,本文設計的IVR系統就沒有涉及到該功能,只是留下接口等待以後實現。需要實現的具體接口函數有收取用戶按鍵和錄音。
收鍵接口,函數體描述如下:
VXIpromptResult Recognize (struct VXIrecInterface* pThis,
const VXIMap* properties,
VXIrecRecognitionResult** recogResult)
圖4.5描述了實現該接口的流程圖。
圖4.5 使用Recognize接口實現收DTMF碼流程圖
1)獲取連接實例,其數據是從語音卡檢測到的信令,發送給語音平臺。通過GetImplementaionName來獲得實例名稱,進入下一步;
2)使用BeginSession來創建session,並且通過LoadGrammarURI來裝載語法。這時候開始啟動收鍵,進入下一步;
3)啟動計時器,等待事件觸發;
4)如果接收到SC_EVENT_DISCCONET事件,表示用戶主動放棄,返回REC_FAILURE,調用EndSession,流程結束;如果接收到SC_EVENT_TIMEOUT事件,表示用戶在計時器的時間內沒有輸入,返回REC_NOINPUT,調用EndSession,流程結束;如果接收到SC_EVENT_DTMF_RECEIVED事件,表示用戶輸入完畢,進入下一步;
5)檢查語法的符合性,通過檢查是否滿足在.gram文件裡設置的正則表達式來判斷,如果符合轉6,不符合轉7;
6)符合語法,返回REC_SUCESS,調用EndSession,流程結束;
7)不符合語法,返回REC_NOMATCH,調用EndSession,流程結束。
錄音接口,接口函數體描述如下:
VXIrecResult Record (struct VXIrecInterface* pThis,
const VXIMap* propertites,
VXIrecRecordResult** recordResult)
圖4.6描述了實現該接口的流程圖。
圖4.6使用Record接口實現錄音流程圖
1)獲取連接實例,其數據是從語音卡檢測到的信令,發送給語音平臺。通過GetImplementaionName來獲得實例名稱,進入下一步;
2)創建錄音文件名,進入下一步;
3) 使用BeginSession來創建session,並且通過LoadGrammarURI來裝載語法。這時候開始啟動錄音功能,進入下一步;
4)啟動計時器,等待事件觸發;
5)如果接收到SC_EVENT_DISCCONET事件,表示用戶主動放棄,轉到步驟7;如果接收到SC_EVENT_TIMEOUT事件,表示用戶在計時器的時間內沒有輸入,返回REC_NOINPUT,調用EndSession,流程結束;如果接收到SC_EVENT_RECORD_RECEIVED事件,表示用戶錄音完畢,進入下一步;
6)返回REC_SUCCESS,進入下一步;
7)檢查錄音文件是否有數據。如果錄音文件沒有數據不存在數據,表示錄音不成功,返回REC_FAILURE,調用EndSession,流程結束;如果錄音文件有數據,表示錄音成功,返回成功,調用EndSession,流程結束。
Prompting Interface(放音接口)的實現
對於放音接口,所需要關注的是3個函數的實現:Queue()接口、Play()接口和Wait()接口。
Queue接口僅僅是將所要播放或者重複播放的語音文件放入隊列中,並不擔當放音的功能, Play()接口才是啟動播放動作的。這個調用會一直阻塞直到放音數據返回以便於調用者可以確認是否需要重播。接口函數體描述如下:
VXIpromptResult Queue (struct VXIproptInterface* pThis,
const VXIchar* type,
const VXIchar* content,
const VXIchar* text,
const VXIMap* properties)
在實現過程中,本文設計的IVR系統只是涉及到語音文件的播放,所以只是需要通過調用語音卡API將語音文件放入播放隊列即可,而需要重複播放的語音文件,只要重複放入到語音隊列當中便可實現。
Play接口是完成放音動作的接口。實現非常簡單,只需要調用語音卡放音API去播放存在播放隊列裡的語音文件。接口函數體描述如下:
VXIpromptResult Queue (struct VXIproptInterface* pThis)
Wait接口是等待所有的放音文件都結束,去捕獲放音時間結束。接口函數體描述如下:
VXIpromptResult Wait (struct VXIproptInterface* pThis
VXIpromptResult* playResutl)
圖4.7描述了這三個接口實現流程圖。
圖4.7 Queue、Play、Wait接口實現流程圖
Queue接口實現如下:
1)獲取連接實例,其數據是從語音卡檢測到的信令,發送給語音平臺,進入下一步;
2)判斷語音文件是否合法,如果合法轉3,不合法返回PROMPT_FAILURE,流程結束;
3)將要播放的文件名放入播放隊列中等待播放,返回PROMPT_SUCCESS,流程結束。
Play接口實現如下:
1)獲取連接實例,其數據是從語音卡檢測到的信令,發送給語音平臺,進入下一步;
2)判斷播放隊列是否為空,如果為空返回PROMPT_SUCCESS,流程結束;如果不為空,轉3;
3)調用語音卡放音API實現放音功能,轉2。
Wait接口實現如下:
1)獲取連接實例,其數據是從語音卡檢測到的信令,發送給語音平臺,進入下一步;
2)啟動計時器,等待事件觸發;
3)如果收到SC_EVENT_DISCONNECT事件,表示話路斷開,返回PROMPT_FAILURE,流程結束;如果收到SC_EVENT_PROMPT_END,返回PROMPT_SUCCESS,流程結束。
Telephony Interface(轉接接口)的實現
對於電話接口,需要實現的方法有GetStatus、Disconnect、TransferBlind,而TransferBridge指的是通過橋接的方式去轉接。首先,他需要平臺的支持,其次還要進行大量的配置,同時佔有很多的資源,非常的不實用。對於IVR系統來說,不需要這麼複雜的操作。對於大型的呼叫中心,IVR系統只是前置於整個呼叫平臺,更多的話路操作還需要交給CTI系統去完成。
下面給出每個接口實現的流程圖,如圖4.8所示。
圖4.8 GetStatus、Disconnect、TransferBlind接口流程圖
GetStatus函數體描述如下:
VXItelResult GetStatus(struct VXItelInterface* pThis,
VXItelStatus* status)
接口實現如下:
1)獲取連接實例,其數據是從語音卡檢測到的信令,發送給語音平臺,進入下一步;
2)調用語音卡API去查看通道狀態,進入下一步;
3)將獲得狀態返回,如果通道中有電話返回VXI_STATUS_ACTIVE;如果通道是空閒狀態則返回VXI_STATUS_INACTIVE流程結束。
Disconnect函數體描述如下
VXItelResult Disconnect(struct VXItelInterface* pThis)
接口實現如下:
1)獲取連接實例,其數據是從語音卡檢測到的信令,發送給語音平臺,進入下一步;
2)調用語音卡API去檢查語音連接是否存在,如果存在,則進入下一步;如果不存在,轉4;
3)調用語音卡API去掛斷電話,進入下一步;
4) 調用語音卡API釋放所有資源,流程結束。
TransferBlind函數體描述如下
VXItelResult TransferBlind (struct VXItelInterface* pThis,
const VXIMap* properties,
const VXIChar* transferDestination,
VXIMap** resp)
接口實現如下:
1)獲取連接實例,其數據是從語音卡檢測到的信令,發送給語音平臺,進入下一步;
2)調用語音卡API去檢查語音連接是否存在,如果存在,則進入下一步;如果不存在,轉4;
3)調用語音卡API去轉接電話(因為是採用的是「盲轉」方式轉接,IVR系統只要將電話轉移到話機上即可,不需要管理轉接後的狀態),返回成功,流程結束;
4)返回失敗,流程結束。
4.3本章小結
本章在基於整個IVR系統的詳細設計基礎上,基於MFC技術和OpenVXI的開源項目,實現了IVR系統可視化的過程定義工具和IVR系統的執行引擎。
基於VoiceXML技術可視化IVR設計和實現(四)
作者獨家提供CTI論壇稿件,其它媒體謝絕轉載
CTI論壇報導
相關閱讀: