ISpeechPhraseAlternate Code Example (SAPI 5.3)
Microsoft Speech API 5.3
Interface: ISpeechPhraseAlternate
ISpeechPhraseAlternate Code Example
The following Visual Basic form code displays use of the ISpeechPhraseAlternate object. It demonstrates recognition and the EmulateRecognition method.
To run this code, create a form with the following controls:
- A text box called Text1
- Two list boxes, called List1 and List2
- Two command buttons, called Command1 and Command2
Paste this code into the Declarations section of the form and add a reference to Microsoft Speech Object Library in Visual Basic's References dialog box.
The solitaire grammar file sol.xml is located in the default directory for a standard SAPI SDK installation. If the file is not there, use the path to an existing version. If no file is available, use the example code from VB Application Sample: Command and Control Recognition if needed.
The Form_Load procedure creates a recognizer, a recognition context, and a grammar object. It loads the grammar object with sol.xml, the Solitaire grammar from the SAPI sample code, then activates the command and control (C and C) and dictation components of the grammar, and places a Solitaire command in the text box. Text matching the rules of the Solitaire grammar will produce better recognition results, but in order to demonstrate recognition alternates, it is necessary to enter phrases that do not satisfy grammar rules.
The command button, captioned Recognition, speaks text from the text box into an audio .wav file and then performs speech recognition of that file. The command button captioned EmulateRecognition simply calls the EmulateRecognition method.
When alternates are available, the code displays three alternates in the top list box, and shows the phrase elements of one alternate in the lower list box. Click any alternate to display its phrase elements in the lower list box. Double click any alternate to perform the Commit method on that alternate. In the illustration below, the first alternate is incorrect; the second alternate is highlighted, and its phrase elements are displayed in the lower list box.
The data displayed in the lower list box is the same data displayed in the ISpeechPhraseElement code example. Please see that page for full details.
Option Explicit
Const WAVEFILENAME = "C:\ISpeechPhraseAlternate.wav"
Private blnAlternatesExist As Boolean
Private MyRecognizer As SpeechLib.SpInprocRecognizer
Private MyGrammar As SpeechLib.ISpeechRecoGrammar
Private MyFileStream As SpeechLib.SpFileStream
Private MyVoice As SpeechLib.SpVoice
Private PhraseInfo As SpeechLib.ISpeechPhraseInfo
Private PhraseAlts1 As SpeechLib.ISpeechPhraseAlternate
Private PhraseAlts2 As SpeechLib.ISpeechPhraseAlternates
Private PhraseElem As SpeechLib.ISpeechPhraseElement
Private PhraseElems As SpeechLib.ISpeechPhraseElements
Private WithEvents MyRecoContext As SpeechLib.SpInProcRecoContext
Private Sub Command1_Click()
On Error GoTo EH
List1.Clear
List2.Clear
Screen.MousePointer = vbHourglass
' Create ISpeechPhraseAlternate.wav file from text in text box.
Set MyFileStream = MakeWAVFileFromText(Text1.Text, WAVEFILENAME)
'Set the file as recognizer's input stream
MyFileStream.Open WAVEFILENAME
Set MyRecognizer.AudioInputStream = MyFileStream
EH:
If Err.Number Then ShowErrMsg
End Sub
Private Sub Command2_Click()
On Error GoTo EH
List1.Clear
List2.Clear
Screen.MousePointer = vbHourglass
MyRecoContext.Recognizer.EmulateRecognition Text1.Text
EH:
If Err.Number Then ShowErrMsg
End Sub
Private Sub Form_Load()
On Error GoTo EH
' Create Recognizer, RecoContext, Grammar, and Voice
Set MyRecognizer = New SpInprocRecognizer
Set MyRecoContext = MyRecognizer.CreateRecoContext
Set MyGrammar = MyRecoContext.CreateGrammar(16)
Set MyVoice = New SpVoice
' Load Grammar with solitaire XML, set active
MyGrammar.CmdLoadFromFile "C:\sol.xml", SLOStatic
MyGrammar.CmdSetRuleIdState 0, SGDSActive 'Set MyRecoContext & MyRecoContext active
MyGrammar.DictationSetState SGDSActive 'Set Dictation active
Text1.Text = "let's go over minor details"
Command1.Caption = "&Recognition;"
Command2.Caption = "&EmulateRecognition;"
EH:
If Err.Number Then ShowErrMsg
End Sub
Private Function MakeWAVFileFromText _
(ByVal strText As String, _
ByVal strFName As String) _
As SpFileStream
On Error GoTo EH
' Declare identifiers:
Dim FileStream As SpFileStream
Dim Voice As SpVoice
' Instantiate Voice and FileStream objects:
Set Voice = New SpVoice
Set FileStream = New SpFileStream
' Open specified .wav file, set voice output
' to file, and speak synchronously:
FileStream.Open strFName, SSFMCreateForWrite, True
Set Voice.AudioOutputStream = FileStream
Voice.Speak strText, SVSFIsXML
' Close file and return reference to FileStream object:
FileStream.Close
Set MakeWAVFileFromText = FileStream
EH:
If Err.Number Then ShowErrMsg
End Function
Private Function PhonesToString(ByVal arrV As Variant) As String
Dim ii As Integer, S As String
On Error GoTo EH
If IsEmpty(arrV) Then
PhonesToString = ""
Else
For ii = 0 To UBound(arrV)
If Len(S) Then
S = S & "," & arrV(ii)
Else
S = arrV(ii)
End If
Next ii
PhonesToString = S
End If
EH:
If Err.Number Then ShowErrMsg
End Function
Private Sub MyRecoContext_Recognition _
(ByVal StreamNumber As Long, _
ByVal StreamPosition As Variant, _
ByVal RecognitionType As SpeechLib.SpeechRecognitionType, _
ByVal Result As SpeechLib.ISpeechRecoResult)
Dim nn As Integer
On Error GoTo EH
Set PhraseAlts2 = Result.Alternates(3) 'May or may not be available
If PhraseAlts2 Is Nothing Then
'No alternates when speech matches PhraseAlts1 grammar rule
'No alternates when using EmulateRecognition
blnAlternatesExist = False
List1.AddItem Result.PhraseInfo.GetText
If Len(Result.PhraseInfo.Rule.Name) Then
List1.AddItem " matches rule """ & Result.PhraseInfo.Rule.Name & """"
End If
Set PhraseInfo = Result.PhraseInfo
Else
blnAlternatesExist = True
nn = 0
For Each PhraseAlts1 In PhraseAlts2
List1.AddItem "alt" & Format(nn) & ": " & PhraseAlts1.PhraseInfo.GetText
nn = nn + 1
Next
Set PhraseInfo = PhraseAlts2.Item(0).PhraseInfo
End If
List1.ListIndex = 0 'Highlight the selected alternate
Call DisplayPhraseElements(0)
Screen.MousePointer = vbDefault
EH:
If Err.Number Then ShowErrMsg
End Sub
Private Sub MyRecoContext_EndStream _
(ByVal StreamNumber As Long, _
ByVal StreamPosition As Variant, _
ByVal StreamReleased As Boolean)
On Error GoTo EH
'Recognition uses the Filestream, EmulateReco does not
If ActiveControl.Caption = "&Recognition;" Then
MyFileStream.Close
DoEvents
MyFileStream.Open WAVEFILENAME
MyVoice.SpeakStream MyFileStream
MyFileStream.Close
End If
Screen.MousePointer = vbDefault
EH:
If Err.Number Then ShowErrMsg
End Sub
Private Sub DisplayPhraseElements(Index As Integer)
Dim X As String
Dim T As String
Dim A1 As Long, A2 As Long
Dim T1 As Long, T2 As Long
Dim C1 As Single, C2 As Integer, C3 As Integer
On Error GoTo EH
List2.Clear
'If no alternates, then there is only one PhraseInfo
If blnAlternatesExist = True Then
Set PhraseInfo = PhraseAlts2.Item(Index).PhraseInfo
End If
For Each PhraseElem In PhraseInfo.Elements
'Audio data
A1 = PhraseElem.AudioStreamOffset
A2 = PhraseElem.AudioSizeBytes
X = Format(A1, "000000") & " " & Format(A2, "000000") & " "
'Time data
T1 = PhraseElem.AudioTimeOffset
T2 = PhraseElem.AudioSizeTime
X = X & Format(T1, "000000000") & " " & Format(T2, "000000000") & " "
'Display attributes
X = X & Format(PhraseElem.DisplayAttributes) & " "
'Confidences
C1 = PhraseElem.EngineConfidence
C2 = PhraseElem.ActualConfidence
C3 = PhraseElem.RequiredConfidence
T = "(" & Format(C1) & " " & Format(C2) & " " & Format(C3) & ")"
X = X & Left(T & " ", 14)
'Text and pronunciation
X = X & Left(PhraseElem.DisplayText & " ", 14)
X = X & PhonesToString(PhraseElem.Pronunciation)
List2.AddItem X
Next
EH:
If Err.Number Then ShowErrMsg
End Sub
Private Sub List1_Click()
Call DisplayPhraseElements(List1.ListIndex)
End Sub
Private Sub List1_DblClick()
PhraseAlts2.Item(List1.ListIndex).Commit
End Sub
Private Sub ShowErrMsg()
' Declare identifiers:
Const NL = vbNewLine
Dim T As String
T = "Desc: " & Err.Description & NL
T = T & "Err #: " & Err.Number
MsgBox T, vbExclamation, "Run-Time Error"
End
End Sub