]> icculus.org git repositories - divverent/nexuiz.git/blob - misc/tools/midichannels.pl
midi: better channel handling
[divverent/nexuiz.git] / misc / tools / midichannels.pl
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5 use MIDI;
6 use MIDI::Opus;
7
8 my ($filename) = @ARGV;
9 my $opus = MIDI::Opus->new({from_file => $filename});
10
11 my %chanpos = (
12         note_off => 2,
13         note_on => 2,
14         key_after_touch => 2,
15         control_change => 2,
16         patch_change => 2,
17         channel_after_touch => 2,
18         pitch_wheel_change => 2
19 );
20
21 while(<STDIN>)
22 {
23         chomp;
24         my @arg = split /\s+/, $_;
25         my $cmd = shift @arg;
26         print "Executing: $cmd @arg\n";
27         if($cmd eq 'ticks')
28         {
29                 if(@arg)
30                 {
31                         $opus->ticks($arg[0]);
32                 }
33                 else
34                 {
35                         print "Ticks: ", $opus->ticks(), "\n";
36                 }
37         }
38         elsif($cmd eq 'tricks')
39         {
40                 print "haha, very funny\n";
41         }
42         elsif($cmd eq 'tracks')
43         {
44                 my $tracks = $opus->tracks_r();
45                 if(@arg)
46                 {
47                         my %taken = (0 => 1);
48                         my @t = ($tracks->[0]);
49                         for(@arg)
50                         {
51                                 next if $taken{$_}++;
52                                 push @t, $tracks->[$_];
53                         }
54                         $opus->tracks_r(\@t);
55                 }
56                 else
57                 {
58                         for(1..@$tracks-1)
59                         {
60                                 print "Track $_:";
61                                 my $name = undef;
62                                 my %channels = ();
63                                 my $notes = 0;
64                                 for($tracks->[$_]->events())
65                                 {
66                                         my $p = $chanpos{$_->[0]};
67                                         if(defined $p)
68                                         {
69                                                 my $c = $_->[$p] + 1;
70                                                 ++$channels{$c};
71                                         }
72                                         ++$notes if $_->[0] eq 'note_on';
73                                         $name = $_->[2] if $_->[0] eq 'track_name';
74                                 }
75                                 my $channels = join " ", sort keys %channels;
76                                 print " $name" if defined $name;
77                                 print " (channel $channels)" if $channels ne "";
78                                 print " ($notes notes)" if $notes;
79                                 print "\n";
80                         }
81                 }
82         }
83         elsif($cmd eq 'save')
84         {
85                 $opus->write_to_file($arg[0]);
86         }
87         else
88         {
89                 print "Unknown command, allowed commands: ticks, tricks, tracks, save\n";
90         }
91         print "Done with: $cmd @arg\n";
92 }