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>