in reply to Speech Recognition with SAPI5

...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

use strict; use warnings; =head1 NAME Speech recognition in Windows using the MS Speech API =head1 DESCRIPTION This is an example of using the Microsoft Speech SDK 5.1 under Windows + for command and control speech recognition in Perl. Ported to perl from http://aspn.activestate.com/ASPN/Cookbook/Python/R +ecipe/93025 but B<not tested yet>. Sample code for using the Microsoft Speech SDK 5.1 via COM (aka Win32: +:OLE) in Perl. Requires that the SDK be installed; it's a free download from http://microsoft.com/speech After running this, then saying "One", "Two", "Three" or "Four" should display "You said One" etc on the console. The recognition can be a bi +t shaky at first until you've trained it (via the Speech entry in the Wi +ndows Control Panel. =head1 Classes =cut use Win32::OLE qw(EVENTS); use Win32::SAPI5; package SpeechRecognition; =head2 SpeechRecognition Initialize the speech recognition with the passed in list of words =head3 C<< SpeechRecognition->new(qw[ words to add ]) >> Initialize the speech recognition with the passed in list of words =cut sub new { my($self, @wordsToAdd)=@_; $self = bless {}, $self; # For text-to-speech $self->{speaker} = Win32::SAPI5::SpVoice->new() or die " \$^E => $^E\nLastError => ".Win32::OLE->LastErro +r() ; # For speech recognition - first create a listener $self->{listener} = Win32::SAPI5::SpSharedRecognizer->new() or die " \$^E => $^E\nLastError => ".Win32::OLE->LastErro +r() ; # Then a recognition context $self->{context} = $self->{listener}->CreateRecoContext() or die " \$^E => $^E\nLastError => ".Win32::OLE->LastErro +r() ; # which has an associated grammar $self->{grammar} = $self->{context}->CreateGrammar() or die " \$^E => $^E\nLastError => ".Win32::OLE->LastErro +r() ; # Do not allow free word recognition - only command and control # recognizing the words in the grammar only $self->{grammar}->DictationSetState(0); # Create a new rule for the grammar, that is top level (so it begi +ns # a recognition) and dynamic (ie we can change it at runtime) use constant SRATopLevel => 1; #from Enum SpeechRuleAttributes use constant SRADynamic => 32; $self->{wordsRule} = $self->{grammar}->{Rules}->Add( "wordsRule" => SRATopLevel + SRADynamic, 0, ); # Clear the rule (not necessary first time, but if we're changing +it # dynamically then it's useful) $self->{wordsRule}->Clear(); # And go through the list of words, adding each to the rule $self->{wordsRule}->{InitialState}->AddWordTransition(undef, $_) for @wordsToAdd; # Set the wordsRule to be active $self->{grammar}->{Rules}->Commit(); $self->{grammar}->CmdSetRuleState("wordsRule", 1); # Commit the changes to the grammar; $self->{grammar}->{Rules}->Commit(); # And add an event handler that's called back when recognition occ +urs # this part is different with Win32::OLE, needs testing $self->{eventHandler} = ContextEvents->new($self->{context}); $self->{context}->WithEvents('ContextEvents'); # $self->{context}->WithEvents( $self->{eventHandler} ); # Announce we've started using speech synthesis $self->say("Started successfully"); } =head3 C<< $self->say($phrase) >> Speak a word or phrase =cut sub say { my($self,$phrase)=@_; $self->{speaker}->Speak($phrase); } =head2 ContextEvents The callback class that handles the events raised by the speech object +. See "Automation | SpSharedRecoContext (Events)" in the MS Speech SDK online help for documentation of the other events supported. @ContextEvents::ISA = Win32::SAPI5::SpSharedRecoContext =cut package ContextEvents; use base qw[ Win32::SAPI5::SpSharedRecoContext ]; =head3 C<< $self->OnRecognition(StreamNumber, StreamPosition, Recognit +ionType, Result) >> Called when a word/phrase is successfully recognized - ie it is found in a currently open grammar with a sufficiently high confidence =cut sub OnRecognition { my($self, $StreamNumber, $StreamPosition, $RecognitionType, $Resul +t) = @_; my $newResult = $self->{speaker}->Invoke('Dispatch', $Result); print "You said: ", $newResult->{PhraseInfo}->GetText(); } sub Recognition { goto &OnRecognition } 1; package main; unless(caller){ my $speechReco = SpeechRecognition->new( "One", "Two", "Three", "F +our" ); while(1){ # not quite sure which one is the equivalent of #pythoncom.PumpWai +tingMessages() # Win32::OLE->MessageLoop(); Win32::OLE->SpinMessageLoop(); } }

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.

Replies are listed 'Best First'.
Re^2: Speech Recognition with SAPI5
by johnnywang (Priest) on Feb 09, 2005 at 22:08 UTC
    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.
Re^2: Speech Recognition with SAPI5
by snake_mountain (Novice) on Dec 21, 2005 at 19:41 UTC
    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