Re: MIDI question
[email protected] ("Sean M. Burke") Sun, 11 May 2003 15:01:26 -0800
| Newsgroups | perl.midi |
|---|---|
| Message-ID | <[email protected]> |
A new MIDI-Perl user recently asked me how to iterate over events in tracks
in an opus and see which channels were being used.
Here is an example program for that task:
use strict;
use MIDI;
my $in = $ARGV[0] || die "What input file?";
my $opus = MIDI::Opus->new({ 'from_file' => $in });
print "Track count: ", scalar($opus->tracks), "\n";
my $total = 0;
foreach my $t (@{ $opus->tracks_r }) {
my @channels;
$#channels = 15; # preallocate the array
foreach my $e (@{ $t->events_r || next }) {
# Iterate over each event in the track.
#print "@$e\n";
if($e->[0] eq 'note_on') {
# ('note_on', dtime, channel, note, velocity)
$channels[ $e->[2] ] = 1;
#print "@$e\n";
}
}
my @which = grep $channels[$_], 0 .. 15;
my $count = scalar @which;
$total += $count;
print "This track used $count tracks, whose numbers are: @which\n";
}
print "Total tracks used: $total\n";
__END__
Note that we cheat and don't survey all possible events that involve a
track (like patch_change), but just look at the note_on events.
This could possibly be made faster by using special arguments to the ->new,
something like include => ['note_on'] to have the system not even bother to
save any other kinds of events.
--
Sean M. Burke http://search.cpan.org/~sburke/