Speech Recognition Command and Control SAPI 5.1
Publié : dim. 10/juin/2012 11:47
Voici un code de reconnaissance vocale qui écrit à l'écran tous les mots que vous avez écrit dans le fichier xml avec plus ou moins de succès.
Je crois que sous Window XP, il faut installer le SDK SAPI 5.1 pour que ça marche
Le code PureBasic nécessite les fichiers de ComatePlus pour fonctionner!
A ce propos, il y a une erreur dans le fichier COMatePLUS.pbi, il faut remplacer les Hresult par des Hresult.l car sinon ça entraine des erreurs si on compile en 64 bits
Il est évident que si vous n'avez jamais utiliser la reconnaissance vocale de votre ordi, ça ne va pas bien fonctionner!
Il faut dans un premier temps exécuter le module d'apprentissage de la voix de window et suivre les didacticiels, plus vous vous servirez de la reconnaissance vocale, mieux il interprétera votre voix.
Pensez à modifier le chemin du fichier xml!
J' ai mis dans le fichier xml, les mots Invisible et Visible qui permettent de cacher et de rendre visible la fenêtre.
Le code:
Le fichier xml:
Je crois que sous Window XP, il faut installer le SDK SAPI 5.1 pour que ça marche
Le code PureBasic nécessite les fichiers de ComatePlus pour fonctionner!
A ce propos, il y a une erreur dans le fichier COMatePLUS.pbi, il faut remplacer les Hresult par des Hresult.l car sinon ça entraine des erreurs si on compile en 64 bits
Il est évident que si vous n'avez jamais utiliser la reconnaissance vocale de votre ordi, ça ne va pas bien fonctionner!
Il faut dans un premier temps exécuter le module d'apprentissage de la voix de window et suivre les didacticiels, plus vous vous servirez de la reconnaissance vocale, mieux il interprétera votre voix.
Pensez à modifier le chemin du fichier xml!
J' ai mis dans le fichier xml, les mots Invisible et Visible qui permettent de cacher et de rendre visible la fenêtre.
Le code:
Code : Tout sélectionner
XIncludeFile "COMatePLUS.pbi"
;{- Enumerations / DataSections
;{ Windows
Enumeration
#Window_0
EndEnumeration
;}
;{ Gadgets
Enumeration
#Text_Message
#String
#Text_2
#Text_3
#Editor
#Button_Desactive
#Button_Reactive
EndEnumeration
;}
;{ Fonts
Enumeration
#Font_Text_Message
#Font_String_1
EndEnumeration
;}
;}
Structure Parametres
SpRecoContext.i
SpeechRecoGrammar.i
EndStructure
Procedure SpeechRecoContextEvents(event.COMateObject, event$, parameterCount)
Protected iParam.iUnknown
Protected SpeechRecoResult.COMateObject
Protected SpeechPhraseInfo.COMateObject
Protected SpeechPhraseElements.COMateObject
Protected SpeechPhraseElement.COMateObject
Protected SpeechPhraseRule.COMateObject
Protected AdditionConfidence.l
Protected Texte.s, rule.s
Protected a.l, count.l, niveau.l
; Debug("EVT " + Str(parameterCount) + " " + event$)
Select event$
Case "FalseRecognition"
SetGadgetText(#String, "<Phrase ou mot non reconnu>")
Case "Recognition"
Debug "-------------Recognition-----------------"
iParam = event\GetObjectEventParam(4)
If iParam
SpeechRecoResult = COMate_WrapCOMObject(iParam)
If SpeechRecoResult
SpeechPhraseInfo = SpeechRecoResult\GetObjectProperty("PhraseInfo()")
COMate_GetLastErrorDescription()
If SpeechPhraseInfo
SpeechPhraseElements = SpeechPhraseInfo\GetObjectProperty("Elements")
If SpeechPhraseElements <> 0
count = SpeechPhraseElements\GetIntegerProperty("Count")
For a=0 To count - 1
SpeechPhraseElement = SpeechPhraseElements\GetObjectProperty("Item(" + Str(a) + ")")
If SpeechPhraseElement <> 0
niveau.l=SpeechPhraseElement\GetIntegerProperty("ActualConfidence")
; #SECLowConfidence = -1 ; niveau de reconnaissance basse
; #SECNormalConfidence = 0 ; niveau de reconnaissance normal
; #SECHighConfidence = 1 ; niveau de reconnaissance haute
; Pour chaque mot, j'affiche le niveau de reconnaissance
Debug "Niveau = " + Str(niveau)
AdditionConfidence = AdditionConfidence + niveau
SpeechPhraseElement\Release()
EndIf
Next a
SpeechPhraseElements\Release()
EndIf
; Si tous les mots ont un niveau de 1
If AdditionConfidence = count
SpeechPhraseRule = SpeechPhraseInfo\GetObjectProperty("Rule")
If SpeechPhraseRule <> 0
rule.s = SpeechPhraseRule\GetStringProperty("Name")
Debug "Rule = " + rule
SpeechPhraseRule\Release()
EndIf
Texte = SpeechPhraseInfo\GetStringProperty("GetText(0, -1, 1)")
SetGadgetText(#String, Texte)
Select Texte
Case "fenêtre visible"
HideWindow(#Window_0, 0)
Case "fenêtre invisible"
HideWindow(#Window_0, 1)
EndSelect
EndIf
If FindString(LCase(Texte), "bonjour")
MessageRequester("Info", "Vous avez dit le mot Bonjour!")
EndIf
SpeechPhraseInfo\Release()
EndIf
SpeechRecoResult\Release()
EndIf
iParam\Release()
EndIf
Case "Hypothesis"
Debug "------------Hypothesis------------------"
SetGadgetText(#Text_Message, "Enregistrement en cours...")
iParam = event\GetObjectEventParam(3)
If iParam
SpeechRecoResult = COMate_WrapCOMObject(iParam)
If SpeechRecoResult
SpeechPhraseInfo = SpeechRecoResult\GetObjectProperty("PhraseInfo()")
If SpeechPhraseInfo
Texte = SpeechPhraseInfo\GetStringProperty("GetText(0, -1, 1)")
SetGadgetText(#Editor, Texte + Chr(13) + GetGadgetText(#Editor))
SpeechPhraseInfo\Release()
EndIf
SpeechRecoResult\Release()
EndIf
iParam\Release()
EndIf
Case "SoundStart"
Debug "SoundStart"
SetGadgetText(#String, "")
Case "SoundEnd"
Debug "SoundEnd"
SetGadgetText(#Text_Message, "Parler")
Case "StartStream"
; Debug "StartStream"
Case "EndStream"
; Debug "EndStream"
EndSelect
EndProcedure
Procedure Load_Speech_Recognition(*Speech_Recognition.Parametres, File.s)
Protected SpRecoContext.COMateObject
Protected SpRecoGrammar.COMateObject
Protected Init_Recognition.l = 0
Protected SpRecognizer.COMateObject
Protected SpeechRecognizer.COMateObject
Protected SpObjectTokenCategory.COMateObject
Protected SpObjectToken.COMateObject
SpRecoContext = COMate_CreateObject("SAPI.SpInProcRecoContext")
Debug COMate_GetLastErrorDescription()
If SpRecoContext = 0 : Goto Clean : EndIf
SpRecoGrammar = SpRecoContext\GetObjectProperty("CreateGrammar(0)")
If SpRecoGrammar = 0 : Goto Clean : EndIf
RecoGrammar.idispatch = SpRecoGrammar\GetCOMObject()
If RecoGrammar = 0 : Goto Clean : EndIf
RecoGrammar\QueryInterface(?IID_ISpeechRecoGrammar, @SpeechRecoGrammar_)
If SpeechRecoGrammar_ = 0 : Goto Clean : EndIf
SpeechRecoGrammar.COMateObject = COMate_WrapCOMObject(SpeechRecoGrammar_)
Debug COMate_GetLastErrorDescription()
If SpeechRecoGrammar = 0 : Goto Clean : EndIf
#SLOStatic = 0
#SLODynamic = 1
If SpeechRecoGrammar\invoke("CmdLoadFromFile('" + File + "', " + Str(#SLODynamic) + ")") <> 0
Debug COMate_GetLastErrorDescription()
Goto Clean
EndIf
If SpRecoContext\SetEventHandler(#COMate_CatchAllEvents, @SpeechRecoContextEvents()) <> 0
Debug COMate_GetLastErrorDescription()
Goto Clean
EndIf
SpRecognizer = SpRecoContext\GetObjectProperty("Recognizer()")
If SpRecognizer = 0 : Goto Clean : EndIf
Recognizer.idispatch = SpRecognizer\GetCOMObject()
If Recognizer = 0 : Goto Clean : EndIf
Recognizer\QueryInterface(?IID_ISpeechRecognizer, @SpeechRecognizer_)
If SpeechRecognizer_ = 0 : Goto Clean : EndIf
SpeechRecognizer.COMateObject = COMate_WrapCOMObject(SpeechRecognizer_)
If SpeechRecognizer = 0 : Goto Clean : EndIf
SpObjectTokenCategory = COMate_CreateObject("SAPI.SpObjectTokenCategory")
If SpObjectTokenCategory = 0 : Goto Clean : EndIf
#SpeechCategoryAudioIn = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\AudioInput"
If SpObjectTokenCategory\invoke("SetId('" + #SpeechCategoryAudioIn + "', 0)") <> 0
Debug comate_getlasterrordescription()
Goto Clean
EndIf
SpObjectToken = COMate_CreateObject("SAPI.SpObjectToken")
If SpObjectToken = 0 : Goto Clean : EndIf
Audio$ = SpObjectTokenCategory\GetStringProperty("Default()")
Debug audio$
If SpObjectToken\invoke("SetId('" + Audio$ + "')") <> 0
Goto Clean
EndIf
If SpeechRecognizer\Setpropertyref("AudioInput(" + Str(SpObjectToken) + " as COMateObject)") <> 0
Goto Clean
EndIf
; La Règle de grammaire est active.
#SGDSActive = 1
If SpeechRecoGrammar\invoke("CmdSetRuleIdState(0, " + Str(#SGDSActive) + ")") <> 0
Goto Clean
Else
Init_Recognition = 1
EndIf
Clean:
If Init_Recognition = 0
If SpRecoContext <> 0 : SpRecoContext\Release() : EndIf
If SpRecoGrammar <> 0 : SpRecoGrammar\Release() : EndIf
If SpeechRecoGrammar <> 0 : SpeechRecoGrammar\Release() : EndIf
Else
*Speech_Recognition\SpRecoContext = SpRecoContext
*Speech_Recognition\SpeechRecoGrammar = SpeechRecoGrammar
EndIf
ProcedureReturn Init_Recognition
EndProcedure
Procedure Finish_Speech_Recognition(*Speech_Recognition.Parametres)
Protected SpRecoContext.COMateObject
Protected SpeechRecoGrammar.COMateObject
SpRecoContext = *Speech_Recognition\SpRecoContext
SpeechRecoGrammar = *Speech_Recognition\SpeechRecoGrammar
If SpeechRecoGrammar <> 0
; La Règle de grammaire est inactive.
#SGDSInActive = 0
SpeechRecoGrammar\invoke("CmdSetRuleIdState(0, " + Str(#SGDSInActive) + ")")
SpeechRecoGrammar\Release()
EndIf
If SpRecoContext <> 0
SpRecoContext\SetEventHandler(#COMate_CatchAllEvents, 0)
SpRecoContext\Release()
EndIf
EndProcedure
Procedure Desactive_Recognition(*Speech_Recognition.Parametres, Valeur.l)
Protected SpeechRecoGrammar.COMateObject
SpeechRecoGrammar = *Speech_Recognition\SpeechRecoGrammar
#SGDSInActive = 0
#SGDSActive = 1
If Valeur = 0
SpeechRecoGrammar\invoke("CmdSetRuleIdState(0, " + Str(#SGDSActive) + ")")
Debug COMate_GetLastErrorDescription()
ElseIf Valeur = 1
SpeechRecoGrammar\invoke("CmdSetRuleIdState(0, " + Str(#SGDSInActive) + ")")
Debug COMate_GetLastErrorDescription()
EndIf
EndProcedure
Procedure OpenWindow_Window_0()
If OpenWindow(#Window_0, 732, 260, 600, 400, "Speech Recognition", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_TitleBar | #PB_Window_SizeGadget)
TextGadget(#Text_Message, 0, 0, 600, 50, "Parler et commencer par dire : Invisible puis Visible", #PB_Text_Center)
StringGadget(#String, 0, 95, 600, 35, "", #PB_String_ReadOnly)
TextGadget(#Text_2, 0, 75, 600, 20, " Phrase Reconnue:")
TextGadget(#Text_3, 0, 160, 600, 20, " Phrase décryptée au fur et à mesure de l'enregistrement:")
EditorGadget(#Editor, 0, 180, 600, 165, #PB_Editor_ReadOnly)
ButtonGadget(#Button_Desactive, 60, 355, 200, 35, "Désactiver Temporairement")
ButtonGadget(#Button_Reactive, 335, 355, 200, 35, "Réactiver")
DisableGadget(#Button_Reactive, 1)
; Gadget Fonts
SetGadgetFont(#Text_Message, LoadFont(#Font_Text_Message, "Microsoft Sans Serif", 12, 272))
SetGadgetFont(#String, LoadFont(#Font_String_1, "Microsoft Sans Serif", 12, 16))
EndIf
EndProcedure
CoInitialize_(0)
File.s = "H:\Programmation\Codes\SAPI Reconnaissance vocale\sol2.xml"
If Load_Speech_Recognition(@Speech_Recognition.Parametres, File) = 0
MessageRequester("Erreur", "L'initialisation du moteur de la reconnaissance vocale à échoué!")
End
EndIf
OpenWindow_Window_0()
;{- Event loop
Repeat
Select WaitWindowEvent()
;/ //////////////////
Case #PB_Event_Gadget
Select EventGadget()
Case #Button_Desactive
DisableGadget(#Button_Reactive, 0)
DisableGadget(#Button_Desactive, 1)
Desactive_Recognition(@Speech_Recognition.Parametres, 1)
Case #Button_Reactive
DisableGadget(#Button_Reactive, 1)
DisableGadget(#Button_Desactive, 0)
Desactive_Recognition(@Speech_Recognition.Parametres, 0)
EndSelect
;/ ///////////////////////
Case #PB_Event_CloseWindow
Select EventWindow()
Case #Window_0
CloseWindow(#Window_0)
Finish_Speech_Recognition(@Speech_Recognition.Parametres)
CoUninitialize_()
Break
EndSelect
EndSelect
ForEver
;
;}
Macro GUID(iid, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, b0)
DataSection
IID:
Data.l $a0
Data.w $a1, $a2
Data.b $a3, $a4, $a5, $a6, $a7, $a8, $a9, $b0
EndDataSection
EndMacro
GUID(IID_ISpeechRecoGrammar, B6D6F79F, 2158, 4E50, B5, BC, 9A, 9C, CD, 85, 2A, 09)
GUID(IID_ISpeechRecognizer, 2D5F1C0C, BD75, 4B08, 94, 78, 3B, 11, FE, A2, 58, 6C)
Le fichier xml:
Code : Tout sélectionner
<GRAMMAR LANGID="40C">
<DEFINE>
<ID NAME="RID_afficher" VAL="1"/>
</DEFINE>
<DEFINE>
<ID NAME="RID_cacher" VAL="2"/>
</DEFINE>
<RULE NAME="afficher" ID="RID_afficher" TOPLEVEL="ACTIVE">
<P>afficher</P>
<RULEREF NAME="transition" />
<RULEREF NAME="cible" />
</RULE>
<RULE NAME="cacher" ID="RID_cacher" TOPLEVEL="ACTIVE">
<p>cacher</p>
<RULEREF NAME="transition" />
<RULEREF NAME="cible" />
</RULE>
<RULE NAME="transition">
<o>la</o>
<o>l'</o>
</RULE>
<RULE NAME="cible">
<L>
<P>fenêtre</P>
<P>application</P>
</L>
</RULE>
</GRAMMAR>