synthèse vocale SAPI ne marche pas en 64 bits?

Programmation d'applications complexes
morosh
Messages : 18
Inscription : jeu. 22/sept./2011 6:01
Localisation : Liban

synthèse vocale SAPI ne marche pas en 64 bits?

Message par morosh »

Bonjour:
J'ai récupéré ce programme du forum et j'ai remarqué que la synthèse vocale SAPI, voix française ne marche pas en mode x64, Par contre ça marche bien en mode x86. La voix anglaise marche bien en x64 et en x86. Quelqu'un a déjà rencontré ça? y-a-t'il un remède?
J'utilise PB6-beta3 (normal non backend-C), et comme voix française j'ai "ScanSoft Virginie_Dri40_16kHz" installée

Merci d'avance

Code : Tout sélectionner

Global VoiceList.s

Import "ole32.lib"
   CoInitialize(reserved.l = #Null)
   CoUninitialize()
   CLSIDFromProgID(ProgID.p-bstr, *clsid.CLSID)
   CLSIDFromString(String.p-bstr, *clsid.CLSID)
EndImport

#CLSCTX_INPROC_SERVER = 1
Enumeration 0 ; SpeechVoiceSpeakFlags
   #SVSFDefault          = 0
   #SVSFlagsAsync        = 1
   #SVSFPurgeBeforeSpeak = 2
   #SVSFIsFilename       = 4
   #SVSFIsXML            = 8
   #SVSFIsNotXML         = 16
   #SVSFPersistXML       = 32
   #SVSFNLPSpeakPunc     = 64
   #SVSFNLPMask          = 64
   #SVSFVoiceMask        = 127
   #SVSFUnusedFlags      = -128
EndEnumeration

Interface ISpeechVoice Extends IDispatch
   get_Status(*ISpeechVoiceStatus.l)
   get_Voice(*ISpeechObjectToken.l)
   put_Voice(*ISpeechObjectToken.l)
   get_AudioOutput(*ISpeechObjectToken.l)
   put_AudioOutput(*ISpeechObjectToken.l)
   get_AudioOutputStream(*ISpeechBaseStream.l)
   put_AudioOutputStream(*ISpeechBaseStream.l)
   get_Rate(long.l)
   put_Rate(long.l)
   get_Volume(long.l)
   put_Volume(long.l)
   put_AllowAudioOutputFormatChangesOnNextSet(VARIANT_BOOL.l)
   get_AllowAudioOutputFormatChangesOnNextSet(VARIANT_BOOL.l)
   get_EventInterests(SpeechVoiceEvents.l)
   put_EventInterests(SpeechVoiceEvents.l)
   put_Priority(SpeechVoicePriority.l)
   get_Priority(SpeechVoicePriority.l)
   put_AlertBoundary(SpeechVoiceEvents.l)
   get_AlertBoundary(SpeechVoiceEvents.l)
   put_SynchronousSpeakTimeout(long.l)
   SynchronousSpeakTimeout(long.l)
   Speak(Text.p-bstr, SpeechVoiceSpeakFlags.l, long.l)
   SpeakStream(*ISpeechBaseStream, SpeechVoiceSpeakFlags.l, long.l)
   Pause()
   Resume()
   Skip(*Type, NumItems.l, long.l)
   GetVoices(*RequiredAttributes.l, *OptionalAttributes, *ISpeechObjectTokens.l)
   GetAudioOutputs(*RequiredAttributes, *OptionalAttributes, *ISpeechObjectTokens.l)
   WaitUntilDone(msTimeout.l, VARIANT_BOOL.l)
   SpeakCompleteEvent(long.l)
   IsUISupported(*TypeOfUI, *ExtraData.VARIANT, VARIANT_BOOL.l)
   DisplayUI(hWndParent.l, *Title, *TypeOfUI, *ExtraData.VARIANT)
EndInterface
Interface ISpeechObjectToken Extends IDispatch
   get_Id(ObjectId)
   get_DataKey(ISpeechDataKey.l)
   get_Category(ISpeechObjectTokenCategory.l)
   GetDescription(Locale.l, Description)
   SetId(id, CategoryID, CreateIfNotExist)
   GetAttribute(AttributeName.p-bstr, *AttributeValue)
   CreateInstance(pUnkOuter, SpeechTokenContext, Object)
   Remove(ObjectStorageCLSID)
   GetStorageFileName(ObjectStorageCLSID, KeyName, FileName, SpeechTokenShellFolder, *FilePath)
   RemoveStorageFileName(ObjectStorageCLSID, KeyName, DeleteFile)
   IsUISupported(TypeOfUI, *ExtraData, *Object, *Supported)
   DisplayUI(hwnd, Title, TypeOfUI, *ExtraData, *Object)
   MatchesAttributes(Attributes, *Matches)
EndInterface
Interface ISpeechObjectTokens Extends IDispatch
   get_Count(a.l)
   Item(Index.l, Token.ISpeechObjectToken)
   get__NewEnum(ppEnumVARIANT.IUnknown )
EndInterface

Procedure.l Speak(*SpeechVoice.ISpeechVoice, *SpeechObjectTokens.ISpeechObjectTokens, Text.s, Rate.l = 0, Voice.l = 0,Volume=100)
   Protected flag.l = #SVSFDefault, Token.ISpeechObjectToken
   If *SpeechObjectTokens\Item(Voice, @Token) = #S_OK
*SpeechVoice\put_Volume(volume)
      *SpeechVoice\put_Voice(Token)
      *SpeechVoice\put_Rate(Rate)
      *SpeechVoice\Speak(Text, 0, @flag)
   EndIf
EndProcedure
;
ProcedureDLL.s  GetWoix( )
  Define clsid.CLSID, Refiid.CLSID, SpeechVoice.ISpeechVoice, SpeechObjectTokens.ISpeechObjectTokens
  Define Count.l, i.l, Token.ISpeechObjectToken, Description.l, AttributeValue.l
  If CLSIDFromProgID("SAPI.SpVoice", @clsid.CLSID) = #S_OK
      If CLSIDFromString("{269316D8-57BD-11D2-9EEE-00C04F797396}", @Refiid.CLSID) = #S_OK
         CoInitialize()
         If  CoCreateInstance_(clsid, #Null, #CLSCTX_INPROC_SERVER, Refiid, @SpeechVoice.ISpeechVoice) = #S_OK       
            SpeechVoice\GetVoices(0, 0, @SpeechObjectTokens.ISpeechObjectTokens)
            SpeechObjectTokens\get_Count(@Count)
            VoiceList.s = ""
            VoiceList =Str(count)+","
            For i = 0 To Count - 1
               SpeechObjectTokens\Item(i, @Token.ISpeechObjectToken)
               Token\GetDescription(0, @Description)
               Token\GetAttribute("Language", @AttributeValue)
               VoiceList+ PeekS(Description, -1, #PB_Unicode) + ","
               ;;;;;;;VoiceList + "Voice[" + Str(i) + "].Language = " + PeekS(AttributeValue, -1, #PB_Unicode) + #LF$
               Token\Release()
            Next i
            SpeechObjectTokens\Release()
            SpeechVoice\Release()
         EndIf
         CoUninitialize()
      EndIf
   EndIf
   ProcedureReturn VoiceList.s
EndProcedure

ProcedureDLL Speak2(voix$,text$,volume=100,Vitesse=0,Pitch=0)
  Define vox.s, clsid.CLSID, Refiid.CLSID, SpeechVoice.ISpeechVoice, SpeechObjectTokens.ISpeechObjectTokens
  Define Count.l
   If voix$<>""
      vox.s="<voice required="+Chr(34)+"Name="+ voix$+Chr(34)+"/>"+"<pitch absmiddle="+Chr(34)+Str(pitch)+Chr(34)+"/>"
      Else
      vox.s=""
   EndIf
   If CLSIDFromProgID("SAPI.SpVoice", @clsid.CLSID) = #S_OK
      If CLSIDFromString("{269316D8-57BD-11D2-9EEE-00C04F797396}", @Refiid.CLSID) = #S_OK
         CoInitialize()
         If  CoCreateInstance_(clsid, #Null, #CLSCTX_INPROC_SERVER, Refiid, @SpeechVoice.ISpeechVoice) = #S_OK   
            SpeechVoice\GetVoices(0, 0, @SpeechObjectTokens.ISpeechObjectTokens)
            SpeechObjectTokens\get_Count(@Count)
            Speak(SpeechVoice, SpeechObjectTokens, vox.s+text$, vitesse, 0,volume)
            SpeechObjectTokens\Release()
            SpeechVoice\Release()
         EndIf
         CoUninitialize()
      EndIf
   EndIf
 EndProcedure

voix$=GetWoix( ) ; on recupere le nombre et le nom des voix installé  ////////  Grab Voices on systeme
; getvoix() retourne une chaine "nbr_de_voix,voix1$,voix2$,voix3$........ etc "

nombre = Val(StringField(voix$,1,",")) ; recupere le nombre de voix installé (premier element de la chaine) ; //// number voices on system
voix$=Right(voix$,Len(voix$)-2) ; on retire le nombre de voix, et sa virgule de la liste des noms de voix

Debug " List Of Voices "
For i=1 To nombre ;
   Debug StringField(voix$,i,",") ; ressort tout les noms des voix installées ////////// print name of voices
Next i
Speak2( "ScanSoft Virginie_Dri40_16kHz" , "Bonjour" , 100, -1, 150)
Speak2( "Microsoft David Desktop" , "hello" , 100, -2, 150)
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: synthèse vocale SAPI ne marche pas en 64 bits?

Message par Ar-S »

J'utilise celui ci depuis des lustres. Il fonctionne en x64
Testé sous W11 x64 avec PB5.73 x64 avec Hotense, la voix par défaut de W10/11

Code : Tout sélectionner

; exécuter
; pour x32 > "C:\Windows\System32\Speech\SpeechUX\sapi.cpl"
; pour x64 > "C:\Windows\SysWOW64\Speech\SpeechUX\sapi.cpl"
; et à "sélection de la voix qui vous intéresse" .

;************************************************************************************
; Ce code à été écrit par Sapero avec le language Aurora Compiler
; Traduit en Purebasic par Nico et modifié par GallyHC et Ar-s.
; ****************************************************************************
; ****************************************************************************

; ****************************************************************************
; ****************************************************************************
; VALEUR POUR "SpeechVoiceSpeakFlags".
Enumeration
  #SVSFDefault            = 0
  #SVSFlagsAsync          = 1
  #SVSFPurgeBeforeSpeak   = 2
  #SVSFIsFilename         = 4
  #SVSFIsXML              = 8
  #SVSFIsNotXML           = 16
  #SVSFPersistXML         = 32
  #SVSFNLPSpeakPunc       = 64
  #SVSFNLPMask            = 64
  #SVSFVoiceMask          = 127
  #SVSFUnusedFlags        = -128
EndEnumeration
Enumeration
  #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)
EndEnumeration
; ****************************************************************************
; ****************************************************************************
Interface ISpeechVoice Extends IDispatch
  get_Status(*ISpeechVoiceStatus .l)
  get_Voice(*ISpeechObjectToken.l)
  put_Voice(*ISpeechObjectToken.l)
  get_AudioOutput(*ISpeechObjectToken.l)
  put_AudioOutput(*ISpeechObjectToken.l)
  get_AudioOutputStream(*ISpeechBaseStream.l)
  put_AudioOutputStream(*ISpeechBaseStream.l)
  get_Rate(long.l)
  put_Rate(long.l)
  get_Volume(long.l)
  put_Volume(long.l)
  put_AllowAudioOutputFormatChangesOnNextSet(VARIANT_BOOL.l)
  get_AllowAudioOutputFormatChangesOnNextSet(VARIANT_BOOL.l)
  get_EventInterests(SpeechVoiceEvents .l)
  put_EventInterests(SpeechVoiceEvents .l)
  put_Priority(SpeechVoicePriority.l)
  get_Priority(SpeechVoicePriority.l)
  put_AlertBoundary(SpeechVoiceEvents.l)
  get_AlertBoundary(SpeechVoiceEvents.l)
  put_SynchronousSpeakTimeout(long.l)
  SynchronousSpeakTimeout(long.l)
  Speak(*Text, SpeechVoiceSpeakFlags.l, long.l)
  SpeakStream(*ISpeechBaseStream, SpeechVoiceSpeakFlags.l, long.l)
  Pause()
  Resume()
  Skip(*Type, NumItems.l, long.l)
  GetVoices(*RequiredAttributes.l, *OptionalAttributes, *ISpeechObjectTokens.l)
  GetAudioOutputs(*RequiredAttributes, *OptionalAttributes, *ISpeechObjectTokens.l)
  WaitUntilDone(msTimeout.l, VARIANT_BOOL.l)
  SpeakCompleteEvent(long.l)
  IsUISupported(*TypeOfUI, *ExtraData.VARIANT, VARIANT_BOOL.l)
  DisplayUI(hWndParent.l, *Title, *TypeOfUI, *ExtraData.VARIANT)
EndInterface 
; ****************************************************************************
; ****************************************************************************
Procedure.b isSAPIInstalled()
; VERIFICATION DE L'INSTALLATION DE SAPI 4 OU 5.
  Define a.i
  Define bresult.b = #False
  CoInitialize_(0)
  If CoCreateInstance_(?CLSID_SpVoice, 0, #CLSCTX_ALL, ?IID_ISpVoice, @a) = 0
         bresult = #True 
  Else
    If CoCreateInstance_(?CLSID_ITextToSpeech, 0, #CLSCTX_ALL, ?IID_ITextToSpeech, @a) = 0
      bresult = #True
      
      ;---********************************
      
      ;---**********
      
      
    EndIf
  EndIf
  CoUninitialize_()
  ProcedureReturn bresult 
  
EndProcedure
; ****************************************************************************
; ****************************************************************************
Procedure SAPISpeechtext(stext.s, speed=0)
  ;
   
  
  Define.i itemp, bstrtext
  Define text1.s
  Define *buffer1, *buffer2, *buffer3 
  Define clsid.CLSID, refiid.CLSID
  Define speechvoice.ISpeechVoice

  
  If isSAPIInstalled() = #True And stext <> #Null$
    text1 = "SAPI.SpVoice"
    *buffer1 = AllocateMemory((Len(text1) + 1) * 2)
    PokeS(*buffer1, text1, -1, #PB_Unicode)
    text1 = "{269316D8-57BD-11D2-9EEE-00C04F797396}"
    *buffer2 = AllocateMemory((Len(text1) + 1) * 2)
    PokeS(*buffer2, text1, -1, #PB_Unicode)
    If CLSIDFromProgID_(*buffer1, @Clsid.clsid)    = #S_OK
      If CLSIDFromString_(*buffer2, @Refiid.clsid) = #S_OK
        CoInitialize_(0)
        If  CoCreateInstance_(clsid, #Null, #CLSCTX_INPROC_SERVER, refiid, @speechvoice) = #S_OK
          *buffer3 = AllocateMemory((Len(stext) + 1) * 2)
          PokeS(*buffer3, stext, -1, #PB_Unicode)
          itemp    = #SVSFDefault
          bstrtext = SysAllocString_(*buffer3)
          ;
          ; EXEMPLE DE QUELQUES PARAMATRES.
          ;
          speechvoice\put_Rate(Speed)
          speechvoice\put_Volume(100)
          ;
          ; EXEMPLE DE QUELQUES PARAMATRES.
          ;
          speechvoice\Speak(bstrtext, 0, @itemp)
          SysFreeString_(bstrtext)
          FreeMemory(*buffer3)
          speechvoice\Release()
        EndIf
        CoUninitialize_()
      EndIf
    EndIf
    FreeMemory(*buffer1)
    FreeMemory(*buffer2)
    
  EndIf
  
EndProcedure
; ************************************************************************************************
 
 
 ; ================ EXECUTION DU PROGRAMME ======================
 
 
 SAPISpeechtext("Je fonctionne trés bien en x64",0)
 

  
; ****************************************************************************
; ****************************************************************************
DataSection
  CLSID_SpVoice:
    Data.l $96749377
    Data.w $3391,$11D2
    Data.b $9E,$E3,$00,$C0,$4F,$79,$73,$96
  IID_ISpVoice:
    Data.l $269316D8
    Data.w $57BD,$11D2
    Data.b $9E,$EE,$00,$C0,$4F,$79,$73,$96
  CLSID_ITextToSpeech:
    Data.l $EEE78591
    Data.w $FE22,$11D0
    Data.b $8B,$EF,$00,$60,$08,$18,$41,$DE
  IID_ITextToSpeech:
    Data.l $EEE78590
    Data.w $FE22,$11D0
    Data.b $8B,$EF,$00,$60,$08,$18,$41,$DE
  EndDataSection
  
 
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
morosh
Messages : 18
Inscription : jeu. 22/sept./2011 6:01
Localisation : Liban

Re: synthèse vocale SAPI ne marche pas en 64 bits?

Message par morosh »

Merci pour votre réponse
je vais l'essayer, mais je cherche une solution qui me permet d'annoncer en anglais et en français comme c'est le cas avec le code précédent.
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: synthèse vocale SAPI ne marche pas en 64 bits?

Message par Ar-S »

Virginie n'est listée qu'en x64
Il faut dans le registre, copier le contenu de
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Speech\Voices\Tokens]
dans
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens]
alors la cle d'origine de virgine dans le syswow6432node

Windows Registry Editor Version 5.00

Code : Tout sélectionner

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Speech\Voices\Tokens\ScanSoftVirginie_Dri40_16kHz]
@="ScanSoft Virginie_Dri40_16kHz"
"LangCode"="FRF"
"40C"="ScanSoft Virginie_Dri40_16kHz"
"CLSID"="{CAC6785B-655E-4ae1-A656-BDEFD18DC46C}"
"VoiceData"="C:\\Program Files (x86)\\ScanSoft\\RealSpeakSolov4\\speech\\components\\data\\Virginie.dat"
"VoiceName"="Virginie"
"Reduction"="DRI40"
"Encoding"="112mrf16"
"Frequency"="16"
"Language"="French"
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Speech\Voices\Tokens\ScanSoftVirginie_Dri40_16kHz\attributes]
"Language"="40C"
"Name"="ScanSoft Virginie_Dri40_16kHz"
"Vendor"="ScanSoft, Inc"
"Gender"="Female"
et la cle ou elle doit se trouver pour l'avoir dans la liste par la chemin normal

Windows Registry Editor Version 5.00

Code : Tout sélectionner

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\ScanSoftVirginie_Dri40_16kHz]
@="ScanSoft Virginie_Dri40_16kHz"
"LangCode"="FRF"
"40C"="ScanSoft Virginie_Dri40_16kHz"
"CLSID"="{CAC6785B-655E-4ae1-A656-BDEFD18DC46C}"
"VoiceData"="C:\\Program Files (x86)\\ScanSoft\\RealSpeakSolov4\\speech\\components\\data\\Virginie.dat"
"VoiceName"="Virginie"
"Reduction"="DRI40"
"Encoding"="112mrf16"
"Frequency"="16"
"Language"="French"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\ScanSoftVirginie_Dri40_16kHz\attributes]
"Language"="40C"
"Name"="ScanSoft Virginie_Dri40_16kHz"
"Vendor"="ScanSoft, Inc"
"Gender"="Female"
J'ai trouvé ça ici : https://www.developpez.net/forums/d1463 ... ncais-vba/
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
morosh
Messages : 18
Inscription : jeu. 22/sept./2011 6:01
Localisation : Liban

Re: synthèse vocale SAPI ne marche pas en 64 bits?

Message par morosh »

Merci, je vais l'essayer
morosh
Messages : 18
Inscription : jeu. 22/sept./2011 6:01
Localisation : Liban

Re: synthèse vocale SAPI ne marche pas en 64 bits?

Message par morosh »

Bonjour:
Dans W10--> Settings --> Speech j'ai installé les voies françaises "Microsoft Julie" et "Microsoft Paul" , mais je ne les vois pas en lançant:
"C:\Windows\SysWOW64\Speech\SpeechUX\sapi.cpl"
et parsuite je ne peux pas les utiliser.

auriez-vous une idée pourquoi ça ne marche pas

Merci
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: synthèse vocale SAPI ne marche pas en 64 bits?

Message par Ar-S »

Effectivement.
En farfouillant dans le registre, on voit que Julie et Paul sont présente ici :

Code : Tout sélectionner

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens
En revanche, elles ne sont pas présente ici :

Code : Tout sélectionner

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens
Peut être faut-il copier la clé à cette endroit.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
morosh
Messages : 18
Inscription : jeu. 22/sept./2011 6:01
Localisation : Liban

Re: synthèse vocale SAPI ne marche pas en 64 bits?

Message par morosh »

après une petite recherche, j'ai tombé sur cette archive: http://www.cross-plus-a.com/mobile.windows10.zip
qui contient des fichiers .reg pour installer les voix dans la base de registres.
Mais voilà, lançant "C:\Windows\SysWOW64\Speech\SpeechUX\sapi.cpl", je vois les voix julie et paul installés, mais en lançant votre code posté plus haut, j'ai toujours la voix de Microsoft David en anglais.

Curieux, non?
Répondre