I wrote this script so I could tell my Mac to "play Stevie Wonder" and it would.
"quit" stops the script.
Just give it the path to a directory that contains directories. Each directory
will contain MP3s (doesn't matter how many levels deep, we are using File::Find
to get every file /\.mp3$/) and will have the name you want to use to invoke it.
Uses Mac::Glue to control SoundJam. It keeps reusing a single playlist window
each time you tell it to play $foo.
-- Chris
#!perl -w
# speak soundjam.plx
# [EMAIL PROTECTED], 2001.06.18
use strict;
use File::Find;
use File::Spec::Functions;
use Mac::Glue ':all';
use Mac::Events;
use Mac::SpeechRecognition;
my $sj = new Mac::Glue 'SoundJam';
my $dir = "Bird:mp3:stuff";
my $artists = getArtists();
createSpeechModel($artists);
my $win = $sj->make(new => 'playlist window');
while (1) {
WaitNextEvent();
}
exit;
# just load in directory names inside $dir
sub getArtists {
opendir(D, $dir) or die $!;
my %artists = map { ($_ => 1) } grep { -d catdir($dir, $_) } readdir D;
closedir D;
return \%artists;
}
# load in all .mp3 files under $dir:$artist
sub getArtistFiles {
my($artist) = @_;
my($newdir, @files);
$newdir = catdir($dir, $artist);
return unless -d $newdir;
find(sub { push @files, $File::Find::name if /\.mp3$/ }, $newdir);
return @files;
}
# phun phun phun
sub createSpeechModel {
my($artists) = @_;
# Initialize Recognition System
my $system = SROpenRecognitionSystem() or die $^E;
SRSetProperty($system, kSRFeedbackAndListeningModes,
kSRHasFeedbackHasListenModes) or die $^E;
# Create Recognizer
my $recognizer = SRNewRecognizer($system);
# Build Language Model
my $topModel = SRNewLanguageModel($system, "<TopLM>") or die $^E;
my %models;
for my $key (qw(quit play artist)) {
$models{$key} = SRNewLanguageModel($system, "<$key>") or die $^E;
for ($key eq 'artist' ? keys %$artists : $key) {
my $phrase = SRNewPhrase($system, $_) or die $^E;
SRAddLanguageObject($models{$key}, $phrase) or die $^E;
SRReleaseObject($phrase) or die $^E;
}
}
for my $key (qw(quit play)) {
my $path = SRNewPath($system) or die $^E;
SRAddLanguageObject($path, $models{$key}) or die $^E;
if ($key eq 'play') {
SRAddLanguageObject($path, $models{artist}) or die $^E;
}
SRAddLanguageObject($topModel, $path) or die $^E;
SRReleaseObject($path);
SRReleaseObject($models{$key});
if ($key eq 'play') {
SRReleaseObject($models{artist});
}
}
SRSetLanguageModel($recognizer, $topModel) or die $^E;
# Set up AppleEvent handler and start listening
$AppleEvent{kAESpeechSuite, kAESpeechDone} = \&Listen;
SRStartListening($recognizer);
SRSetProperty($recognizer, kSRNotificationParam,
kSRNotifyRecognitionDone) or die $^E;
END {
SRStopListening($recognizer);
SRReleaseObject($topModel);
SRReleaseObject($recognizer);
SRCloseRecognitionSystem($system);
}
}
sub AEGetSpeechObject {
my($event, $key, $type) = @_;
my $desc = AEGetParamDesc($event, $key, $type);
my $obj = SRMakeSpeechObject($desc->data->get);
AEDisposeDesc($desc);
return $obj;
}
sub Listen {
my($event, $reply) = @_;
my $rec = AEGetSpeechObject($event, keySRRecognizer, typeSRRecognizer);
my $res = AEGetSpeechObject($event, keySRSpeechResult, typeSRSpeechResult);
my $text = SRGetProperty($res, kSRTEXTFormat);
SRReleaseObject($res);
if (!$text || $text =~ /\Q???/) {
print "I don't know what you said.\n";
return 0;
} elsif ($text =~ /^quit/i) {
print "Good-bye.\n";
exit;
} else {
print "I think you said: '$text'.\n";
$text =~ s/^play\s+//i;
}
my @files = getArtistFiles($text) or return;
$sj->delete( $sj->obj(file_tracks => $win) );
$sj->add(\@files, to => $win);
$sj->play($sj->obj(file_track => 1, $win));
return 1;
}
__END__
--
Chris Nandor [EMAIL PROTECTED] http://pudge.net/
Open Source Development Network [EMAIL PROTECTED] http://osdn.com/