Stupid Mac::Glue Tricks: Name That Tune
The iPod has a Name That Tune game in it, where it shows you a list of five songs, and it plays a song from your iPod, and you guess which one it is. Here's a perl/iTunes version. It has a crummy UI, and it doesn't keep score, but the guts all seem to work. Just type the number of the song you think is playing.
One slightly dangerous part is that it sets the "start" time of the file, so that it begins playing in the middle of the song, then it sets it back. It could, of course, fail to set it back if there's a crash of some kind. Oh, the risks we take in life!
One slightly dangerous part is that it sets the "start" time of the file, so that it begins playing in the middle of the song, then it sets it back. It could, of course, fail to set it back if there's a crash of some kind. Oh, the risks we take in life!
#!/usr/local/bin/perl
use strict;
use warnings;
use Mac::Glue ':all';
use Term::ReadKey;
my $itunes = new Mac::Glue 'iTunes';
# interval between guesses
my $guess_sleep = 3;
# tracks to guess
my $guesses = 5;
# define the songs you want to get
my $any = $itunes->obj(track => gAny, tracks => whose(bit_rate => g_e => 128), playlist => 1);
play_game() for 0..2;
exit;
sub play_game {
my(@tracks, %tracks);
until (@tracks == $guesses) {
my $track = $any->get;
my($artist, $name, $duration, $start) = map { $track->prop($_)->get || '' }
qw(artist name duration start);
next unless $artist && $name;
next if $tracks{$artist, $name}++;
push @tracks, [$track, @tracks + 1, $artist, $name, $duration, $start];
}
my $selected = my $winner = int rand(@tracks);
$winner += 1;
my $playing = $tracks[$selected];
my $newstart = int($playing->[4]/3 + rand($playing->[4]/10) - rand($playing->[4]/10));
if ($newstart > $playing->[4]) {
$newstart = int($playing->[4] - $guesses*$guess_sleep);
$newstart = 0 if $newstart < 0;
}
$playing->[0]->prop('start')->set(to => $newstart);
$playing->[0]->play;
print_tracks(\@tracks);
ReadMode(4);
OUTER: while (@tracks > 1) {
my $now = time();
INNER: while (($now + $guess_sleep) > time()) {
my $c = ReadKey(-1);
next unless $c && $c =~/\d/;
if ($c == $winner) {
print "Right-o!\n\n\n";
last OUTER;
} else {
last INNER;
}
}
my $remove = int rand(@tracks);
next if $remove == $selected;
$selected-- if $remove < $selected;
splice(@tracks, $remove, 1);
print_tracks(\@tracks);
}
ReadMode(0);
$itunes->stop;
$playing->[0]->prop('start')->set(to => $playing->[5]);
}
sub print_tracks {
my($tracks) = @_;
for (@$tracks) {
print "$$_[1]. $$_[2], '$$_[3]'\n";
}
print "\n\n";
}
Leave a comment