E,0.5,3,1
D,0.25,3,1
C,0.5,3,1
D,0.5,3,1
E,0.5,3,1
E,0.5,3,1
E,0.75,3,1
D,0.5,3,1
D,0.5,3,1
D,0.5,3,1
E,0.5,3,1
G,0.5,3,1
G,0.5,3,1
####
D,0.25,3,1
F,0.25,3,1
D,0.25,3,1
G,0.25,3,1
D,0.25,3,1
F,0.25,3,1
D,0.25,3,1
R,2,1,1
D,0.25,3,1
F,0.25,3,1
D,0.25,3,1
G,0.25,3,1
D,0.25,3,1
F,0.25,3,1
D,0.25,3,1
R,2,1,1
D,0.25,3,1
F,0.25,3,1
D,0.25,3,1
G,0.25,3,1
D,0.25,3,1
F,0.25,3,1
D,0.25,3,1
####
#!/perl/bin/perl -w
use strict;
use Win32::MIDI;
my $midi_obj = Win32::MIDI->new();
$midi_obj->openDevice(0);
if (scalar @ARGV == 0) {
play_file("mary.txt");
play_file("song.txt");
melody(day_tripper(3));
} else {
for my $song (@ARGV) {
play_file($song);
}
}
sleep(1);
$midi_obj->closeDevice();
exit(0);
sub note {
# note(NOTE, DURATION, OCTAVE, ON/OFF);
my ($note, $duration, $octave, $on) = @_;
# play_note(NOTE, DURATION, VELOCITY, CHANNEL, ON/OFF, OCTAVE)
if ($note ne 'R') {
$midi_obj->play_note($note, $duration, 127, 1, $on, $octave)
|| print $midi_obj->error() . "\n" and $midi_obj->reset_error();
} else {
select(undef, undef, undef, $duration); # Rest for this $duration
}
}
sub melody {
# ([NOTE, DURATION, OCTAVE, ON/OFF], [NOTE, DURATION, OCTAVE, ON/OFF],...)
for my $melody (@_) {
note(@$melody);
}
sleep(3);
}
sub play_file {
my $file = shift;
my @song;
open(MID, "<", $file);
for my $line () {
my ($note, $duration, $octave, $on) = split/,/, $line;
push @song, [split /,/, $line];
}
close(MID);
melody(@song);
}
sub day_tripper {
# 'Day Tripper' by the Beatles
my $octave = shift;
my @song;
for (0..2) {
push @song, (
['E', 1.25, $octave, 1],
['G', 0.5, $octave, 1],
['G#', 0.25, $octave, 1],
['B', 0.25, $octave, 1],
['E', 0.25, $octave, 1],
['D', 0.25, $octave, 1],
['D', 1, $octave, 1],
['B', 0.25, $octave, 1],
['F#', 0.25, $octave, 1],
['F', 0.25, $octave, 1],
['B', 0.25, $octave, 1],
['D', 0.25, $octave, 1],
['E', 0.25, $octave, 1],
);
}
return @song;
}