Writing with text-to-speech feedback

As I’m working on the next edition of Intermediate Perl, I’m letting the computer read it back to me. I use Mac::Speech, part of the old Perl Carbon interface.

I use this script as a BBEdit Text Filter (although it’s not really filtering anything). I put this in my ~/Library/Application Support/BBEdit/Text Filters/speak_it. When I select text and choose this (or any) filter, BBEdit supplies the selected text to my filter on standard input. Anything I send to standard output replaces the selection, but I don’t want to replace the text. If I output nothing, the text disappears so I just print the unmodified text.

I call SpeakText and give it the current line. This fires off a separate process and my program continues, so I sleep while the interface tells me that it is speaking.

#!/usr/bin/perl

=pod

To use Mac::Speech, you need to use the 32-bit perl. The Mac comes
with both 32- and 64-bit versions and automatically selects the one. 
However, the Carbon API, which Mac::Speech uses, needs the 32-bit
version.

You can set the default perl to the 32-bit version:
 
	% defaults write com.apple.versioner.perl Prefer-32-Bit -bool yes

You can also choose it for just this session:

	% export VERSIONER_PERL_PREFER_32_BIT=yes

You don't really have to do anything because the program will set this
for you and re-exec itself if necessary.

=cut

BEGIN {
	unless( $ENV{VERSIONER_PERL_PREFER_32_BIT} eq 'yes' ) {
		$ENV{VERSIONER_PERL_PREFER_32_BIT} = 'yes';
		exec qq($^X "$0");
		}
	}

use v5.12;
use Mac::Speech;

my $voice   = $Mac::Speech::Voice{Victoria};
my $channel = NewSpeechChannel( $voice );

while( <> ) {
	SpeakText( $channel, $_ );
	print; 
	sleep 1 while SpeechBusy();
	}

DisposeSpeechChannel($channel);