Powershell Text To Speech - SMcNeill - 04-23-2022
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
RE: Powershell Text To Speech - SMcNeill - 05-16-2025
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.
RE: Powershell Text To Speech - OldMoses - 05-16-2025
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.
RE: Powershell Text To Speech - SMcNeill - 05-16-2025
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.
|