1

Recently, I found out about the spvoice interface. Therefore, I wanted to make a small program that makes Powershell say something I type into it. So, I made this:

$Voice = New-Object -ComObject Sapi.spvoice
for(;;){
Clear-Host
$UserInput = Read-Host
if($UserInput -eq "Voice.Rate"){
$VoiceRate = Read-Host "Set new voice rate"}
else{
$Voice.rate = $VoiceRate
$Voice.speak("$UserInput")}}

And although it did whatever I wanted it to, the .speak() method was returning the number 1. How can I prevent this from happening?

PlatoHero
  • 31
  • 5
  • 1
    In short: any output - be it from a PowerShell command, an operator-based expression, or a .NET method call - that is neither captured in a variable nor redirected (sent through the pipeline or to a file) is _implicitly output_ from a script or function. To simply _discard_ such output, use `$null = ...`. If you don't discard such output, it becomes part of a script or function's "return value" (stream of output objects). See the linked duplicate for details. – mklement0 Jun 14 '22 at 15:21

1 Answers1

1

I've done this, but not using sapi.spvoice. Instead, I used System.Speech, as follows:

Add-Type -AssemblyName System.Speech
$voice = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer
$voice.SelectVoice("Microsoft Zira Desktop")

While ($true) {
    Clear-Host
    $UserInput = Read-Host
    $voice.Speak("$UserInput")
}

This example doesn't have the provisions for setting the rate, but you can change the rate and volume by setting $voice.Rate and $voice.Volume respectively. See Microsoft Docs on the Speech Synthesizer.

Jeff Zeitlin
  • 9,773
  • 2
  • 21
  • 33