dumping scores instead of events

[email protected] ("Sean M. Burke") Sat, 12 Jun 2004 23:17:36 -0800
Newsgroups perl.midi
Message-ID <[email protected]>
At 10:39 AM 2004-06-06, Ramon Schalleck wrote:
>[...] I looked at the examples. I could not find a detailed explanation on 
>how to convert a list that contains the midi events like @events in the 
>example below into a list that contains the score events. [...]

Yes, the MIDI::Score class was about the last part of MIDI-Perl that I 
added, and it definitely has the look of being sort of "tacked on" and 
run-away-from.

(In an ideal world, I would have done something really clever like making a 
track object something that you can look at as an event-list (which is 
really in there) or as a score (which is an abstraction from the 
event-list).  I suppose I could do that by making a $track->score_items 
method that does this:
{
   package MIDI::Track;

   sub score_items { @{ $_[0]->score_items_r } }

   sub score_items_r {
     my $e = $_[0]->events_r || return [];
     return MIDI::Score::events_r_to_score_r( $e ) || [];
   }
}
And then I'd add a warning in the docs like like "if you change the these 
score items, they won't actually change the events in the track!".  I think 
that'd work.  But people would still have to read the MIDI::Score docs to 
see what it all means.)

Anyway, here's two score-dumper programs.  The first is a straightforward 
one that uses the dump_score function:

require 5;
use strict;
use MIDI;
use MIDI::Score;

die "No filename" unless @ARGV;
my $input = $ARGV[0];
my $opus = MIDI::Opus->new( { "from_file" => $input } );
my $count = 0;
foreach my $t ( $opus->tracks ) {
   print "\n## track $count of \"$input\"\n";
   $count++;
   my $score_r = MIDI::Score::events_r_to_score_r( $t->events_r );
   MIDI::Score::dump_score( $score_r );
}



Whereas this one is a bit more verbose but clearer, and dumps only notes 
(ignoring all other score items, like patch_changes, etc.) :

require 5;
use strict;
use MIDI;
use MIDI::Score;

die "No filename" unless @ARGV;
my $input = $ARGV[0];
my $opus = MIDI::Opus->new( { "from_file" => $input } );
my $count = 0;
foreach my $t ( $opus->tracks ) {
   print "\n## track $count of \"$input\"\n";
   $count++;
   my $score_r = MIDI::Score::events_r_to_score_r( $t->events_r );

   my($time, $duration, $channel, $note, $velocity);
   foreach my $n (@$score_r) {
     next unless $n->[0] eq 'note';
     (undef, $time, $duration, $channel, $note, $velocity ) = @$n;
     print "time $time : duration $duration : note $note : ",
       "volume $velocity : channel $channel\n";
   }
}


I hope this helps!

--
Sean M. Burke    http://search.cpan.org/~sburke/