My progress on converting MIDI files to a music score with MIDI::Perl

[email protected] ("Charles Cave") Fri, 25 Jul 2003 08:36:09 +1000
Newsgroups perl.midi
Message-ID <[email protected]>
I have written the following program to extract the notes
from a MIDI file, but now I need to understand "delta" times
to work out the note durations and covert to whole note/half note/
quarter notes as well as allocating the notes to measures (bars).

My next area to understand is the meaning of the parameters
of the note_on event and how to convert "deltas" into note durations.
How does the duration of the note (in ticks) relate to the Ticks
paramater 192 at the header?  I am reviewing the MIDI::Event doco
but need more information and examples.


First of all, there is the MUP file to create the score
and MIDI file:

// Minuet in G
// JS Bach - "Children's Bach"

score
	time=3/4
	key=1#
	staffs=2
	beamstyle=4,4,4

   staff 2
	clef=bass

music
// measure 1
1: 8g; b; d+; g+; a; f+;
2: 2g; 4d;
bar

// measure 2
1: 4g+; g; g;
2: 8g-; b-; d; g; d; b-;
bar

// measure 3
1: 8g; b; d+; g+; a; f+;
2: 2g-; 4d;
bar

// measure 4
1: 4g+; g; g;
2: 8g-; b-; d; g; d; b-;
bar

// measure 5
1: 4e+; ; 8e+; g+;
2: c; g; c;
bar

// measure 6
1: 4d+; ; 8d+; g+;
2: 4b-; 4g; 4b-;
bar


// Start printed row 2

// measure 7
1: 4c+; 8d+; c+; b; c+;
2: 4a; f; g;
bar

// measure 8
1: 2.a;
2: 8d; e; f; d; e; f;
bar

--------------------------------------------------

Here is my Perl program "midi_sniffer.pl"

#!perl -w
#
# midi_sniffer.pl 22nd July 2003
# Author: Charles Cave     [email protected]
#
# Reads a Midi file and outputs the information for each track
# in such a way that a score can be constructed

use strict;
use MIDI;

my($midfile) = shift();
unless (defined($midfile)) { die "Syntax is midi_sniffer.pl
midifilename\n"; }

my $opus = MIDI::Opus->new({ 'from_file' => $midfile });

my(@tracklist) = $opus->tracks;
# each element of @tracklist is a reference to a hash

print "There are    ", scalar(@tracklist), " tracks\n";
print "Ticks:       ", $opus->ticks(), "\n";
print "MIDI format: ", $opus->format(), "\n";

my($track, @event_list);
my($track_ctr) = 0;
foreach $track (@tracklist) {
   print "\nTrack No: $track_ctr\n";
   $track_ctr++;
   @event_list = $track->events();
   print scalar(@event_list), " events in the track\n";
   my($event, $val);
   foreach $event (@event_list) {
       print "  ";   # to indent the event information
       # each event is an array reference
       foreach $val (@$event) {
          print "$val ";
       }
       print "\n";
   }
}


--------------------------------

And here is it's output...

There are    3 tracks
Ticks:       192
MIDI format: 1

Track No: 0
3 events in the track
  set_tempo 0 500000
  key_signature 0 1 0
  time_signature 0 3 2 24 8

Track No: 1
64 events in the track
  note_on 0 0 67 64
  note_on 89 0 67 0
  note_on 7 0 71 64
  note_on 89 0 71 0
  note_on 7 0 74 64
  note_on 89 0 74 0
  note_on 7 0 79 64
  note_on 89 0 79 0
  note_on 7 0 69 64
  note_on 89 0 69 0
  note_on 7 0 78 64
  note_on 89 0 78 0
  note_on 7 0 79 64
  note_on 185 0 79 0
  note_on 7 0 67 64
  note_on 185 0 67 0
  note_on 7 0 67 64
  note_on 185 0 67 0
  note_on 7 0 67 64
  note_on 89 0 67 0
  note_on 7 0 71 64
  note_on 89 0 71 0
  note_on 7 0 74 64
  note_on 89 0 74 0
  note_on 7 0 79 64
  note_on 89 0 79 0
  note_on 7 0 69 64
  note_on 89 0 69 0
  note_on 7 0 78 64
  note_on 89 0 78 0
  note_on 7 0 79 64
  note_on 185 0 79 0
  note_on 7 0 67 64
  note_on 185 0 67 0
  note_on 7 0 67 64
  note_on 185 0 67 0
  note_on 7 0 76 64
  note_on 185 0 76 0
  note_on 7 0 76 64
  note_on 185 0 76 0
  note_on 7 0 76 64
  note_on 89 0 76 0
  note_on 7 0 79 64
  note_on 89 0 79 0
  note_on 7 0 74 64
  note_on 185 0 74 0
  note_on 7 0 74 64
  note_on 185 0 74 0
  note_on 7 0 74 64
  note_on 89 0 74 0
  note_on 7 0 79 64
  note_on 89 0 79 0
  note_on 7 0 72 64
  note_on 185 0 72 0
  note_on 7 0 74 64
  note_on 89 0 74 0
  note_on 7 0 72 64
  note_on 89 0 72 0
  note_on 7 0 71 64
  note_on 89 0 71 0
  note_on 7 0 72 64
  note_on 89 0 72 0
  note_on 7 0 69 64
  note_on 569 0 69 0

Track No: 2
62 events in the track
  note_on 0 0 55 64
  note_on 377 0 55 0
  note_on 7 0 50 64
  note_on 185 0 50 0
  note_on 7 0 43 64
  note_on 89 0 43 0
  note_on 7 0 47 64
  note_on 89 0 47 0
  note_on 7 0 50 64
  note_on 89 0 50 0
  note_on 7 0 55 64
  note_on 89 0 55 0
  note_on 7 0 50 64
  note_on 89 0 50 0
  note_on 7 0 47 64
  note_on 89 0 47 0
  note_on 7 0 43 64
  note_on 377 0 43 0
  note_on 7 0 50 64
  note_on 185 0 50 0
  note_on 7 0 43 64
  note_on 89 0 43 0
  note_on 7 0 47 64
  note_on 89 0 47 0
  note_on 7 0 50 64
  note_on 89 0 50 0
  note_on 7 0 55 64
  note_on 89 0 55 0
  note_on 7 0 50 64
  note_on 89 0 50 0
  note_on 7 0 47 64
  note_on 89 0 47 0
  note_on 7 0 48 64
  note_on 185 0 48 0
  note_on 7 0 55 64
  note_on 185 0 55 0
  note_on 7 0 48 64
  note_on 185 0 48 0
  note_on 7 0 47 64
  note_on 185 0 47 0
  note_on 7 0 55 64
  note_on 185 0 55 0
  note_on 7 0 47 64
  note_on 185 0 47 0
  note_on 7 0 57 64
  note_on 185 0 57 0
  note_on 7 0 54 64
  note_on 185 0 54 0
  note_on 7 0 55 64
  note_on 185 0 55 0
  note_on 7 0 50 64
  note_on 89 0 50 0
  note_on 7 0 52 64
  note_on 89 0 52 0
  note_on 7 0 54 64
  note_on 89 0 54 0
  note_on 7 0 50 64
  note_on 89 0 50 0
  note_on 7 0 52 64
  note_on 89 0 52 0
  note_on 7 0 54 64
  note_on 89 0 54 0
MIN.MID (audio/mid, 621 B) - not displayed