Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Powershell Text To Speech
#1
Code: (Select All)
_Title "Steve's Powershell Speech Script"


SaP "Hello World. This is a normal speed demo of David's voice", "David", 0
_Delay 2
SaP "Hello again.  This is a normal speed demo of Ziva's voice.", "Ziva", 0
_Delay 2
SaP "And now I'm speaking as David, but I'm speaking veeery slow.", "David", -10
_Delay 2
SaP "And now I'm a very hyper Ziva!", "Ziva", 5
_Delay 2
SaP "And now I'm done with my demo!", "", 0

Sub SaP (text$, who$, speed)
    Print text$
    If UCase$(who$) = "ZIVA" Then Speaker = 1
    speak text$, Speaker, speed
End Sub

Sub speak (text As String, Speaker As Integer, Speed)
    Dim message As String
    message = text
    'some symbols and such can't be used with Powershell like this, as they're command symbols
    'we need to strip them out of our text.  (Like apostrophes!)
    remove$ = "'" + Chr$(34) 'add to remove$ here, if more symbols need to be removed as future testing showcases problems
    For j = 1 To Len(remove$)
        Do
            i = InStr(message, Mid$(remove$, j, 1))
            If i Then message = Left$(message, i - 1) + Mid$(message, i + 1)
        Loop Until i = 0
    Next
    out$ = "Powershell -Command " + Chr$(34)
    out$ = out$ + "Add-Type -AssemblyName System.Speech; "
    out$ = out$ + "$Speech = New-Object System.Speech.Synthesis.SpeechSynthesizer; "
    If Speaker = 0 Then out$ = out$ + "$Speech.SelectVoice('Microsoft David Desktop'); "
    If Speaker = 1 Then out$ = out$ + "$Speech.SelectVoice('Microsoft Zira Desktop'); "
    If Speed Then out$ = out$ + "$Speech.Rate =" + Str$(Speed) + "; "
    out$ = out$ + "$Speech.Speak('" + message + "');" + Chr$(34)
    Shell _Hide out$
End Sub
Reply
#2
And update to this which is more powerful and seems to correct the issue with first words being cut off and not playing on my system properly.

Code: (Select All)
Type SpeechType
    As Integer Speaker, Speed, Volume
    As String File
End Type
Dim Shared SpeechVar As SpeechType

Speech.Init
Speech.Speaker "Female"
Speech.Speak "Hello World. My name is Steve. Testing."
Speech.Speaker "Male"
Speech.Speak "This is a second line of text.  Do I sound completely stupid?"
Speech.Speak "Are any of these cutting off the first few words?"
Speech.Speak "I hope not.  I've tried to sort those issues out, and correct for proper pausing to make certain the text is heard completely before moving on."
Speech.Speed 5
Speech.Speak "And this should be speaking fast as crap!"
Speech.Speed -10
Speech.Speak "And this should be a slow, drawn out speech."

System

Sub Speech.Init
    SpeechVar.Speaker = 0
    SpeechVar.Speed = 0
    SpeechVar.Volume = 100
    SpeechVar.File = ""
    Speech.Speak " "
End Sub

Sub Speech.Speaker (who$)
    Select Case UCase$(who$)
        Case "DAVID", "MALE", "M": SpeechVar.Speaker = 0
        Case "ZIVA", "FEMALE", "F": SpeechVar.Speaker = 1
    End Select
End Sub

Sub Speech.Speed (Speed)
    If Speed < -10 Then Speed = -10
    If Speed > 10 Then Speed = 10
SpeechVar.Speed = Speed: End Sub
Sub Speech.Volume (Volume): SpeechVar.Volume = Volume: End Sub

Sub Speech.OutTo (where$)
    Select Case UCase$(where$)
        Case "CONSOLE", "CONS", "", "SPEAKER": SpeechVar.File$ = ""
        Case Else: SpeechVar.File$ = where$
    End Select
End Sub

Sub Speech.Speak (text$)
    If _FileExists("TempSpeech.WAV") Then Kill "TempSpeech.WAV"
    Speech.Process text$, SpeechVar.Speaker, SpeechVar.Speed, "TempSpeech.WAV", SpeechVar.Volume
    Do: _Delay .1: Loop Until _FileExists("TempSpeech.WAV")
    s = _SndOpen("TempSpeech.WAV")
    _SndPlay s
    Do
        _Delay .1
    Loop Until _SndPlaying(s) = 0
    _SndClose s
End Sub

Sub Speak.ToWav (text$, file$)
    If UCase$(Right$(file$, 4)) = ".WAV" Then
        Speech.Process text$, SpeechVar.Speaker, SpeechVar.Speed, file$, SpeechVar.Volume
    End If
End Sub

Sub Speech.Process (text As String, Speaker As Integer, Speed, savefile$, volume)
    Dim As String message, file, remove
    Dim out$
    Dim As Long j, i
    message = text 'an in sub variable so we don't change the passed data
    If UCase$(Right$(savefile$, 4)) <> ".WAV" Then file$ = "" Else file$ = savefile$ 'again, don't change passed data
    'some symbols and such can't be used with Powershell like this, as they're command symbols
    'we need to strip them out of our text.  (Like apostrophes!)
    remove$ = "'" + Chr$(34) 'add to remove$ here, if more symbols need to be removed as future testing showcases problems
    For j = 1 To Len(remove$)
        Do
            i = InStr(message, Mid$(remove$, j, 1))
            If i Then message = Left$(message, i - 1) + Mid$(message, i + 1)
        Loop Until i = 0
    Next
    out$ = "Powershell -Command " + Chr$(34)
    out$ = out$ + "Add-Type -AssemblyName System.Speech; "
    out$ = out$ + "$Speech = New-Object System.Speech.Synthesis.SpeechSynthesizer; "
    If file$ <> "" Then out$ = out$ + "$Speech.SetOutputToWaveFile({" + Chr$(34) + file$ + Chr$(34) + "}); " 'The command to send the output to a file and not the speakers.
    If Speaker = 0 Then
        out$ = out$ + "$Speech.SelectVoice('Microsoft David Desktop'); "
    ElseIf Speaker = 1 Then
        out$ = out$ + "$Speech.SelectVoice('Microsoft Zira Desktop'); "
    End If
    If volume >= 0 _AndAlso volume <= 100 Then out$ = out$ + "$Speech.Volume =" + Str$(volume) + "; "
    If Speed Then out$ = out$ + "$Speech.Rate =" + Str$(Speed) + "; "
    out$ = out$ + "$Speech.Speak(' " + message + "');" + Chr$(34)
    Shell _Hide out$
End Sub

Note that you can use this to export to your own .WAV file and then handle it without any automatic delays in speaking and such.  Just use this to write to a file, open the output and _SNDPLAY it without using the _SOUNDPLAYING loop like I am to force it to wait for the speech to finish playing.

For my own uses, this is generally what I want to make certain happens -- the program pauses until the speech is played completely, and then it resumes running after that.  If you're doing something where this pause isn't wanted, be certain to save it and process it yourself instead.
Reply
#3
Thanks for the update. It's a funny thing that I was just thinking of this routine last night, and wondering if I would be able to locate it.
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#4
Hope it all works well for you and without any issues @OldMoses

Let me know if it plays without cutting out any of the leading speech like the older version does.  This seems to run and work much better on my system.  I hope it performs just as flawlessly for everyone else as well.  Wink
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Embed Text SMcNeill 2 1,057 02-19-2023, 11:24 AM
Last Post: Petr
  Rainbow Text SMcNeill 0 638 01-08-2023, 09:47 PM
Last Post: SMcNeill

Forum Jump:


Users browsing this thread: 1 Guest(s)