]> git.rm.cloudns.org Git - xonotic/xonotic.git/commitdiff
support sustain pedal events (controller 64, value 0/127)
authorRudolf Polzer <divverent@xonotic.org>
Thu, 8 Dec 2011 14:13:41 +0000 (15:13 +0100)
committerRudolf Polzer <divverent@xonotic.org>
Thu, 8 Dec 2011 14:13:41 +0000 (15:13 +0100)
misc/tools/midi2cfg-ng.pl

index 3e178a24d3463aab4e021da807f0d16d541799f6..2c792744320e76cdb1ac732a7edfb7e79c7dc48e 100755 (executable)
@@ -803,41 +803,97 @@ sub ConvertMIDI($$)
        my %notes_seen = ();
        my %programs = ();
        my $t = 0;
+       my %sustain = ();
+
+       my $note_on = sub
+       {
+               my ($ev) = @_;
+               my $chan = $ev->[4] + 1;
+               ++$notes_seen{$chan}{($programs{$chan} || 1)}{$ev->[5]};
+               if($midinotes{$chan}{$ev->[5]})
+               {
+                       --$notes_stuck;
+                       busybot_note_off($t - SYS_TICRATE - 0.001, $chan, $ev->[5]);
+               }
+               busybot_note_on($t, $chan, $programs{$chan} || 1, $ev->[5]);
+               ++$notes_stuck;
+               $midinotes{$chan}{$ev->[5]} = 1;
+       };
+
+       my $note_off = sub
+       {
+               my ($ev) = @_;
+               my $chan = $ev->[4] + 1;
+               if(exists $sustain{$chan})
+               {
+                       push @{$sustain{$chan}}, $ev;
+                       return;
+               }
+               if($midinotes{$chan}{$ev->[5]})
+               {
+                       --$notes_stuck;
+                       busybot_note_off($t - SYS_TICRATE - 0.001, $chan, $ev->[5]);
+               }
+               $midinotes{$chan}{$ev->[5]} = 0;
+       };
+
+       my $patch_change = sub
+       {
+               my ($ev) = @_;
+               my $chan = $ev->[4] + 1;
+               my $program = $ev->[5] + 1;
+               $programs{$chan} = $program;
+       };
+
+       my $sustain_change = sub
+       {
+               my ($ev) = @_;
+               my $chan = $ev->[4] + 1;
+               if($ev->[6] == 0)
+               {
+                       # release all currently not pressed notes
+                       my $s = $sustain{$chan};
+                       delete $sustain{$chan};
+                       for(@{($s || [])})
+                       {
+                               $note_off->($_);
+                       }
+               }
+               else
+               {
+                       # no more note-off
+                       $sustain{$chan} = [];
+               }
+       };
+
        for(@allmidievents)
        {
                $t = $tick2sec->($_->[1]);
-               my $track = $_->[3];
+               my $track = $_->[3];
                if($_->[0] eq 'note_on')
                {
-                       my $chan = $_->[4] + 1;
-                       ++$notes_seen{$chan}{($programs{$chan} || 1)}{$_->[5]};
-                       if($midinotes{$chan}{$_->[5]})
-                       {
-                               --$notes_stuck;
-                               busybot_note_off($t - SYS_TICRATE - 0.001, $chan, $_->[5]);
-                       }
-                       busybot_note_on($t, $chan, $programs{$chan} || 1, $_->[5]);
-                       ++$notes_stuck;
-                       $midinotes{$chan}{$_->[5]} = 1;
+                       $note_on->($_);
                }
                elsif($_->[0] eq 'note_off')
                {
-                       my $chan = $_->[4] + 1;
-                       if($midinotes{$chan}{$_->[5]})
-                       {
-                               --$notes_stuck;
-                               busybot_note_off($t - SYS_TICRATE - 0.001, $chan, $_->[5]);
-                       }
-                       $midinotes{$chan}{$_->[5]} = 0;
+                       $note_off->($_);
                }
                elsif($_->[0] eq 'patch_change')
                {
-                       my $chan = $_->[4] + 1;
-                       my $program = $_->[5] + 1;
-                       $programs{$chan} = $program;
+                       $patch_change->($_);
+               }
+               elsif($_->[0] eq 'control_change' && $_->[5] == 64) # sustain pedal
+               {
+                       $sustain_change->($_);
                }
        }
 
+       # fake events for releasing pedal
+       for(keys %sustain)
+       {
+               $sustain_change->(['control_change', $t, undef, undef, $_ - 1, 64, 0]);
+       }
+
        print STDERR "For file $filename:\n";
        print STDERR "  Stuck notes: $notes_stuck\n";