Speech Recognition Command and Control SAPI 5.1

Partagez votre expérience de PureBasic avec les autres utilisateurs.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Speech Recognition Command and Control SAPI 5.1

Message par nico »

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:

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>
Dernière modification par nico le mer. 13/juin/2012 17:52, modifié 6 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Speech Recognition Command (Reconnaissance vocale)

Message par Backup »

Merci , je vais essayer deja de comprendre le truc


ps: j'ai une erreur de label introuvable sur la ligne :

Code : Tout sélectionner

 RecoGrammar\QueryInterface(?IID_ISpeechRecoGrammar, @SpeechRecoGrammar_)
ceci plante
?IID_ISpeechRecoGrammar
ceci aussi :
?IID_ISpeechRecognizer
ps : je pensais que sous Seven nous etions en Sapi5 ... 8O
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Speech Recognition Command (Reconnaissance vocale)

Message par nico »

Désolé, c'est corrigé!
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Speech Recognition Command (Reconnaissance vocale)

Message par Backup »

a ce propos , si vous installez Virginie (magnifique voix Française, en Sapi5 ) sous Win seven 64 bit

il est possible que cette vois n’apparaisse pas dans les voix disponible de Seven

pour la rendre disponible il faut allez dans :

Ordinateur > c:\ Windows > SysWOW64 > Speech >SpeechUX
et double cliquer dur le fichier "sapi.cpl" ; et voila , elle sera reconnue :)

je remet ici : le lien de la voix Virginie :
http://idee-association.org/wp-content/ ... French.zip

:)

Merci Nico , je re-essai
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Speech Recognition Command (Reconnaissance vocale)

Message par Backup »

Marche niquel :)

tu viens de me donner la possibilité d'appeler mon Starter de façon vocale :)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Speech Recognition Command (Reconnaissance vocale)

Message par Backup »

en fait cette histoire de Dico c'est pas mal , car dans la version 1 du prg

il ecoutait tout les mots qu'on disait ... sauf que .. si je disai "dobro"

bien sur , il ne reconnaissai rien, car dobro , ne fait pas partie de la langue française

par contre .... la version avec dico
est tres tres intéressante , pour apprendre des nouveaux mots a la reconnaissance vocale :D

il m'a suffit d'ajouter :
<GRAMMAR>
<DEFINE>
<ID NAME="RID_invisible" VAL="101"/>
</DEFINE>
<DEFINE>
<ID NAME="RID_visible" VAL="102"/>
</DEFINE>
<DEFINE>
<ID NAME="RID_dobro" VAL="103"/>
</DEFINE>
<RULE NAME="invisible" ID="RID_invisible" TOPLEVEL="ACTIVE">
<P>invisible</P>
</RULE>
<RULE NAME="visible" ID="RID_visible" TOPLEVEL="ACTIVE">
<P>visible</P>
</RULE>
<RULE NAME="dobro" ID="RID_dobro" TOPLEVEL="ACTIVE">
<P>dobro</P>
</RULE>
</GRAMMAR>
pour creer un mots nouveau "dobro" qui soit reconnu :)

dorenavant , lorsque je dis "dobro"
le prg réagit :D

c'est clairement une façon d'apprendre , n'importe quel nouveau mot au prg , mais aussi
de le tenir dans un contexte particulier , ou justement, comme j'en parlais avec Case
une façon d'etre sur qu'il reconnaisse QUE certaines expression :D en filtrant ce qu'il ne connais pas ...

instinctivement on peut en deduire que :
<DEFINE>
<ID NAME="RID_dobro" VAL="103"/>
</DEFINE>
creer un slot pour le nouveau mots

et que :
<RULE NAME="dobro" ID="RID_dobro" TOPLEVEL="ACTIVE">
<P>dobro</P>
</RULE>
sert a creer la regle de reconnaissance du nouveau mot
en utilisant le meme ID qu'a la creation du Slot
en précisant la meme "orthographe" du mot

juste le parametre (TOPLEVEL="ACTIVE") a décoder , mais je suppose qu'on peux ainsi
désactiver temporairement un mot .. a vérifier :)

Merci encore Nico , si Fred pouvait inclure ce Boulot dans la future version de Purebasic , ce serai GEANT :)
histoire d’alléger les codes

peut etre envisager une petite Lib :)
Dernière modification par Backup le dim. 10/juin/2012 21:58, modifié 1 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Speech Recognition Command (Reconnaissance vocale)

Message par Backup »

et ... si on ajoute ton ancien travail sur la Synthese Vocale Sans librairie ( mais avec la voix Virginie d'installée ..dont je donne le lien un peu plus haut )
et le Dico.xml
<GRAMMAR>
<DEFINE>
<ID NAME="RID_invisible" VAL="101"/>
</DEFINE>
<DEFINE>
<ID NAME="RID_visible" VAL="102"/>
</DEFINE>
<DEFINE>
<ID NAME="RID_dobro" VAL="103"/>
</DEFINE>
<RULE NAME="invisible" ID="RID_invisible" TOPLEVEL="ACTIVE">
<P>invisible</P>
</RULE>
<RULE NAME="visible" ID="RID_visible" TOPLEVEL="ACTIVE">
<P>visible</P>
</RULE>
<RULE NAME="dobro" ID="RID_dobro" TOPLEVEL="ACTIVE">
<P>dobro</P>
</RULE>
</GRAMMAR>

Code : Tout sélectionner


Procedure Speak2(Text$)
    Interface ISpNotifySource Extends IUnknown
        SetNotifySink(a)
        SetNotifyWindowMessage(a,b,c,d)
        SetNotifyCallbackFunction(a,b,c)
        SetNotifyCallbackInterface(a,b,c)
        SetNotifyWin32Event()
        WaitForNotifyEvent(a)
        GetNotifyEventHandle()
    EndInterface
    
    Interface ISpEventSource Extends ISpNotifySource
        SetInterest(a,b)
        GetEvents(a,b,c)
        GetInfo(a)
    EndInterface
    
    Interface ISpVoice Extends ISpEventSource
        SetOutput(a,b)
        GetOutputObjectToken(a)
        GetOutputStream(a)
        Pause()
        Resume()
        SetVoice(a)
        GetVoice(a)
        Speak(a,b,c)
        SpeakStream(a,b,c)
        GetStatus(a,b)
        Skip(a,b,c)
        SetPriority(a)
        GetPriority(a)
        SetAlertBoundary(a)
        GetAlertBoundary(a)
        SetRate(a)
        GetRate(a)
        SetVolume(a)
        GetVolume(a)
        WaitUntilDone(a)
        SetSyncSpeakTimeout(a)
        GetSyncSpeakTimeout(a)
        SpeakCompleteEvent()
        IsUISupported(a,b,c,d)
        DisplayUI(a,b,c,d,e)
    EndInterface
    
    #CLSCTX_INPROC_SERVER  = $1
    #CLSCTX_INPROC_HANDLER = $2
    #CLSCTX_LOCAL_SERVER   = $4
    #CLSCTX_REMOTE_SERVER  = $10
    #CLSCTX_ALL = (#CLSCTX_INPROC_SERVER|#CLSCTX_INPROC_HANDLER|#CLSCTX_LOCAL_SERVER|#CLSCTX_REMOTE_SERVER)
    
    Global VoiceObject.ISpVoice
    
    
    
    
    
    
    length = Len(Text$)*2+10
    *mem = AllocateMemory(length)
    MultiByteToWideChar_(#CP_ACP ,0,Text$,-1,*mem, length)
    VoiceObject\Speak(*mem,0,0)
    
    DataSection
        CLSID_SpVoice:
        ;96749377-3391-11D2-9EE3-00C04F797396
        Data.l $96749377
        Data.w $3391,$11D2
        Data.b $9E,$E3,$00,$C0,$4F,$79,$73,$96
        IID_ISpVoice:
        ;6C44DF74-72B9-4992-A1EC-EF996E0422D4
        Data.l $6C44DF74
        Data.w $72B9,$4992
        Data.b $A1,$EC,$EF,$99,$6E,$04,$22,$D4
    EndDataSection 
    
    
EndProcedure



CoInitialize_(0)
If CoCreateInstance_(?CLSID_SpVoice, 0, #CLSCTX_ALL, ?IID_ISpVoice, @VoiceObject.ISpVoice) = 0
    VoiceObject\SetVolume(100)
    VoiceObject\SetRate(-5)
    VoiceObject\SetVoice(0) ; voix 0
    Speak2("on fait parler PureBasic sans librairie !!.")
    VoiceObject\SetRate(-50) ; vitesse 
    Speak2("on fait parler PureBasic sans librairie !!.")
Else
    MessageRequester("ERROR","MS SPEECH API not installed",0)
EndIf

nous avons la un programme capable d'ecouter et de répondre !! :D

pour le fun , et apres avoir installé Virginie
lancez ce code , et dites :
"invisible"
"visible"

"Salut Dobro"
le prg va répondre "Salut Mec"

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


; synthese
Interface ISpNotifySource Extends IUnknown
	SetNotifySink(a)
	SetNotifyWindowMessage(a,b,c,d)
	SetNotifyCallbackFunction(a,b,c)
	SetNotifyCallbackInterface(a,b,c)
	SetNotifyWin32Event()
	WaitForNotifyEvent(a)
	GetNotifyEventHandle()
EndInterface

Interface ISpEventSource Extends ISpNotifySource
	SetInterest(a,b)
	GetEvents(a,b,c)
	GetInfo(a)
EndInterface

Interface ISpVoice Extends ISpEventSource
	SetOutput(a,b)
	GetOutputObjectToken(a)
	GetOutputStream(a)
	Pause()
	Resume()
	SetVoice(a)
	GetVoice(a)
	Speak(a,b,c)
	SpeakStream(a,b,c)
	GetStatus(a,b)
	Skip(a,b,c)
	SetPriority(a)
	GetPriority(a)
	SetAlertBoundary(a)
	GetAlertBoundary(a)
	SetRate(a)
	GetRate(a)
	SetVolume(a)
	GetVolume(a)
	WaitUntilDone(a)
	SetSyncSpeakTimeout(a)
	GetSyncSpeakTimeout(a)
	SpeakCompleteEvent()
	IsUISupported(a,b,c,d)
	DisplayUI(a,b,c,d,e)
EndInterface

#CLSCTX_INPROC_SERVER  = $1
#CLSCTX_INPROC_HANDLER = $2
#CLSCTX_LOCAL_SERVER   = $4
#CLSCTX_REMOTE_SERVER  = $10
#CLSCTX_ALL = (#CLSCTX_INPROC_SERVER|#CLSCTX_INPROC_HANDLER|#CLSCTX_LOCAL_SERVER|#CLSCTX_REMOTE_SERVER)

Global VoiceObject.ISpVoice
;}
;}

Structure Parametres
	SpRecoContext.i
	SpeechRecoGrammar.i
EndStructure
Declare  OpenWindow_Window_0()
Declare  SpeechRecoContextEvents(event.COMateObject, event$, parameterCount)
Declare  Load_Speech_Recognition(*Speech_Recognition.Parametres, File.s)
Declare  Finish_Speech_Recognition(*Speech_Recognition.Parametres)
Declare  Desactive_Recognition(*Speech_Recognition.Parametres, Valeur.l)
Declare  Speak2(Text$)



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 = "D:\Dobro\PureBasic\dobro\ExemplePerso\nico\dico.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) 


Procedure SpeechRecoContextEvents(event.COMateObject, event$, parameterCount)
	Protected iParam.iUnknown
	Protected SpeechRecoResult.COMateObject
	Protected SpeechPhraseInfo.COMateObject
	Protected Texte.s
	
	;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()")
				If SpeechPhraseInfo
					Texte = SpeechPhraseInfo\GetStringProperty("GetText(0, -1, 1)")
					
					SetGadgetText(#String, Texte)
					
					Select Texte
						Case "visible"
						HideWindow(#Window_0, 0)
						Case "invisible"
						HideWindow(#Window_0, 1)
						case "dobro"
						CoInitialize_(0)
						If CoCreateInstance_(?CLSID_SpVoice, 0, #CLSCTX_ALL, ?IID_ISpVoice, @VoiceObject.ISpVoice) = 0
							VoiceObject\SetVolume(100)
							VoiceObject\SetRate(-5)
							VoiceObject\SetVoice(0) ; voix 0
							Speak2("Salut Mec...")
							; VoiceObject\SetRate(-50) ; vitesse 
							;Speak2("on fait parler PureBasic sans librairie !!.")
							SpeechPhraseInfo\Release()
							SpeechRecoResult\Release()
							iParam\Release()
							ProcedureReturn
							Else
							MessageRequester("ERROR","MS SPEECH API not installed",0)
						EndIf
						;debug "Salut Mec"
						
					EndSelect
					
					
					
					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 Speak2(Text$)
	length = Len(Text$)*2+10
	*mem = AllocateMemory(length)
	MultiByteToWideChar_(#CP_ACP ,0,Text$,-1,*mem, length)
	VoiceObject\Speak(*mem,0,0)
	
	DataSection
		CLSID_SpVoice:
		;96749377-3391-11D2-9EE3-00C04F797396
		Data.l $96749377
		Data.w $3391,$11D2
		Data.b $9E,$E3,$00,$C0,$4F,$79,$73,$96
		IID_ISpVoice:
		;6C44DF74-72B9-4992-A1EC-EF996E0422D4
		Data.l $6C44DF74
		Data.w $72B9,$4992
		Data.b $A1,$EC,$EF,$99,$6E,$04,$22,$D4
	EndDataSection 
	
	
EndProcedure






; EPB

Dernière modification par Backup le dim. 10/juin/2012 16:40, modifié 2 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Speech Recognition Command (Reconnaissance vocale)

Message par Backup »

@Nico
je n'ai pas trouvé comment l'empecher de dire plusieurs fois "Salut mec"

il semble que la reconnaissance, boucle plusieurs fois sur le meme résultat ;)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Speech Recognition Command (Reconnaissance vocale)

Message par Backup »

il semble que j'arrive a couper l'effet de boucle
lorsque j'utilise

Code : Tout sélectionner

SpeechPhraseInfo\Release()
               ProcedureReturn
juste apres la diction :) ( j'ai changé le code ci-dessus )

... mais c'est pas parfait, il boucle souvent encore ...

en fait , il boucle du nombre de mot qu'il a reconnu

si je dit "invisible" "visible" "salut dobro" la repetition aura lieu 3 fois car il a reconnu 3 mots

peut etre un tampon qui ne se vide pas .. ??
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Speech Recognition Command (Reconnaissance vocale)

Message par nico »

J'ai regardé, si j'utilise un micro casque, apparemment je n'ai pas le problème; c'est peut être un problème de retour de son.

Le fait qu'il repete "Salut mec" pour chaque mot doit provenir du faite que le souffle donne comme résultat "Dobro", il faudrait peut être inclure dans le dico un mot bateau pour que le souffle se dirige là dessus.

Sinon, tu peux toujours couper la reconnaissance et la remettre après, le problème, c'est qu'on ne sait pas combien de temps met la voix.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Speech Recognition Command (Reconnaissance vocale)

Message par Backup »

nico a écrit :J'ai regardé, si j'utilise un micro casque, apparemment je n'ai pas le problème; c'est peut être un problème de retour de son.
j'utilise aussi un microcasque ( de la marque SteelSeries fourni avec mon portable :) )
Sinon, tu peux toujours couper la reconnaissance et la remettre après, le problème, c'est qu'on ne sait pas combien de temps met la voix.
couper la reconnaissance ? ..
tu veux dire avec

Code : Tout sélectionner

Desactive_Recognition(*Speech_Recognition.Parametres, Valeur.l)
?
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Speech Recognition Command (Reconnaissance vocale)

Message par nico »

oui, c'est ça!
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Speech Recognition Command (Reconnaissance vocale)

Message par Backup »

j'ai trouvé :)

ça venais de la façon dont tu avait fait le Dico.xml :)

en fait il faut l'ecrire de cette façon :)
<?xml version="1.0" encoding="UTF-8"?>
<grammar version="1.0" xml:lang="fr-FR" mode="voice" tag-format="semantics-ms/1.0"
root="mouskie" xmlns="http://www.w3.org/2001/06/grammar">
<rule id="mouskie" scope="public">
<ruleref special="GARBAGE" />
<one-of>
<item>
invisible
<tag>$.mouskie={}; $.mouskie._value="invisible";</tag>
</item>
<item>
visible
<tag>$.mouskie={}; $.mouskie._value="visible";</tag>
</item>
<item>
dobro
<tag>$.mouskie={}; $.mouskie._value="dobro";</tag>
</item>
<item>
Fermer
<tag>$.mouskie={}; $.mouskie._value="QUIT";</tag>
</item>
</one-of>
<ruleref special="GARBAGE" />
</rule>
</grammar>

explications ici :
http://www.siteduzero.com/tutoriel-3-18 ... ation.html


le mode Garbage , force la reconnaissance vocale, sur SEULEMENT les termes entré dans le XMl

voici les explications du format xml :
Tout d'abord, il contient les en-têtes XML normales, puis une série d'informations sur la version de la grammaire, la langue, la règle racine (mouskie), la visibilité et le format des tags. Ensuite, les commandes vocales sont listées avec des informations particulières. Donc maintenant qu'est-ce que tout cela veut bien dire?

Le tag-format c'est la définition du format utilisé pour le texte contenu dans la balise tag. Cette balise tag est utilisée pour renvoyer des informations sémantiques à l'application. En gros au lieu de recevoir des phrases dans le style "Jean a mangé à 13h une pomme verte savoureuse." on aurait plutôt "Qui => Jean, Action => Manger, Nourriture => Pomme, Couleur => Verte". Bref, des informations beaucoup plus simples à interpréter dans un programme informatique.

La règle racine (mouskie dans ce cas) c'est là où le programme va entrer en premier. Cette règle contiendra toutes les commandes vocales et leur manière de fonctionner comme c'est le cas ici.

Le GARBAGE est une règle spéciale qui permet de dire "parle tant que tu veux, je n'écouterai pas avant que tu dises quelque chose que je peux comprendre". En gros, ici on peut voir que les textes a, b, Quitter et Fermer peuvent être reconnus. Cette règle permettrait de dire à l'application "J'aimerais bien QUITTER l'application maintenant" et la reconnaissance vocale se focaliserait sur le terme "QUITTER" qu'elle comprend. Le reste qui vient avant et après, elle ne connaît pas, alors elle jette.

Les termes reconnus sont comme dit juste avant a, b, Quitter et Fermer et toutes les phrases qui peuvent les contenir grâce au garbage. Ces termes qui peuvent être reconnus sont dans des balises one-of, et item. Le one-of permet de dire "Tu peux reconnaître UN de ces termes". Le item permet de définir un terme. A noter qu'un item peut contenir un one-of et ainsi de suite cela permet de faire de la construction de phrase.

La balise tag intimement liée au tag-format permet de renvoyer des commandes à l'application. Ici on peut voir que lorsque "Quitter" ou "Fermer" sont reconnus l'application recevra la commande "QUIT" en retour. Cette technique est pratique pour que plusieurs commandes entraînent la même action dans l'application. Bref, cela simplifie la programmation.
effectivement apres avoir donner a bouffer le Xml ci -dessu
le prg fait la difference entre le mot "dobro" dit tout seul , et dans ce cas , le synthetiseur répond
et la phrase "salut Dobro" , dans ce cas la reconnaissance affiche "... dobro" , et du coup le Case ne se vérifie plus , et donc la synthese ne dit rien :)

en clair on peut maintenant vraiment discriminer ce qu'on désire :)

pour que "salut dobro" soit reconnu , il faut faire

Code : Tout sélectionner

case "dobro","... dobro"
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Speech Recognition Command (Reconnaissance vocale)

Message par Backup »

voici un autre exemple :D
un dialogue :)

préalablement , il faut installer la voix virginie ( lien dans les messages ci dessus )

il faut ce xml "dico.xml"
<?xml version="1.0" encoding="UTF-8"?>
<grammar version="1.0" xml:lang="fr-FR" mode="voice" tag-format="semantics-ms/1.0"
root="mouskie" xmlns="http://www.w3.org/2001/06/grammar">
<rule id="mouskie" scope="public">
<ruleref special="GARBAGE" />
<one-of>
<item>
l'heure
<tag>$.mouskie={}; $.mouskie._value="l'heure";</tag>
</item>
<item>
météo
<tag>$.mouskie={}; $.mouskie._value="météo";</tag>
</item>
<item>
nono
<tag>$.mouskie={}; $.mouskie._value="dobro";</tag>
</item>
<item>
bye
<tag>$.mouskie={}; $.mouskie._value="bye";</tag>
</item>
<item>
merci
<tag>$.mouskie={}; $.mouskie._value="merci";</tag>
</item>
<item>
bidon
<tag>$.mouskie={}; $.mouskie._value="bidon";</tag>
</item>
</one-of>
<ruleref special="GARBAGE" />
</rule>
</grammar>
ce prg comprendra lorsque vous lui direz une phrase comprenant "nono"

genre : " Salut Nono.."
le prg va répondre ...

puis dites " tu peux me donner l'heure ? .."
le prg va répondre ...

dites "Merci"
le prg va répondre ...


puis "tu pourrai me donner la météo"
ou bien "c'est quoi la météo ?"

le prg va répondre ... :)

dites lui "bye.."

le prg va répondre ... :) et quitter


Code : Tout sélectionner


XIncludeFile "COMatePLUS.pbi"



;{ **************** init synthese Vocale ***************************************
;-init synthese vocale
Procedure Speak2(Text$)
	Interface ISpNotifySource Extends IUnknown
		SetNotifySink(a)
		SetNotifyWindowMessage(a,b,c,d)
		SetNotifyCallbackFunction(a,b,c)
		SetNotifyCallbackInterface(a,b,c)
		SetNotifyWin32Event()
		WaitForNotifyEvent(a)
		GetNotifyEventHandle()
	EndInterface
	
	Interface ISpEventSource Extends ISpNotifySource
		SetInterest(a,b)
		GetEvents(a,b,c)
		GetInfo(a)
	EndInterface
	
	Interface ISpVoice Extends ISpEventSource
		SetOutput(a,b)
		GetOutputObjectToken(a)
		GetOutputStream(a)
		Pause()
		Resume()
		SetVoice(a)
		GetVoice(a)
		Speak(a,b,c)
		SpeakStream(a,b,c)
		GetStatus(a,b)
		Skip(a,b,c)
		SetPriority(a)
		GetPriority(a)
		SetAlertBoundary(a)
		GetAlertBoundary(a)
		SetRate(a)
		GetRate(a)
		SetVolume(a)
		GetVolume(a)
		WaitUntilDone(a)
		SetSyncSpeakTimeout(a)
		GetSyncSpeakTimeout(a)
		SpeakCompleteEvent()
		IsUISupported(a,b,c,d)
		DisplayUI(a,b,c,d,e)
	EndInterface
	
	#CLSCTX_INPROC_SERVER  = $1
	#CLSCTX_INPROC_HANDLER = $2
	#CLSCTX_LOCAL_SERVER   = $4
	#CLSCTX_REMOTE_SERVER  = $10
	#CLSCTX_ALL = (#CLSCTX_INPROC_SERVER|#CLSCTX_INPROC_HANDLER|#CLSCTX_LOCAL_SERVER|#CLSCTX_REMOTE_SERVER)
	
	Global VoiceObject.ISpVoice
	
	
	
	length = Len(Text$)*2+10
	*mem = AllocateMemory(length)
	MultiByteToWideChar_(#CP_ACP ,0,Text$,-1,*mem, length)
	VoiceObject\Speak(*mem,0,0)
	
	DataSection
		CLSID_SpVoice:
		;96749377-3391-11D2-9EE3-00C04F797396
		Data.l $96749377
		Data.w $3391,$11D2
		Data.b $9E,$E3,$00,$C0,$4F,$79,$73,$96
		IID_ISpVoice:
		;6C44DF74-72B9-4992-A1EC-EF996E0422D4
		Data.l $6C44DF74
		Data.w $72B9,$4992
		Data.b $A1,$EC,$EF,$99,$6E,$04,$22,$D4
	EndDataSection
	
	
EndProcedure
;} 
; **********************************************************************




;{ ************ init reconnaissance Vocale **************************************************************
;-init reconaissance Vocale
#CLSCTX_INPROC_SERVER  = $1
#CLSCTX_INPROC_HANDLER = $2
#CLSCTX_LOCAL_SERVER   = $4
#CLSCTX_REMOTE_SERVER  = $10
#CLSCTX_ALL = (#CLSCTX_INPROC_SERVER|#CLSCTX_INPROC_HANDLER|#CLSCTX_LOCAL_SERVER|#CLSCTX_REMOTE_SERVER)
enumeration
	#window
endenumeration



Structure Parametres
	SpRecoContext.i
	SpeechRecoGrammar.i
EndStructure


;Global VoiceObject.ISpVoice


Declare  OpenWindow_Window_0()
Declare  SpeechRecoContextEvents(event.COMateObject, event$, parameterCount)
Declare  Load_Speech_Recognition(*Speech_Recognition.Parametres, File.s)
Declare  Load_Speech_Recognition2(*Speech_Recognition.Parametres)
Declare  Finish_Speech_Recognition(*Speech_Recognition.Parametres)
Declare  Desactive_Recognition(*Speech_Recognition.Parametres, Valeur.l)
Declare  speakk(voix,text.s,volume,vitesse)





CoInitialize_(0)

; **********  chargement du Dico ************************
File.s = "dico.xml"
If Load_Speech_Recognition(@Speech_Recognition.Parametres, File.s) = 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()
			
			
		EndSelect
		;/ ///////////////////////
		Case #PB_Event_CloseWindow
		Select EventWindow()
			Case #Window
			CloseWindow(#Window)
			Finish_Speech_Recognition(@Speech_Recognition.Parametres) ; arrete la reconaissance
			CoUninitialize_()
			Break
		EndSelect
	EndSelect
ForEver
End
;}


; **************** Zone des procedures ***********************************************************************
;- Les procedures
Procedure OpenWindow_Window_0()
	If OpenWindow(#Window, 732, 260, 600, 400, "Speech Recognition", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_TitleBar|#PB_Window_SizeGadget)
		
	EndIf
EndProcedure





;{ ******************** zone procedure Reconnaissance vocale ****************************************
;- procedure reconnaissance vocale
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) 


Procedure SpeechRecoContextEvents(event.COMateObject, event$, parameterCount)
	Protected iParam.iUnknown
	Protected SpeechRecoResult.COMateObject
	Protected SpeechPhraseInfo.COMateObject
	Protected Texte.s
	
	;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()")
				If SpeechPhraseInfo
					mem_text.s=texte.s ; on retient le mot qui viens d'etre reconnu
					
					Texte.s = SpeechPhraseInfo\GetStringProperty("GetText(0, -1, 1)")  ; on recupere le mot entendu
					
					if mem_text<>texte.s ; ajout du teste qui empeche la diction du meme mot reconnu ..; ajout du teste qui empeche la diction du meme mot reconnu ; on parle seulement si ce n'est pas le meme mot que tout a l'heure
						
						;SetGadgetText(#String, Texte)
						debug texte
						Select Texte
							case "bye"
							CoUninitialize_()
							text.s="Salut mon Coco"
							speakk(0,text.s,100,-3)
							End
							
							Case "l'heure","... l'heure" , "... l'heure ..."
							text.s="Attends, je regarde ça ....il est...."+str(Hour(Date()))+"...heures ..."+str(Minute(Date()))+"..minutes....et"+str(Second(Date()))+"..secondes"
							speakk(0,text.s,100,-3)
							;Speak("ScanSoft Virginie_Dri40_16kHz","Attends, je regarde ça ....il est...."+str(Hour(Date()))+"...heures ..."+str(Minute(Date()))+"..minutes....et"+str(Second(Date()))+"..secondes",100,-3,0)
							
							Case "météo";,"... météo","... météo ..."
							text.s="je ne suis pas une grenouille"
							speakk(0,text.s,100,-3)
							
							case "nono","... nono","... nono ..."
							text.s="Bonjour, comment vas tu ?..."
							speakk(0,text.s,100,-3)
							
							;Speak("ScanSoft Virginie_Dri40_16kHz","Bonjour, comment vas tu ?...",100,-3,0)
							case "merci", "... merci", "... merci ..."
							text.s="De rien..."
							speakk(0,text.s,100,-3)
							
							case "bidon"
							
						EndSelect
						Texte=" "
						
						SpeechPhraseInfo\Release()
					endif
				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"
		ProcedureReturn
	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
;}
; *****************************************************************************************************


;{ ************************** Zone des procedure Synthese Vocale ****************************************

procedure speakk(voix,text.s,volume,vitesse)
	If CoCreateInstance_(?CLSID_SpVoice, 0, #CLSCTX_ALL, ?IID_ISpVoice, @VoiceObject.ISpVoice) = 0
		VoiceObject\SetVolume(volume)
		VoiceObject\SetRate(vitesse)
		VoiceObject\SetVoice(voix) ; voix 0
		Speak2(text.s)    
		Else
		MessageRequester("ERROR","MS SPEECH API not installed",0)
	EndIf
	
endprocedure

;}
; ************************************************************************************************

; EPB

Dernière modification par Backup le lun. 11/juin/2012 11:22, modifié 4 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Speech Recognition Command (Reconnaissance vocale)

Message par Backup »

je viens de modifier le dernier code ci dessus

pour éviter une répétition du meme mot , c'est tout simple , il suffit d'ajouter un test :) .. je devais etre fatigué hier :lol:

Code : Tout sélectionner

mem_text.s=texte.s ; on retient le mot qui viens d'etre reconnu
               
               Texte.s = SpeechPhraseInfo\GetStringProperty("GetText(0, -1, 1)") ; on recupere le mot entendu
               
               if mem_text<>texte.s ; ajout du teste qui empeche la diction du meme mot reconnu ; on parle seulement si ce n'est pas le meme mot que tout a l'heure
Répondre