Seite 1 von 1

[MODULE] Text - Sprachausgabe

Verfasst: 02.04.2018 13:08
von Mijikai
Die Veröffentlichung von PB.Ex Speech (RSBasic) -> http://www.purebasic.fr/german/viewtopi ... 11&t=30692
hat mein Interesse geweckt.

Ich wollte wissen wie TextToSpeaker() funktioniert aber da es keinen
Sourcecode gab habe ich beschlossen es selbst zu versuchen.

Hier mein VOICE Module:

Code: Alles auswählen

DeclareModule VOICE
  Declare.i Init()
  Declare.i Voices()
  Declare.s GetVoiceName(Index.i)
  Declare.i SetVoice(Index.i)
  Declare.i Speak(Text.s,Volume.l,Rate.l,Async.b)
  Declare.i SpeakXML(Text.s,Volume.l,Rate.l,Async.b)
  Declare.i SpeakFile(File.s,Volume.l,Rate.l,Async.b)
  Declare.i SpeakFileXML(File.s,Volume.l,Rate.l,Async.b)
  Declare.i Release()
EndDeclareModule

Module VOICE
  
  ;VOICE MODULE by Mijikai
  ;PB v.5.62 x64 (Windows 10)
  ;v.alpha

  Interface ISpeechObjectToken Extends IDispatch
    Get_Id(*Output)
    Get_DataKey(*ISpeechDataKey)
    Get_Category(*ISpeechObjectTokenCategory)
    GetDescription(Locale.l,*Output)
    Set_Id(Id.s,CategoryID.s,CreateIfNotExist.i)
    GetAttribute(AttributeName.s,*Output)
    CreateInstance(*pUnkOuter,ClsContext.l,*IUnknown)
    Remove(ObjectStorageCLSID.s)
    GetStorageFileName(ObjectStorageCLSID.s,KeyName.s,FileName.s,Folder.l,*Output)
    RemoveStorageFileName(ObjectStorageCLSID.s,KeyName.s,DeleteFile.i)
    IsUISupported(TypeOfUI.s,*ExtraData,*IUnknown,*Output)
    DisplayUI(hWnd.l,Title.s,TypeOfUI.s,*ExtraData,*IUnknown)
    MatchesAttributes(Attributes.s,*Output)
  EndInterface
  
  Interface ISpeechObjectTokens Extends IDispatch
    Get_Count(*Output)
    Item(Index.l,*ISpeechObjectToken)
    Get_PropGet()
  EndInterface
  
  Interface ISpeechVoice Extends IDispatch
    Get_Status(*ISpeechVoiceStatus)
    Get_Voice(*ISpeechObjectToken)
    Set_Voice(*ISpeechObjectToken)
    Get_AudioOutput(*ISpeechObjectToken)
    Set_AudioOutput(*ISpeechObjectToken)
    Get_AudioOutputStream(*ISpeechBaseStream)
    Set_AudioOutputStream(*ISpeechBaseStream)
    Get_Rate(*Output)
    Set_Rate(Rate.l)
    Get_Volume(*Output)
    Set_Volume(Volume.l)
    Set_AllowAudioOutputFormatChangesOnNextSet(Allow.i)
    Get_AllowAudioOutputFormatChangesOnNextSet(*Output)
    Get_EventInterests()
    Set_EventInterests(EventInterestFlags.l)
    Set_Priority(Priority.l)
    Get_Priority(*Output)
    Set_AlertBoundary(Boundary.l)
    Get_AlertBoundary(*Output)
    Set_SynchronousSpeakTimeout(msTimeout.l)
    Get_SynchronousSpeakTimeout()
    Speak(Text.s,Flags.l,*Output)
    SpeakStream(*ISpeechBaseStream,Flags.l,*Output)
    Pause()
    Resume()
    Skip(Type.s,NumItems.l,*Output)
    GetVoices(RequiredAttributes.s,OptionalAttributes.s,*ISpeechObjectTokens)
    GetAudioOutputs(RequiredAttributes.s,OptionalAttributes.s,*ISpeechObjectTokens)
    WaitUntilDone(msTimeout.l,*Output)
    SpeakCompleteEvent(*Output)
    IsUISupported(TypeOfUI.s,*ExtraData,*Output)
    DisplayUI(hWndParent.l,Title.s,TypeOfUI.s,*ExtraData)
  EndInterface
  
  #SPF_ASYNC            = 1
  #SPF_IS_FILENAME      = 4
  #SPF_IS_XML           = 8
  #SPF_IS_NOT_XML       = 16
  
  Global *Speech.ISpeechVoice
  
  Procedure.i Init()
    Protected rclsid.CLSID
    Protected riid.CLSID
    Protected VirtualTable.i
    If Not *Speech
      If CoInitializeEx_(#Null,#Null) = #S_OK
        If CLSIDFromString_("{96749377-3391-11D2-9EE3-00C04F797396}",@rclsid) = #S_OK;CLSID_SpVoice  
          If IIDFromString_("{269316D8-57BD-11D2-9EEE-00C04F797396}",@riid) = #S_OK;IID_ISpeechVoice
            If CoCreateInstance_(@rclsid,#Null,#CLSCTX_INPROC_SERVER,@riid,@VirtualTable) = #S_OK
              *Speech = VirtualTable
              ProcedureReturn #True
            EndIf
          EndIf
        EndIf
        CoUninitialize_()
      EndIf
    Else
      ProcedureReturn #True
    EndIf
  EndProcedure
    
  Procedure.i Voices()
    Protected *Tokens.ISpeechObjectTokens
    Protected Count.i
    If *Speech
      If *Speech\GetVoices(#Null$,#Null$,@*Tokens) = #S_OK
        If *Tokens\Get_Count(@Count) = #S_OK 
          ProcedureReturn Count
        EndIf
        *Tokens\Release()
      EndIf
    EndIf
  EndProcedure
  
  Procedure.s GetVoiceName(Index.i)
    Protected *Tokens.ISpeechObjectTokens
    Protected Count.i
    Protected *Token.ISpeechObjectToken
    Protected Buffer.i
    Protected Name.s
    If *Speech
      If *Speech\GetVoices(#Null$,#Null$,@*Tokens) = #S_OK
        If *Tokens\Get_Count(@Count) = #S_OK 
          If Not Index > Count
            If *Tokens\Item(Index,@*Token) = #S_OK
              If *Token\GetDescription(#Null,@Buffer) = #S_OK
                Name = PeekS(Buffer)
                SysFreeString_(Buffer)
              EndIf
              *Token\Release()
            EndIf
          EndIf
        EndIf
        *Tokens\Release()
      EndIf
    EndIf
    ProcedureReturn Name
  EndProcedure
  
  Procedure.i SetVoice(Index.i)
    Protected *Tokens.ISpeechObjectTokens
    Protected Count.i
    Protected *Token.ISpeechObjectToken
    Protected Result.i
    If *Speech
      If *Speech\GetVoices(#Null$,#Null$,@*Tokens) = #S_OK
        If *Tokens\Get_Count(@Count) = #S_OK 
          If Not Index > Count
            If *Tokens\Item(Index,@*Token) = #S_OK
              If *Speech\Set_Voice(*Token) = #S_OK
                Result = #True
              EndIf
              *Token\Release()
            EndIf
          EndIf
        EndIf
        *Tokens\Release()
      EndIf
    EndIf
    ProcedureReturn Result
  EndProcedure
  
  Procedure.i Speak(Text.s,Volume.l,Rate.l,Async.b)
    Protected Result.i
    If *Speech
      *Speech\Set_Volume(Volume)
      *Speech\Set_Rate(Rate)
      If Async
        Result = *Speech\Speak(Text,#SPF_IS_NOT_XML|#SPF_ASYNC,#Null)
      Else
        Result = *Speech\Speak(Text,#SPF_IS_NOT_XML,#Null)
      EndIf
    EndIf
    ProcedureReturn Bool(Result = #S_OK)
  EndProcedure
  
  Procedure.i SpeakXML(Text.s,Volume.l,Rate.l,Async.b)
    Protected Result.i
    If *Speech
      *Speech\Set_Volume(Volume)
      *Speech\Set_Rate(Rate)
      If Async
        Result = *Speech\Speak(Text,#SPF_IS_XML|#SPF_ASYNC,#Null)
      Else
        Result = *Speech\Speak(Text,#SPF_IS_XML,#Null)
      EndIf
    EndIf
    ProcedureReturn Bool(Result = #S_OK)
  EndProcedure
  
  Procedure.i SpeakFile(File.s,Volume.l,Rate.l,Async.b)
    Protected Result.i
    If *Speech
      *Speech\Set_Volume(Volume)
      *Speech\Set_Rate(Rate)
      If Async
        Result = *Speech\Speak(File,#SPF_IS_NOT_XML|#SPF_IS_FILENAME|#SPF_ASYNC,#Null)
      Else
        Result = *Speech\Speak(File,#SPF_IS_NOT_XML|#SPF_IS_FILENAME,#Null)
      EndIf
    EndIf
    ProcedureReturn Bool(Result = #S_OK)
  EndProcedure
  
  Procedure.i SpeakFileXML(File.s,Volume.l,Rate.l,Async.b)
    Protected Result.i
    If *Speech
      *Speech\Set_Volume(Volume)
      *Speech\Set_Rate(Rate)
      If Async
        Result = *Speech\Speak(File,#SPF_IS_XML|#SPF_IS_FILENAME|#SPF_ASYNC,#Null)
      Else
        Result = *Speech\Speak(File,#SPF_IS_XML|#SPF_IS_FILENAME,#Null)
      EndIf
    EndIf
    ProcedureReturn Bool(Result = #S_OK)
  EndProcedure
  
  Procedure.i Release()
    If *Speech
      *Speech\Release()
      *Speech = #Null
      CoUninitialize_()
    EndIf
  EndProcedure
  
EndModule

Global Index.i

If VOICE::Init()
  
  For Index = 0 To VOICE::Voices() - 1
    Debug VOICE::GetVoiceName(Index)
    If Index = 1
      VOICE::SetVoice(Index)
    EndIf
  Next
    
  Debug VOICE::SpeakXML("This sounds normal <pitch middle = '-80'/> but the pitch drops half way through",100,0,#True)
  Debug VOICE::Speak("take some notice here i speak",100,0,#False)
  
  VOICE::Release()
EndIf
Viel Spass :)

Re: [MODULE] Text - Sprachausgabe

Verfasst: 02.04.2018 13:16
von Bisonte
:allright:

Klingt lustig, wenn die deutsche Stimme den englischen Text vorliest :mrgreen:

Re: [MODULE] Text - Sprachausgabe

Verfasst: 02.04.2018 13:22
von RSBasic
:allright:

Re: [MODULE] Text - Sprachausgabe

Verfasst: 02.04.2018 13:52
von mk-soft
Geht es nicht für alles OS?

Code: Alles auswählen

Global SpeechSynthesizer = CocoaMessage(0, CocoaMessage(0, 0, "NSSpeechSynthesizer alloc"), "initWithVoice:", #nil)
Global voice.s = "com.apple.speech.synthesis.voice.anna"

CocoaMessage(0, SpeechSynthesizer, "setVoice:$", @voice)
CocoaMessage(0, SpeechSynthesizer, "startSpeakingString:$", @"Es muss nicht immer nur für windows sein")
If OpenWindow(0, 0, 0, 200, 30, "Hallo", #PB_Window_SystemMenu | #PB_Window_Minimize | #PB_Window_NoActivate)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: [MODULE] Text - Sprachausgabe

Verfasst: 02.04.2018 13:55
von RSBasic
Jetzt nur noch Linux. :mrgreen:
ccode_new hat geschrieben:

Code: Alles auswählen

;Sprachausgabe unter Linux (Test)

text.s = Chr(34)+"Ich bin eine Computerstimme."+Chr(34)
prog = RunProgram("espeak", "-v de -a 120 -p 20 -s 120 "+text , GetCurrentDirectory(), #PB_Program_Wait)
Es gibt bestimmt dort auch ne API-Schnittstelle.

Re: [MODULE] Text - Sprachausgabe

Verfasst: 02.04.2018 16:29
von ccode_new
Hallo!

Plattformunabhängig über SpiderBasic:

Code: Alles auswählen

EnableJS
var hallo = new SpeechSynthesisUtterance("Ich bin eine Computerstimme");
hallo.lang = "de-DE";
hallo.rate = 0.5;
hallo.pitch = 3;
window.speechSynthesis.speak(hallo);
DisableJS
;Es kommt halt auf dem verwendeten Browser an.

Sprachausgabe ist die einfachere Sache, aber Spracheingabe wird (vor allem unter Linux) recht komplex und kompliziert.

->Die beste Lösung für Spracheingabe könnte sein:

Ein Hinweis das sie bitte Google Chrome installieren sollen und ihre Internetverbindung aktivieren. (Verwendung von Google Chrome)
Oder Verwendung einer (Android-)App (mit Spracherkennungsdienst) auf einem Smartphone das als Vermittlungsprogramm dient.

Re: [MODULE] Text - Sprachausgabe

Verfasst: 02.04.2018 16:34
von RSBasic
ccode_new hat geschrieben:Platformunabhängig
Naja, nicht ganz: https://caniuse.com/#search=speechsynthesisutterance
IE 11 wird nicht unterstützt.
Und Edge gibts erst ab Windows 10.

Re: [MODULE] Text - Sprachausgabe

Verfasst: 02.04.2018 17:40
von ccode_new
Es gibt bestimmt dort auch ne API-Schnittstelle.
Wer möchte kann sich damit gerne auseinandersetzen:

http://espeak.sourceforge.net/speak_lib.h.