Page 1 of 3

PB.Ex Speech (Windows)

Posted: Sat Mar 10, 2018 10:59 pm
by RSBasic
Hello,

with this library you can use speech recognition (speak -> text) and speech output (text -> speak).
Speech recognition allows you to speak defined words that can be recognized and evaluated by the program. For example, when you speak the word "Basic" an event is triggered and you can react to it.
With the voice output, a text can be read out by the computer voice or stored in an audio file.

Note: I could not test the English speech output, but only the German one.

Functions:
  • TextToSpeaker()
    • Syntax:

      Code: Select all

      Result = TextToSpeaker(Text$, Voice$, Speed, Volume, Asynchronous, @ErrorOutput)
    • Description: Specified text is read by the computer voice.
    • Parameter:
      1. Text$: Text to be read out.
      2. Voice$: When multiple voices are installed on the computer, a specific voice can be set. If "" is specified, the default voice is used.
      3. Speed: Sets the speech speed (-10 (very slow) to 10 (very fast)).
      4. Volume: Sets the volume (0-100).
      5. Asynchronous: If 1 is specified, the program does not wait until the text has been read out completely, but the text is read out in the background.
      6. @ErrorOutput: If an error occurs, the error message is stored in the string variable.
    • Return value:
      • 0: The process was successful.
    • Example:

      Code: Select all

      EnableExplicit
      
      Global PBEx_Speech
      
      CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
        PBEx_Speech = OpenLibrary(#PB_Any, "PB.Ex_Speech_x86.dll")
      CompilerElseIf #PB_Compiler_Processor = #PB_Processor_x64
        PBEx_Speech = OpenLibrary(#PB_Any, "PB.Ex_Speech_x64.dll")
      CompilerEndIf
      
      If PBEx_Speech
        Prototype TextToSpeaker(Text.p-Unicode, Voice.p-Unicode, Speed, Volume, Asynchronous, ErrorOutput)
        Global TextToSpeaker.TextToSpeaker = GetFunction(PBEx_Speech, "TextToSpeaker")
        Prototype TextToAudioFile(Text.p-Unicode, Voice.p-Unicode, Speed, Volume, SaveFilePath.p-Unicode, ErrorOutput)
        Global TextToAudioFile.TextToAudioFile = GetFunction(PBEx_Speech, "TextToAudioFile")
        Prototype SpeechRecognition(WordArray, WordArraySize, ErrorOutput)
        Global SpeechRecognition.SpeechRecognition = GetFunction(PBEx_Speech, "SpeechRecognition")
        Prototype WaitSpeechRecognition(RecognizedWord)
        Global WaitSpeechRecognition.WaitSpeechRecognition = GetFunction(PBEx_Speech, "WaitSpeechRecognition")
        Prototype KillSpeechRecognition()
        Global KillSpeechRecognition.KillSpeechRecognition = GetFunction(PBEx_Speech, "KillSpeechRecognition")
        
        Define ErrorOutput$ = Space(1024)
        If TextToSpeaker("Hello PureBasic friends", "", 1, 100, 0, @ErrorOutput$) <> 0
          Debug ErrorOutput$
        EndIf
        
        CloseLibrary(PBEx_Speech)
      EndIf
  • TextToAudioFile()
    • Syntax:

      Code: Select all

      Result = TextToAudioFile(Text$, Voice$, Speed, Volume, SaveFilePath$, @ErrorOutput)
    • Description: The speech output of the text is stored in the specified audio file (Wave).
    • Parameter:
      1. Text$: Text to be read out.
      2. Voice$: When multiple voices are installed on the computer, a specific voice can be set. If "" is specified, the default voice is used.
      3. Speed: Sets the speech speed (-10 (very slow) to 10 (very fast)).
      4. Volume: Sets the volume (0-100).
      5. SaveFilePath$: Sets the location of the audio file.
      6. @ErrorOutput: If an error occurs, the error message is stored in the string variable.
    • Return value:
      • 0: The process was successful.
    • Example:

      Code: Select all

      EnableExplicit
      
      Global PBEx_Speech
      
      CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
        PBEx_Speech = OpenLibrary(#PB_Any, "PB.Ex_Speech_x86.dll")
      CompilerElseIf #PB_Compiler_Processor = #PB_Processor_x64
        PBEx_Speech = OpenLibrary(#PB_Any, "PB.Ex_Speech_x64.dll")
      CompilerEndIf
      
      If PBEx_Speech
        Prototype TextToSpeaker(Text.p-Unicode, Voice.p-Unicode, Speed, Volume, Asynchronous, ErrorOutput)
        Global TextToSpeaker.TextToSpeaker = GetFunction(PBEx_Speech, "TextToSpeaker")
        Prototype TextToAudioFile(Text.p-Unicode, Voice.p-Unicode, Speed, Volume, SaveFilePath.p-Unicode, ErrorOutput)
        Global TextToAudioFile.TextToAudioFile = GetFunction(PBEx_Speech, "TextToAudioFile")
        Prototype SpeechRecognition(WordArray, WordArraySize, ErrorOutput)
        Global SpeechRecognition.SpeechRecognition = GetFunction(PBEx_Speech, "SpeechRecognition")
        Prototype WaitSpeechRecognition(RecognizedWord)
        Global WaitSpeechRecognition.WaitSpeechRecognition = GetFunction(PBEx_Speech, "WaitSpeechRecognition")
        Prototype KillSpeechRecognition()
        Global KillSpeechRecognition.KillSpeechRecognition = GetFunction(PBEx_Speech, "KillSpeechRecognition")
        
        Define ErrorOutput$ = Space(1024)
        If TextToAudioFile("Hello PureBasic friends", "", 1, 100, "D:\AudioText.wav", @ErrorOutput$) <> 0
          Debug ErrorOutput$
        EndIf
        
        CloseLibrary(PBEx_Speech)
      EndIf
  • SpeechRecognition()
    • Syntax:

      Code: Select all

      Result = SpeechRecognition(WordArray, WordArraySize, @ErrorOutput)
    • Description: Detects the specified words when speaking and returns an event to the WaitSpeechRecognition() function.
    • Parameter:
      1. WordArray: A string array of words to be recognized. If 0 is passed, then any words are recognized.
      2. WordArraySize: Number of elements. If 0 is passed, then any words are recognized.
      3. @ErrorOutput: If an error occurs, the error message is stored in the string variable.
    • Return value:
      • 0: The process was successful.
    • Example:

      Code: Select all

      EnableExplicit
      
      Global PBEx_Speech
      
      CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
        PBEx_Speech = OpenLibrary(#PB_Any, "PB.Ex_Speech_x86.dll")
      CompilerElseIf #PB_Compiler_Processor = #PB_Processor_x64
        PBEx_Speech = OpenLibrary(#PB_Any, "PB.Ex_Speech_x64.dll")
      CompilerEndIf
      
      If PBEx_Speech
        Prototype TextToSpeaker(Text.p-Unicode, Voice.p-Unicode, Speed, Volume, Asynchronous, ErrorOutput)
        Global TextToSpeaker.TextToSpeaker = GetFunction(PBEx_Speech, "TextToSpeaker")
        Prototype TextToAudioFile(Text.p-Unicode, Voice.p-Unicode, Speed, Volume, SaveFilePath.p-Unicode, ErrorOutput)
        Global TextToAudioFile.TextToAudioFile = GetFunction(PBEx_Speech, "TextToAudioFile")
        Prototype SpeechRecognition(WordArray, WordArraySize, ErrorOutput)
        Global SpeechRecognition.SpeechRecognition = GetFunction(PBEx_Speech, "SpeechRecognition")
        Prototype WaitSpeechRecognition(RecognizedWord)
        Global WaitSpeechRecognition.WaitSpeechRecognition = GetFunction(PBEx_Speech, "WaitSpeechRecognition")
        Prototype KillSpeechRecognition()
        Global KillSpeechRecognition.KillSpeechRecognition = GetFunction(PBEx_Speech, "KillSpeechRecognition")
        
        Define RecognizedWord$ = Space(1024)
        Define ErrorOutput$ = Space(1024)
        Define IsRecognized
        Dim WordArray.s(5)
        WordArray(0) = "Hello"
        WordArray(1) = "Engine"
        WordArray(2) = "Install"
        WordArray(3) = "Basic"
        WordArray(4) = "Welcome"
        WordArray(5) = "Love"
        
        If SpeechRecognition(0, 0, @ErrorOutput$) = 0
          WaitSpeechRecognition(@RecognizedWord$)
          Debug RecognizedWord$
        EndIf
        
        If SpeechRecognition(WordArray(), ArraySize(WordArray())+1, @ErrorOutput$) = 0
          Repeat
            IsRecognized = WaitSpeechRecognition(@RecognizedWord$)
            If IsRecognized = 1
              Debug "Recognized: " + RecognizedWord$
              Break
            ElseIf IsRecognized = 2
              If RecognizedWord$ = ""
                Debug "Nothing was recognized correctly."
              Else
                Debug "Not recognized correctly, maybe this word: " + RecognizedWord$ + "?"
              EndIf
            EndIf
          ForEver
        EndIf
        
        KillSpeechRecognition()
        
        CloseLibrary(PBEx_Speech)
      EndIf
  • WaitSpeechRecognition()
    • Syntax:

      Code: Select all

      Result = WaitSpeechRecognition(@RecognizedWord$)
    • Description: Returns 1 and the word if a specified word is recognized by the SpeechRecognition() function. Or 2 for nothing recognized or similar word.
    • Parameter:
      1. @RecognizedWord$: The recognized word is stored in the string variable. If no correct word is found, it returns either empty or a similar word.
    • Return value:
      • 1: A specified word was detected.
      • 2: Nothing was recognized correctly
  • KillSpeechRecognition()
    • Syntax:

      Code: Select all

      Result = KillSpeechRecognition()
    • Description: Toughly terminates the Windows speech recognition program.
    • Parameter: None
    • Return value:
      • 0: The process was successful.
System requirements:
  • Windows XP or higher
  • .NET Framework 4 or higher
  • Unicode activation (standard from PB 5.50)
Licence: This DLL file is free of charge and may be used both privately and commercially.
The following copyright texts must be provided:
Copyright © 2019 RSBasic.de
Download: https://www.rsbasic.de/downloads/downlo ... Speech.zip
Image

I would be happy to receive feedback, suggestions for improvement, bug reports or requests. If you want to support me, you can also donate me a little something. Thank you :)

Re: PB.Ex Speech (Windows)

Posted: Sun Mar 11, 2018 1:35 pm
by Mistrel
Would you be willing to share the DLL source? What speech recognition library are you using? I've been wanting to do something like this with Dragon but never got around to it.

There is so much cool stuff that can be used with speech recognition but there aren't many free libraries available that are easily inter-operable with PureBasic.

Re: PB.Ex Speech (Windows)

Posted: Sun Mar 11, 2018 1:40 pm
by RSBasic
Mistrel wrote:What speech recognition library are you using?
TextToSpeaker()/TextToAudioFile() :arrow: System.Speech.Synthesis.SpeechSynthesizer() :arrow: System.Speech.dll
SpeechRecognition()/WaitSpeechRecognition() :arrow: System.Speech.Recognition.SpeechRecognizer() :arrow: System.Speech.dll

Re: PB.Ex Speech (Windows)

Posted: Mon Mar 12, 2018 8:07 pm
by RSBasic
PB.Ex Speech 1.0.1.0 was published.

Changelog:
  • Added: Returns "2" of the WaitSpeechRecognition() function if no correct or similar word was detected.

Re: PB.Ex Speech (Windows)

Posted: Tue Mar 13, 2018 5:26 pm
by juror
Brilliant :!:
Been wanting like this for some time :D

Back to development

Re: PB.Ex Speech (Windows)

Posted: Thu Mar 29, 2018 11:09 pm
by firace
Very nice! But is it possible to use voice recognition without having the Microsoft UI visible?

Re: PB.Ex Speech (Windows)

Posted: Fri Mar 30, 2018 7:44 am
by RSBasic
You mean the little window? Yes, it comes automatically from the interface. Microsoft apparently didn't want the program to eavesdrop, but that the user always sees immediately.
Without this window it is not possible.

Re: PB.Ex Speech (Windows)

Posted: Sun Apr 01, 2018 3:38 pm
by RSBasic
PB.Ex Speech 1.0.2.0 has been released.

Changelog:
  • Changed: The target.NET framework has been changed from 3.5 to 4.0.
  • Added: KillSpeechRecognition()-Function
  • Added: SpeechRecognition() can now recognize words without predefinition.

Re: PB.Ex Speech (Windows)

Posted: Tue Apr 03, 2018 5:08 pm
by ar-s
Thanks for your work.

Re: PB.Ex Speech (Windows)

Posted: Mon May 06, 2019 10:30 am
by BarryG
This looks (sounds!) amazing! Thanks for this. You're coming up with some amazing stuff for PureBasic. Very impressed!

Can DLLs be included in the exe (such as with IncludeBinary) and be accessed with something like CatchDLL, if you know what I mean? I'm a big stickler for distributing only one file (the executable itself) for my products.

Re: PB.Ex Speech (Windows)

Posted: Mon May 06, 2019 10:51 am
by RSBasic
You can include the DLL and unpack it before use, but there is no CatchLibrary().
There's a wish thread: viewtopic.php?f=3&t=43442
If there's another way, I don't know.
Or you use UPX.

Re: PB.Ex Speech (Windows)

Posted: Mon May 06, 2019 11:22 am
by BarryG
Thanks, I will have to include and unpack it to the Windows temp dir, then. That's ok.

I also confirmed this tool doesn't work on a raw Windows XP install, because XP only comes with .NET 1.0 installed. XP users would need to manually install .NET 4.0 first, followed by a manual install of .NET 4.03 (the last supported by Microsoft). See below.
Microsoft wrote:Source: https://docs.microsoft.com/en-us/dotnet ... windows-xp

The .NET Framework 4.0.3 is the latest supported .NET Framework version on Windows XP and Windows Server 2003. The .NET Framework 4.0.3 requires that the .NET Framework 4 is installed first. Both of these .NET Framework versions are no longer supported by Microsoft.
I think I'll have to either drop XP support for my product (makes sense, really) or just not allow the speech functions of it unless .NET 4.0 is detected. Since I still use XP daily for testing (and playing some older games), I'll probably do the latter.

Re: PB.Ex Speech (Windows)

Posted: Mon May 06, 2019 11:26 am
by RSBasic
Windows XP is over 17 years old and there have been no security updates for a long time.
I would recommend that you use a current operating system. :)
You can play the old games in a VM.
There are very few users who still use XP. It is not necessary to support the applications for XP.

Re: PB.Ex Speech (Windows)

Posted: Mon May 06, 2019 11:30 am
by BarryG
RSBasic wrote:I would recommend that you use a current operating system. :)
Windows 10 Pro is my main system. I just use an old XP laptop as a backup, and for games that don't run in a VM. It's ok, I will just make the product not use the speech on XP. Not a big deal. :)

Re: PB.Ex Speech (Windows)

Posted: Mon May 06, 2019 12:16 pm
by BarryG
Hi again RSBasic. I just noticed that the return value of the PBEx_Speech variable is 0 on XP, so it seems to be failing to load your DLL at all, before even .NET is used. Interesting? I would expect the DLL to load but then the voices just to fail to play?