In fact, whatever voice is currently selected will be the talker, you can even change the voice with one of the SAPI example c++ applications, come back to perl and the new voice you choose via the exe will be selected. Ah, but to do it in perl.... I found that my registry gets altered whenever the SAPI exe changes the voice. Hence, we let perl change the same registry key and voila, perl changed the default SAPI4 voice. Works great for me, i hope it does for you as well. Here's the working code which changes the voice to RoboSoft Six...use Win32::OLE qw( EVENTS ); my $vt = Win32::OLE->new('{EEE78591-FE22-11D0-8BEF-0060081841DE}') || +die "Can't start VoiceText"; my $use_id = $vt->Find( "Male Whisper" ); $vt->Select($use_id); $vt->Speak("Hello World"); while( $vt->{Speaking} ){ Win32::OLE->SpinMessageLoop(); Win32::Sleep( 100 ); }
Notice that we call the CountEngines() function built-in to SAPI4 (thanks Jouke). Then we iterate through the list of all the voices installed on Windows (I've got 37 of em). When we find our match ("RoboSoft Six" above), we take the ModeID value sent to us by SAPI4 and pack that accordingly and set our registry to the new value. Most smart people i'm sure will think my "Flip" subroutine is absurd and pointless. I'm sure there's a way to do it without the subroutine but i don't know it yet. I tested this code on Win2000Pro and WinXPPro with no issues.use Win32::OLE qw( EVENTS ); use Win32::TieRegistry; my $vt = Win32::OLE->new('{EEE78591-FE22-11D0-8BEF-0060081841DE}') || +die "Can't start VoiceText"; my $ttl = $vt->CountEngines(); my $look_for = "RoboSoft Six"; for(my $x=1;$x <= $ttl;$x++){ my $mode_name = $vt->ModeName($x); my $mode_id = $vt->ModeID($x); if ($mode_name eq $look_for){ my($h1,$h2,$h3,$h4,$h5) = split(/\-/,$mode_id); $h1 = &Flip($h1); $h2 = &Flip($h2); $h3 = &Flip($h3); &ChangeVoiceRegKey("$h1$h2$h3$h4$h5"); } } $vt->Speak("Hello World"); while( $vt->{Speaking} ){ Win32::OLE->SpinMessageLoop(); Win32::Sleep( 100 ); } ######################################################### ######################################################### ######################################################### sub ChangeVoiceRegKey{ my $hsh = $_[0]; my $rf = $Registry->{"HKEY_CURRENT_USER\\Software\\Voice\\VoiceText\\L +ocal PC"}= { "Mode", => [ pack("H*","$hsh"), "REG_BINARY" ] }; }################################## end ChangeVoiceRegKey sub Flip{ my $vle = $_[0]; $vle =~ s/(..)/$1\|/g; $vle =~ s/\|$//; my @all = split(/\|/,$vle); my $new_all; foreach my $li(reverse @all){ $new_all .= $li; } return $new_all; }################################## end Flip
In reply to perl SAPI4 changing voices Win32 by true
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |