【轉】SAPI中的IspeechRecoContext(介面)

於為源發表於2013-11-22

IspeechRecoContext自動化介面定義一個識別上下文。

什麼是一個識別上下文?

一個識別上下文就是應用程式和SAPI共同作用來實現語音識別的最主要方法。它就是用來允許應用程式來開始、停止識別,接收識別結果、其他事件的一個物件。它也能控制哪些單詞或者短語可以被提供給使用者來發音。一個應用程式可能有很多的識別上下文在同一時間同時開放,每一個控制應用程式的不同部分。一個特殊的識別上下文控制可被使用的單詞的集合,並且被關聯給應用程式的特殊部分。在一般情況下,這樣的單詞的集合就是限制哪些語音識別嘗試被限定,並且被輪詢去符合單詞。不被保留在集合或者上下文中的單詞,將不會被用於語音識別的嘗試。通過設定識別上下文,應用程式限制或擴充套件單詞的範圍,這些單詞是滿足應用程式特殊方向使用的需要。這種語音識別的精細度通過刪除當時不需要的單詞,來提高語音識別的質量。相應地,這種精細度也允許應用程式來增加必要的單詞。

例如:一個應用程式可能只有一個識別上下文,所有的單詞都在詞典中,所有的單詞在所有的時候都可用。如果這個應用程式只是單純的聽寫,唯一上下文模式也可以被很好地使用,使用者可以在任意時間說任何單詞給應用程式,並且可能被成功使用。然而,如果應用程式有一個退出的新要求的時候,當使用者說“Close”,唯一上下文模式將會關閉。假設在聽寫期間,單詞“Close”被說出時,應用程式突然停止執行並且關閉,使用者將會很失望。

很明顯,這裡的單詞“Close”有兩種用法(上下文),第一種是語音的一部分(如"please close the door," "that was too close for comfort," "we'll close in on the criminal"),第二種上下文是一種專有的命令。這裡必須有一種方法去區別兩者的不同。一個識別上下文允許應用程式去做這樣的區分。

應用程式可以有多於一個的識別上下文。實際上,它可以有儘可能多的有意義的上下文。例如,一個識別上下文可以被關聯給選單欄,另一個可以關聯給聽寫螢幕,還有另一個關聯給對話方塊,甚至只是Yes/No/Cancel這樣的臨時對話方塊。程式設計師需要去決定識別上下文的範圍,一個應用程式的選單系統可能有多個識別上下文,可能每一個選單項對應一個上下文。這種精細度授予應用程式魯棒地集中資源。例如,一個小選單可能只有12與之相關的專案,不僅如此,它還有12個非常特殊的單詞。因此,不必要去使用整個聽寫集合(大約有65000到1000000個詞彙),實際上只有12個單詞被用到。一個多於需要的詞彙庫不僅佔有更多的程式時間,而且導致更多的搭錯的單詞。同樣的原因,在上面“Close”例子中,一個聽寫模式將不能把“Close”與其他單詞區分。兩個識別上下文可以用來去區分這種不同。

如何使用識別上下文?

產生一個識別上下文,需要使用兩個步驟處理法。一個識別上下文必須先被宣告,然後才能產生。

識別上下文的型別:

識別上下文有兩種型別:共享的或者獨佔的(Inproc)。一個共享的上下文允許資源可以被其他的識別上下文或者應用程式使用。在一臺機器上使用共享上下文的所有應用程式共同使用一個音訊輸入、語音識別(SR)引擎、語法。當使用者發音時,SR引擎將會識別,SAPI根據哪個語法的結果最符合要求,決定傳送哪個上下文給識別結果。在一般情況下,大多數應用程式使用共享上下文。

獨佔上下文限制可用的資源給一個上下文或者應用程式,這就是一個SR引擎或者麥克風被一個獨佔識別上下文使用。將不會被其他的應用程式使用。在使用獨佔上下文狀況下,要求最高的效能標準、響應時間或者嚴格的識別質量。獨佔上下文對於其他硬體平臺的嵌入系統是非常重要的,同樣也被使用在無麥克風識別(如從檔案中識別)。然而,獨佔上下文也應該被謹慎地使用,原因就是它排除其他應用程式使用語音識別資源。

預設值:

識別上下文按照計算機系統的預設狀態產生自己的預設值。這些預設值可以在控制皮膚中的語音屬性中進行設定。儘管應用程式可能因為特殊的原因而重寫這些預設值,但是應用程式不應該直接設定或者修改這些預設值。

這些預設值包括:

Recognizer:確定語音識別(SR)引擎;

EventInterests:確定語音識別(SR)引擎產生哪個事件;

RetainedAudio:為語音堅持實際的音訊;

RetainedAudioFormat:確定要保留的音訊格式;

Voice:對文字進行發音;

語法:

唯一被明確產生的資源是語法使用CreateGrammar。語法定義了一系列的單詞為識別上下文。語法也可以是兩種型別:聽寫式和命令控制式(C&C)。聽寫式語法通常不限制單詞列表,目的是包括語言中儘可能多的單詞。聽寫式模式允許使用者說任一單詞或者短語,並且被用在傳統的偵測,來聽寫一封信或報紙。例如,下面的程式碼片段宣告瞭一個聽寫語法。

Set myGrammar = RC.CreateGrammar

myGrammar.DictationSetState SGDSActive

一個命令控制語法是一個有限的單詞列表(限制發音人在一個小集合中)。在這種方式下,使用者可以說一個命令,通常是一個單一的單詞,有更多的機會來被失敗。小集合單詞不接受不在特殊列表中的單詞,一個語法對能響應語音選單很有用的。選單語法可以很小,擁有精確的單詞或短語命令,如"New," "Exit," or "Open."等等,下面一段程式碼片段宣告瞭一個命令和控制語法。

Set myGrammar = RC.CreateGrammar

myGrammar.CmdLoadFromFile "sol.xml", SLODynamic

myGrammar.CmdSetRuleIdState 101, SGDSActive

由於單詞列表的內容是有限的,一個顯式的列表將會被使用。在這個例子裡,命令檔案sol.xml被使用。另外,上面的程式碼中啟用了一條規則,這個規則有一個Id值為101。

狀態:

儘管個體語法規則可能隨著條件的改變而處於啟用或者非啟用狀態。在識別上下文中所有的語法規則都隨著State屬性的改變,而變成啟用或者非啟用狀態。例如,一個窗體不在當前的焦點是,語法可能被關閉。當這個窗體重新得到焦點是,語法將會恢復。另外,識別上下文可以被暫時停止,並且可以被重新啟動。使用Pause方法可以暫時停止識別,以便和語法保持同步。在暫停之後,可以使用Resume方法來恢復識別過程。在暫停的時候,引擎將會繼續接受聲音輸入和語言加工。提供一個暫停對於系統並不過分,在預設的情況下,一次暫停的時間不應該超過30秒。

ISpeechRecoContext物件總是關聯一個單一的語音識別引擎(也被稱為識別器)。然而,一個單一的識別器可能有很多的識別上下文。

事件

作為一個與識別上下文相關的結果,語音識別(SR)引擎返回資訊給使用事件機理的應用程式。一個事件是使用者或者應用程式感興趣的特殊發生。事件的例子包括通知應用程式一個成功的識別或者指出音訊流達到的指定位置。不管怎樣,應用程式與加工程式或者忽略程式是無關的。

另外,事件可能被過濾,允許引擎去返回一些或者所有事件。或者避免對於應用程式無關的事件在第一位產生。過濾是使用EventInterests控制的。

ISpeechRecoContext自動化介面包括以下元素:

屬性有:

AllowVoiceFormatMathingOnNextSet屬性:確定識別上下文是否可以改變輸出聲音的音訊格式去適應輸入音訊流的音訊格式。

AllowVoiceFormatMathingOnNextSet只有在一個聲音通過識別上下文產生時才會被使用。如果這個屬性被設定為True,聲音的輸出格式將會被設定成和關聯與語音識別(SR)引擎的音訊輸入格式一樣的格式。這種轉化只有在下一次設定SpVoice.Voice時才會發生。如果這個音訊物件已經被繫結給一個有特殊格式的音訊流,即使在被設定為True的情況下,聲音格式將不會隨著語音識別(SR)引擎的輸入格式而進行改變。如果是False,這種改變將不會進行。

使用相同的聲音格式給輸入、輸出資源對於不支援全雙工音訊(例如:輸入格式必須適應輸出格式)的音效卡是有用的。如果輸入格式低於輸出格式質量,輸出格式質量將會降低到輸入的質量的水平。

AllowVoiceFormatMathingOnNextSet在預設情況下被設定為True。

AudioInputInterferenceStatus屬性:返回關於識別上下文的音訊輸入的干擾的資訊。這個資訊通常被IspeechRecoContext的Interference時間返回。

CmdMaxAlternates屬性:指定為命令和控制語法生成的替換的最大數量。

在預設狀態下,最大的替換數量為0,所以一個應用程式必須在試圖接收或者依靠為命令和控制的替換前呼叫這個方法。不是所有的不是所有的語音識別(SR)引擎都支援命令和控制語法或者專有語法的替換。如果特殊的引擎不支援替換,這個方法將會表示已經成功替換,但是替換的數量將返回0值。

EventInterests屬性:指定被SpeechRecoContext物件接收的事件的型別。

一個感興趣事件就是給每一個識別上下文加上過濾機制。通過設定EventInterests,識別上下文允許或者拒絕語音識別(SR)引擎事件到達應用程式。所有、無一、被選擇型別的事件都可以被過濾。在預設狀態下,語音識別(SR)引擎除了SREAudioLevel事件外,允許所有的事件。

注意:

為EventInterests設定事件常量的定義位於SpeechRecoEvents列表中,每一個事件型別通過它本身的值來表現。傳遞給EventInterests的值就是應用程式要求的每一個事件的總和。例如:SRESoundStart+SRERecognition將會作為一個值被傳遞,可供選擇的兩種事件將會被像一個單一的值18一樣被傳遞。SRESoundStart(值為2)加上SRERecognition(值為16)。相反地,如果應用程式取回當前的事件設定,值為1064,它表示有三個事件是啟用狀態,SREPhraseStart(值為8),SREHypothesis(值為32),SREInterference(值為1024)加起來就是1064.

Recognizer屬性:表示和識別上下文關聯的識別器。

注意:

儘管在通常情況下,定義一個物件需要準確的類名。ISpeechRecognizer通常以SpSharedRecognizer或者SpInprocRecognizer來實現。由於在使用前不知道哪種型別將會被使用,所以定義這個物件為Object是安全的。

RequestedUIType屬性:指出從引擎要求的最後的使用者介面(UI)的UI型別(UIType)。

在語音識別(SR)引擎傳送一個RequestUI事件之後,UIType持續直到下個RequestUI事件。使用這種方式,應用程式可以檢查最後要求的UI型別。如果沒有UI被要求,UIType字串將為空。

RetainedAudio屬性:得到或者設定識別上下文的音訊保留狀態。

在預設狀態下,一個識別上下文不保留音訊,最初將被設定為SRAONone。如果企圖訪問一個不存在的音訊會導致一個SPERR_NO_AUDIO_DA他的錯誤,對ISpeechRecoResult.Audio和ISpeechRecoResult.SpeekAudiao的呼叫就會導致這個錯誤。這個錯誤在設定一個SpAudioFormat例項時也會發生。

如果為了保留音訊,需要把這個屬性設定為SRAORetainAudio

RetainedAudioFormat屬性:得到或者被識別上下文保留的音訊的格式。

在預設狀態下,被保留的音訊格式將會和輸入的音訊格式一樣。輸入的音訊格式通過呼叫Recognizer.GetFormat(使用SFTInput作為引數)來進行回收。音訊格式可以通過傳遞Nothing作為引數來設定或者重設(在上一次改變以後)為引擎正在使用的相同的格式。

注意:

識別上下文的RetainedAudio需要不被設定為SRAORetainAudio才能使RetainedAudioFormat才能被成功呼叫。RetainedAudioFormat表示音訊應該被保留的格式,而不管這個音訊當前是否被保留。

State屬性:得到或者設定識別上下文的活動狀態。

被關聯給識別上下文的整個語法可以是禁用的或可用的。否則,語法的個別規則狀態是不受影響的。這些條件允許應用程式在高階別控制語法的狀態。例如,一個窗體失去當前的焦點,如果識別不需要,與這個窗體關聯的識別上下文就會被禁用。同樣的,當窗體得到焦點,所有相關的識別上下文就可以變成可用的。

Voice屬性:指定與識別上下文相關聯的SpVoice物件。

注意:

ISpeechRecoContext.Voice可以被臨時改變,並且限制上下文。改變Voice可以使用控制皮膚中的語音選項。

VoicePurgeEvent屬性:得到或者設定RecoContext事件。這個事件可以停止RecoContext聲音,並且清除聲音佇列。

應用程式可以為了一個聲音輸入而使用一個RecoContext物件的聲音屬性來提示使用者。當使用者開始發音時,設定VoicePurgeEvent給SRESoundStart事件將會引起RecoContext的聲音停止發音。

方法有:

Bookmark方法:在當前識別流中設定一個書籤。

一個書籤在音訊流位置和對應用程式有重要意義的事件之間建立聯絡。語音識別(SR)引擎在發音到識別之間有一個潛伏期,這個潛伏狀態可能被這些事件所引起:一個長的發音週期(引擎必須在加工之前得到所有的短語),或者引擎必須完成已經在排隊的等候事件。然而,在潛伏時期,使用者或者應用程式可以繼續操作(如滑鼠移動或者發音)。因此,一個應用程式的條件在識別復原和識別初始化時將會有所不同。書籤允許應用程式標記或者記錄應用程式的特殊識別企圖。

Bookmark是一個對於引擎查詢音訊位置的方便替換。當引擎產生一個書籤時,將會有一個Bookmark事件被返回。

SpeechRecoContext.Bookmark(

Options As SpeechBookmarkOptions,

StreamPos As Variant,

BookmarkId As Variant

)

注意:

例如:一個想顯示識別進展的應用程式,可以在每一個書籤被收到的同時,使用ISpeechRecoContext.Bookmark並且更新UI。

CreateGrammar方法:在ISpeechRecoGrammar的基礎上產生一個物件。

在語音識別發生之前,一個語音識別(SR)引擎要求兩件事:語法產生和語法啟用。一個識別器可能有多於一個與之關聯的語法,儘管他們被限制為兩種型別:聽寫式語法、與上下文無關式語法(CFG)。CFG被用做命令和控制。識別器可能有多於一個的同一型別的活動型別的語法在同一時間開放。在這種情況下,識別將在完全符合的語法下進行。如果有多於一個的語法符合,那個最早開放的語法將會被識別接受。

一個語法在使用之前必須是啟用的,呼叫ISpeechRecoGrammar.DictationSetState去啟用或者釋放一個聽寫語法。ISpeechRecoGrammar.CmdSetRulesStates被用來啟用或者釋放一個命令和控制規則(其同樣控制相關聯的語法)。通過控制語法的狀態,不同的語法被用在不同的時間。

下面的程式碼用來說明如何產生和啟用一個聽寫式語法:

Public WithEvents RC As SpSharedRecoContext

Public myGrammar As ISpeechRecoGrammar

 

Set RC = New SpSharedRecoContext

Set myGrammar = RC.CreateGrammar(0)

myGrammar.DictationLoad

myGrammar.DictationSetState SGDSActive

 

下面的程式碼則用來說明如何產生和啟用一個CFG語法:

Public WithEvents RC As SpSharedRecoContext

Public myGrammar As ISpeechRecoGrammar

 

Set RC = New SpSharedRecoContext

Set myGrammar = RC.CreateGrammar

 

myGrammar.CmdLoadFromFile "sol.xml", SLODynamic

myGrammar.CmdSetRuleIdState 0, SGDSActive

Pause方法:暫停引擎物件,以便和語音識別(SR)引擎同步。Pause停止SR引擎在同步點,以便改變語法和規則狀態。任何一個Recogition事件、Bookmark事件或者明確呼叫Pause都會產生一個同步點。在同步語法和規則狀態後,如果呼叫Resume,引擎將會繼續識別。

在應用程式已經改變狀態或語法後,它應該呼叫ISpeechRecoContext.Resume。每一個Resume呼叫對應於一個Pause呼叫。SAPI將會自動把緩衝音訊資料提供給SR引擎。確保沒有實時資料丟失,使用者的體驗過程不被打斷。一旦呼叫Resume,SAPI將會重啟SR引擎。

在暫停過程中,SAPI收集和儲存音訊,放入一個音訊緩衝中。SAPI音訊緩衝有一個靜態限制,以防止SAPI應用程式或SR引擎消耗大量的系統資源。如果SR引擎暫停時間過長,並且音訊緩衝被填充,這時候緩衝就會溢位(SPER_AUDIO_BUFFER_OVERFLOW),這將會導致打斷正在使用SAPI的其他應用程式。緩衝被設定為每秒平均量的30倍或者被設定為30秒。因此,在緩衝溢位的點之間的被收集的音訊資料(或者當音訊流重新開始時)都將會被徹底丟棄。使用Pause只能是在很短的時間,並且一旦語法和規則狀態改變,應立即呼叫Resume。

注意:

當SR引擎在執行時,語法和規則狀態的改變都會被要求。然而,這種改變可能不會發生直到引擎停止或同步時。由於一個Recognition事件是一個普通的同步點。在很多情況下,沒有必要去呼叫Pause。但是如果語法或者狀態改變需要立即實現,呼叫Pause,做出改變,然後呼叫Resume。

SAPI5的SR引擎同步每過60秒自動關閉,用來避免響亮或者持續背景噪聲造成的干擾。

Resume方法:從暫停狀態中釋放SR引擎,重啟識別程式。

SetAdaptationData方法:傳遞一串適應資料給SR引擎。

一個應用程式通過訓練SR引擎接受新單詞或者片語來提高對口述的不常用單詞或者片語的識別準確率。

一個應用程式通過使用SetAdptationData方法可以產生或者獲得典型文字,並且傳送結果給引擎。

注意:

應用程式使用適應資料應該把資料分成小塊(1KB或者更小),並且單獨地提交這些塊。首先,使用ISpeechRecoContex.EventInterests方法可以指定適應事件中感興趣的內容。Adapation事件中的興趣預設是開啟狀態。然後,使用SetAdaptation方法傳送一個小資料塊到SR引擎,並且等待ISpeechRecoContext.Adaptation事件,這個事件指出適應資料已經被加工。傳送所有連續的資料塊都使用這種方法。最後,使用EventInterests方法來關閉Adaptation事件。由於這個事件僅在顯式呼叫SetAdaptationData之後被返回,所以這個事件的興趣不需要移除,除非有大量的片語被新增或者加工的時間不可接受。Adaptation事件表示引擎已經加工適應性字串,並且準備去接受另一個SetAdaptation呼叫。

相關文章