johnnywang has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I just started playing with the Windows speech API, and tried the module Win32::SAPI5, it turns out to be very simple to do speech synthesis, e.g., to read text aloud. What I'd like to do is to take speech commands, e.g., something like:
## very pseudo code while ( $recognized_word = process_input(STDIN) ){ run_commands_for($recongized_word); }
I've got the dictation to work in MS Office, but have no idea how to use perl to do it. Thanks.

Replies are listed 'Best First'.
Re: Speech Recognition with SAPI5
by jbrugger (Parson) on Feb 09, 2005 at 10:19 UTC
    like said on cpan,

    This documentation won't offer the complete documentation for it, just download the Microsoft Speech API 5.1 SDK and read the part of the documentation that covers 'Automation' (since we're using the Automation Object interface.),

    Looks like not a real Perl question here.
      Folks, This Perl grasshopper finally went back and looked over my code and SAPI5 documentation. In three hours I was able to hack the following. It is a (crappy) but functional Windoze SAPI5 speech recognition script. It will do for today. Have fun! If using Vista, be sure and plug in a mic before starting voice recognition, otherwise it will not start.
      #!/usr/bin/perl use strict; use warnings; use Win32::OLE qw( EVENTS ); use Win32::SAPI5; use constant SGDSActive => 1; use constant SREAllEvents => 393215; use constant SpSharedRecoContext => "{47206204-5ECA-11D2-960F-00C04F8E +E628}"; my $speaker = Win32::SAPI5::SpVoice->new() or die " \$^E => $^E\nLastError => ".Win32::OLE->LastErro +r() ; $speaker->speak("Hello"); my $context = Win32::OLE->new(SpSharedRecoContext) || die "Can't star +t OLE: ".Win32::OLE->LastError; $context->SetProperty('EventInterests', SREAllEvents); Win32::OLE->WithEvents( $context, \&ProcessEvents, "{7B8FCB42-0E9D-4F +00-A048-7B04D6179D3D}" ); ## Works my $grammar = $context->CreateGrammar(1); $grammar->DictationLoad(); $grammar->DictationSetState(SGDSActive); while( 1 ) { Win32::OLE->SpinMessageLoop(); Win32::Sleep( 10 ); } sub ProcessEvents { my( $Obj, $Event, @Args ) = @_; if ($Event == 7) { \&OnRecognition(@_); } } sub OnRecognition { my($self, $Event, $StreamNumber, $StreamPosition, $RecognitionType +, $Result) = @_; my $newResult = $self->Invoke('Dispatch', $Result); print $Result->PhraseInfo->GetText() . "\n";; }
Re: Speech Recognition with SAPI5
by PodMaster (Abbot) on Feb 09, 2005 at 09:39 UTC
    ...I've got the dictation to work in MS Office, but have no idea how to use perl to do it.
    So can it be done with SAPI5 or not?

    update: Apparently it can. Like jbrugger said. It shouldn't be too difficult to adapt this python example, here's a rough untested translation

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

      Thanks, I'll give it a try. The question about dictation, I was using only Word, not perl at all, so was just testing the SAPI and microphone worked.
        Hey johnny, did you ever get this to work? I've been messing with it for hours with no luck. It seems very, very close to being able to simply print out a recognized word or phrase, but the last mile isn't complete.
      Greetings,

      Ive been a member some years but never posted until now. I'm an admitted terrible Perl coder. So please be gentle.

      I've read the MS SAPI documentation and have tested the python version with success but still haven't got a Perl version to work. Being weak with Oops, I blindly hacked what I think is on the right track. I blended two non-functional code solutions to this problem, one from the Python Cokbook and the other from Jorke Visser of pvoice. I've sent Jorke a copy at his request but never heard back.

      Could some Monk take mercy on this lost soul and help me interpret these events? I believe event 7 points to a set of probable word or phrase matches.

      Thanks.

      #!/usr/bin/perl use strict; use warnings; use Win32::OLE qw( EVENTS ); use Win32::SAPI5; use constant SGDSActive => 1; use constant SREAllEvents => 393215; use constant SpSharedRecoContext => "{47206204-5ECA-11D2-960F-00C04F8E +E628}"; my $speaker = Win32::SAPI5::SpVoice->new() or die " \$^E => $^E\nLastError => ".Win32::OLE->LastErro +r() ; $speaker->speak("Hello"); my $context = Win32::OLE->new(SpSharedRecoContext) || die "Can't star +t OLE: ".Win32::OLE->LastError; $context->SetProperty('EventInterests', SREAllEvents); Win32::OLE->WithEvents( $context, \&ProcessEvents, "{7B8FCB42-0E9D-4F +00-A048-7B04D6179D3D}" ); ## Works my $grammar = $context->CreateGrammar(1); $grammar->DictationLoad(); $grammar->DictationSetState(SGDSActive); while( 1 ) { Win32::OLE->SpinMessageLoop(); Win32::Sleep( 10 ); } sub ProcessEvents { my( $Obj, $Event, @Args ) = @_; if ($Event == 7) { \&OnRecognition(@_); } if ($Event == 8) { \&OnRecognition(@_); } } sub OnRecognition { print("Inside = @_\n"); my($self, $Event, $StreamNumber, $StreamPosition, $RecognitionType +, $Result) = @_; my $newResult = $self->Invoke('Dispatch', $Result); # print "\$newResult = $newResult\n\n}"; }

      20070730 Janitored by Corion: Fixed code tags, as per Writeup Formatting Tips

Re: Speech Recognition with SAPI5
by mkirank (Chaplain) on Feb 09, 2005 at 05:51 UTC
    Google Festival TTS (text to speech) , I think there is a wrapper for Perl .