Stupid Mac::Glue Tricks: Name That Tune

| | Comments (0)
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!

#!/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";
}

use.perl.org

Leave a comment

<pudge/*> (pronounced "PudgeGlob") is thousands of posts over many years by Pudge.

"It is the common fate of the indolent to see their rights become a prey to the active. The condition upon which God hath given liberty to man is eternal vigilance; which condition if he break, servitude is at once the consequence of his crime and the punishment of his guilt."

About this Entry

This page contains a single entry by pudge published on July 21, 2004 3:54 PM.

Tuesday Thoughts was the previous entry in this site.

Ben Folds + William Shatner = Magic, Baby! is the next entry in this site.

Find recent content on the main index or look in the archives to find all content.