After having helped out primus with Win32::MIDI and seeing LostS's songs, I decided to try my hand at a very basic Win32::MIDI player. It can read a song from a comma seperated values file or you can hard code the song in. I didn't use Text::CSV since this is really just a play thing but I might rewrite it later to do so.

Before I show you the code, let me explain the format of the CSV files. Each line should have NOTE,DURATION,OCTAVE,ON/OFF as understood by Win32::MIDI.

I have added support for a rest. NOTE is R. OCTAVE and ON/OFF are ignored.

mary.txt

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

AC/DC - A Whole Lot of Rosie
song.txt

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

And now for the code!

#!/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 (<MID>) { 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; }

Update: all music was "transcribed" by LostS.

Update 2: Plays all song files listed on the command line or enters "demo" mode if you do not specify any files.

Replies are listed 'Best First'.
Re: Win32::MIDI Player
by LostS (Friar) on Jan 31, 2003 at 22:37 UTC
    This song is written correctly... The others I don't think I coded right... will rework them...

    Now see if you can identify this song:
    G#,1,3,0 E,1,3,0 R,.25,4,1 G#,.25,4,1 B,.25,4,1 G#,.25,4,1 F#,1,3,0 D,1,3,0 B,1,3,0 A,.25,4,1 F#,.25,4,1 A,.50,4,1 A,1,3,0 F#,1,3,0 D,1,3,0 D,.25,5,1 A,.25,4,1 D,.50,5,1 E,1,3,0 C#,1,3,0 A,1,3,0 C#,.25,5,1 A,.25,4,1 C#,.50,5,1


    -----------------------
    Billy S.
    Slinar Hardtail - Hand of Dane
    Datal Ephialtes - Guildless
    RallosZek.Net Admin/WebMaster

    perl -e '$cat = "cat"; if ($cat =~ /\143\x61\x74/) { print "Its a cat! +\n"; } else { print "Thats a dog\n"; } print "\n";'
      #!/usr/bin/perl use strict; use warnings; use MIDI::Simple; my $quarter_notes_per_minute = 140; new_score(); Volume 127; set_tempo int(60_000_000/$quarter_notes_per_minute); patch_change 1, 1; noop "c1", "o3"; # Setup n "hn", "Gs", "E", "en", "rest"; n "Gs_u1"; n "B_u1"; n "Gs_u1"; n "hn", "Fs", "D", "B", "en", "A_u1"; n "Fs_u1"; n "qn", "A_u1"; n "hn", "A", "Fs", "D", "en", "D_u2"; n "A_u1"; n "qn", "D_u2"; n "hn", "E", "Cs", "A", "en", "Cs_u2"; n "A_u1"; n "qn", "Cs_u2"; r "wn"; write_score('LostS.mid'); exec('start','LostS.mid') if ($^O =~ /MSWin32/);
        What is this part? It doesn't work for me:
        exec('start','LostS.mid') if ($^O =~ /MSWin32/);


        -----------------------
        Billy S.
        Slinar Hardtail - Hand of Dane
        Datal Ephialtes - Guildless
        RallosZek.Net Admin/WebMaster

        perl -le '$cat = "cat"; if ($cat =~ /\143\x61\x74/) { print "Its a cat +!\n"; } else { print "Thats a dog\n"; }'
Re: Win32::MIDI Player
by LostS (Friar) on Feb 02, 2003 at 20:44 UTC
    OK I sat down and coded this one... Very long... Had my little sister do the note conversion for me so they should be correct... and it sounds exactly like the midi file I downloaded of it... Now can you all name it??
    D,.2,3,1 D,.2,3,1 G,.2,3,1 F#,.2,3,1 G,.2,3,1 A,.2,3,1 G,.2,3,1 R,.2,3,1 G,.2,3,1 G,.2,3,1 A#,.2,3,0 G,.2,3,1 A#,.2,3,1 A#,.2,3,1 C,.2,4,1 A#,.2,3,0 G,.2,3,1 R,.2,3,1 A#,.2,3,1 A#,.2,3,1 D,.2,4,0 F,.2,3,1 C#,.2,4,1 D,.2,4,1 E,.2,4,1 D,.2,4,0 F,.2,3,1 E,.2,4,1 F,.2,4,1 F#,.2,4,1 G,.2,4,0 G,.2,3,1 R,.2,3,1 R,.2,3,1 R,.2,3,1 G,.2,4,0 G,.2,3,1 R,.2,3,1 R,.2,3,1 R,.2,3,1 G,.2,3,1 D,.2,4,1 D,.2,4,1 E,.2,4,1 D,.2,4,1 C,.2,4,1 C,.2,4,1 E,.2,4,1 F,.2,4,1 A,.2,4,1 C,.2,5,1 A,.2,4,1 A,.2,4,1 G,.2,4,1 G,.4,4,1 A,.2,4,1 A#,.2,3,1 A#,.2,3,1 A,.2,4,1 G,.2,4,1 C,.2,4,1 C,.2,4,1 E,.2,4,1 E,.2,4,0 G,.2,3,1 D,.2,4,0 A#,.2,3,1 E,.2,4,0 G,.2,3,1 D,.2,4,0 A#,.2,3,1 E,.2,4,0 G,.2,3,1 D,.2,4,0 A#,.2,3,1 E,.2,4,0 G,.2,3,1 D,.2,4,0 A#,.2,3,1 G,.2,3,1 D,.2,4,1 D,.2,4,1 E,.2,4,1 D,.2,4,1 C,.2,4,1 C,.2,4,1 E,.2,4,1 F,.2,4,1 A,.2,4,1 C,.2,5,1 A,.2,4,1 A,.2,4,1 G,.2,4,1 G,.4,4,1 A,.2,4,1 A#,.2,3,1 A#,.2,3,1 A,.2,4,1 G,.2,4,1 C,.2,4,1 C,.2,4,1 E,.2,4,1 E,.2,4,0 G,.2,3,1 D,.2,4,0 A#,.2,3,1 E,.2,4,0 G,.2,3,1 D,.2,4,0 A#,.2,3,1 E,.2,4,0 F,.2,3,1 D,.2,4,0 C,.2,3,1 C,.4,4,0 C,.4,3,1 E,.4,4,1 C,.4,4,1 A,.4,3,1 G,.4,3,1 G,.2,4,1 D,.2,4,1 E,.2,4,1 F,.2,4,1 E,.2,4,1 D,.2,4,1 C,.4,4,1 E,.4,4,1 C,.4,4,1 A,.4,3,1 G,.4,3,1 F#,.2,3,1 G,.2,3,1 A,.2,3,1 A#,.2,3,1 D,.2,4,1 C,.2,4,1 C,.4,4,1 E,.4,4,1 C,.4,4,1 A,.4,3,1 G,.4,3,1 G,.2,4,1 D,.2,4,1 E,.2,4,1 F,.2,4,1 E,.2,4,1 D,.2,4,1 C,.4,4,1 E,.4,4,1 C,.4,4,1 A,.4,3,1 G,.4,3,1 F#,.2,3,1 G,.2,3,1 A,.2,3,1 A#,.2,3,1 C,.2,4,0 C,.4,3,1 G,.2,3,1 B,.2,3,0 D,.4,3,1 G,.2,3,1 C,.2,4,0 C,.4,3,1 G,.2,3,1 B,.2,3,0 D,.4,3,1 G,.2,3,1 C,.2,4,0 C,.4,3,1 C,.2,4,1 C,.2,4,0 C,.4,3,1 C,.2,4,1 C,.2,4,0 C,.4,3,1 C,.2,4,1 C,.2,4,0 C,.4,3,1 C,.2,4,1 C,.2,3,1 C,.2,3,1 C,.2,3,1 C,.2,3,1 F,.8,3,1 G,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 C,.4,4,0 A,.4,3,1 C,.4,4,0 A,.4,3,1 C,.2,4,0 A,.2,3,1 D,.2,4,1 A,.2,3,1 A#,.2,3,1 G,.4,3,0 E,.4,3,1 G,.4,3,0 E,.4,3,1 G,.2,3,0 E,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.2,3,1 F,.2,4,1 E,.2,4,1 D,.2,4,1 C,.2,4,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.8,3,1 G,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 C,.4,4,0 A,.4,3,1 C,.4,4,0 A,.4,3,1 C,.2,4,0 A,.2,3,1 D,.2,4,1 A,.2,3,1 A#,.2,3,1 G,.4,3,0 E,.4,3,1 G,.4,3,0 E,.4,3,1 G,.2,3,0 E,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.2,3,1 C,.2,4,0 A,.2,3,1 G,.2,3,0 E,.2,3,1 A,.2,3,1 F,.2,3,1 R,.2,3,1 C,.4,3,1 F,.8,3,1 G,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 c,.4,4,0 A,.4,3,1 C,.4,4,0 A,.4,3,1 C,.2,4,0 A,.2,3,1 D,.2,4,1 A,.2,3,1 A#,.2,3,1 G,.4,3,0 E,.4,3,1 G,.4,3,0 E,.4,3,1 G,.2,3,0 E,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.2,3,1 F,.2,4,1 E,.2,4,1 D,.2,4,1 C,.2,4,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.8,3,1 G,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 C,.4,4,0 A,.4,3,1 C,.4,4,0 A,.4,3,1 C,.2,4,0 A,.2,3,1 D,.2,4,1 A,.2,3,1 A#,.2,3,1 G,.4,3,0 E,.4,3,1 G,.4,3,0 E,.4,3,1 G,.2,3,0 E,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.2,3,1 C,.2,4,0 A,.2,3,1 G,.2,3,0 E,.2,3,1 A,.2,3,1 F,.2,3,1 R,.2,3,1 F,.2,3,1 R,.2,3,1 G,.2,3,1 D,.2,4,1 D,.2,4,1 E,.2,4,1 D,.2,4,1 C,.2,4,1 C,.2,4,1 E,.2,4,1 F,.2,4,1 A,.2,4,1 C,.2,5,1 A,.2,4,1 A,.2,4,1 G,.2,4,1 G,.4,4,1 A,.2,4,1 A#,.2,3,1 A#,.2,3,1 A,.2,4,1 G,.2,4,1 C,.2,4,1 C,.2,4,1 E,.2,4,1 E,.2,4,0 G,.2,3,1 D,.2,4,0 A#,.2,3,1 E,.2,4,0 G,.2,3,1 D,.2,4,0 A#,.2,3,1 E,.2,4,0 G,.2,3,1 D,.2,4,0 A#,.2,3,1 E,.2,4,0 G,.2,3,1 D,.2,4,0 A#,.2,3,1 G,.2,3,1 D,.2,4,1 D,.2,4,1 E,.2,4,1 D,.2,4,1 C,.2,4,1 C,.2,4,1 E,.2,4,1 F,.2,4,1 A,.2,4,1 C,.2,5,1 A,.2,4,1 A,.2,4,1 G,.2,4,1 G,.4,4,1 A,.2,4,1 A#,.2,3,1 A#,.2,3,1 A,.2,4,1 G,.2,4,1 C,.2,4,1 C,.2,4,1 E,.2,4,1 E,.2,4,0 G,.2,3,1 D,.2,4,0 A#,.2,3,1 E,.2,4,0 G,.2,3,1 D,.2,4,0 A#,.2,3,1 E,.2,4,0 F,.2,3,1 D,.2,4,0 C,.2,3,1 C,.4,4,0 C,.4,3,1 E,.4,4,1 C,.4,4,1 A,.4,3,1 G,.4,3,1 G,.2,4,1 D,.2,4,1 E,.2,4,1 F,.2,4,1 E,.2,4,1 D,.2,4,1 C,.4,4,1 E,.4,4,1 C,.4,4,1 A,.4,3,1 G,.4,3,1 F#,.2,3,1 G,.2,3,1 A,.2,3,1 A#,.2,3,1 D,.2,4,1 C,.2,4,1 C,.4,4,1 E,.4,4,1 C,.4,4,1 A,.4,3,1 G,.4,3,1 G,.2,4,1 D,.2,4,1 E,.2,4,1 F,.2,4,1 E,.2,4,1 D,.2,4,1 C,.4,4,1 E,.4,4,1 C,.4,4,1 A,.4,3,1 G,.4,3,1 F#,.2,3,1 G,.2,3,1 A,.2,3,1 A#,.2,3,1 C,.2,4,0 C,.4,3,1 G,.2,3,1 B,.2,3,0 D,.4,3,1 G,.2,3,1 C,.2,4,0 C,.4,3,1 G,.2,3,1 B,.2,3,0 D,.4,3,1 G,.2,3,1 C,.2,4,0 C,.4,3,1 C,.2,4,1 C,.2,4,0 C,.4,3,1 C,.2,4,1 C,.2,4,0 C,.4,3,1 C,.2,4,1 C,.2,4,0 C,.4,3,1 C,.2,4,1 C,.2,3,1 C,.2,3,1 C,.2,3,1 C,.2,3,1 F,.8,3,1 G,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 C,.4,4,0 A,.4,3,1 C,.4,4,0 A,.4,3,1 C,.2,4,0 A,.2,3,1 D,.2,4,1 A,.2,3,1 A#,.2,3,1 G,.4,3,0 E,.4,3,1 G,.4,3,0 E,.4,3,1 G,.2,3,0 E,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.2,3,1 F,.2,4,1 E,.2,4,1 D,.2,4,1 C,.2,4,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.8,3,1 G,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 C,.4,4,0 A,.4,3,1 C,.4,4,0 A,.4,3,1 C,.2,4,0 A,.2,3,1 D,.2,4,1 A,.2,3,1 A#,.2,3,1 G,.4,3,0 E,.4,3,1 G,.4,3,0 E,.4,3,1 G,.2,3,0 E,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.2,3,1 C,.2,4,0 A,.2,3,1 G,.2,3,0 E,.2,3,1 A,.2,3,1 F,.2,3,1 R,.2,3,1 C,.4,3,1 F,.8,3,1 G,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 c,.4,4,0 A,.4,3,1 C,.4,4,0 A,.4,3,1 C,.2,4,0 A,.2,3,1 D,.2,4,1 A,.2,3,1 A#,.2,3,1 G,.4,3,0 E,.4,3,1 G,.4,3,0 E,.4,3,1 G,.2,3,0 E,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.2,3,1 F,.2,4,1 E,.2,4,1 D,.2,4,1 C,.2,4,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.8,3,1 G,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 C,.4,4,0 A,.4,3,1 C,.4,4,0 A,.4,3,1 C,.2,4,0 A,.2,3,1 D,.2,4,1 A,.2,3,1 A#,.2,3,1 G,.4,3,0 E,.4,3,1 G,.4,3,0 E,.4,3,1 G,.2,3,0 E,.2,3,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.2,3,1 C,.2,4,0 A,.2,3,1 G,.2,3,0 E,.2,3,1 A,.2,3,1 F,.4,3,1 F,.4,3,1 G,.4,3,1 A,.4,3,1 C,.2,4,1 A#,.2,3,1 E,.2,4,1 D,.2,4,1 C,.2,4,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.4,3,1 F,.4,3,1 G,.4,3,1 A,.4,3,1 C,.2,4,1 A#,.2,3,1 E,.2,4,1 D,.2,4,1 C,.2,4,1 A#,.2,3,1 A,.2,3,1 G,.2,3,1 F,.2,3,1 C,.2,4,1 G,.2,3,1 A,.2,3,1 F,.2,3,1 C,.2,4,1 G,.2,3,1 A,.2,3,1 F,.2,3,1 C,.2,4,1 G,.2,3,1 A,.2,3,1 F,.2,3,1 C,.2,4,1 G,.2,3,1 A,.2,3,1 F,.2,3,1 R,.2,3,1 R,.4,2,1 F,.2,3,1 R,.2,3,1 R,.4,2,1 F,1,3,1 R,.8,3,1 C,.2,4,0 A#,.2,3,1 R,.6,3,1 F,.2,4,0 F,.2,3,1 R,.6,3,1
    PS: The blank lines just mean I went to another measure... Now for me and Mr. Muskrat to get together and make it so all you have to do is say if a note is a whole, quater and so forth and be able to put in the count and speed... also the ability to make it auto repeat at a certain line might be nice... This is good for those who wanna write music I guess or for those who are just bored out of their mind like I am :-P

    -----------------------
    Billy S.
    Slinar Hardtail - Hand of Dane
    Datal Ephialtes - Guildless
    RallosZek.Net Admin/WebMaster

    perl -le '$cat = "cat"; if ($cat =~ /\143\x61\x74/) { print "Its a cat +!\n"; } else { print "Thats a dog\n"; }'

      Okay, I don't know the name of the original musical score but I do know one song that adds words to it. Picnic of the World. It's a great song for kids. We listen to it all the time here.