[nexuiz-commits] r6939 - trunk/misc/tools

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Tue Jun 9 07:19:59 EDT 2009


Author: div0
Date: 2009-06-09 07:19:58 -0400 (Tue, 09 Jun 2009)
New Revision: 6939

Added:
   trunk/misc/tools/midichannels.pl
Modified:
   trunk/misc/tools/midi2bgs.pl
   trunk/misc/tools/midi2cfg.pl
Log:
midi: better channel handling


Modified: trunk/misc/tools/midi2bgs.pl
===================================================================
--- trunk/misc/tools/midi2bgs.pl	2009-06-09 10:17:01 UTC (rev 6938)
+++ trunk/misc/tools/midi2bgs.pl	2009-06-09 11:19:58 UTC (rev 6939)
@@ -103,7 +103,7 @@
 		unless $trackno < 0 || $trackno == $track;
 	if($_->[0] eq 'note_on')
 	{
-		my $chan = $_->[4];
+		my $chan = $_->[4] + 1;
 		my $note = sprintf $notepattern, $notenames[$_->[5]], $trackno, $channelno;
 		my $velocity = $_->[6] / 127.0;
 		push @outevents, [$note, $t, $velocity]
@@ -114,7 +114,7 @@
 	}
 	elsif($_->[0] eq 'note_off')
 	{
-		my $chan = $_->[4];
+		my $chan = $_->[4] + 1;
 		my $note = sprintf $notepattern, $notenames[$_->[5]], $trackno, $channelno;
 		my $velocity = $_->[6] / 127.0;
 		--$notecounters_converted{$note}

Modified: trunk/misc/tools/midi2cfg.pl
===================================================================
--- trunk/misc/tools/midi2cfg.pl	2009-06-09 10:17:01 UTC (rev 6938)
+++ trunk/misc/tools/midi2cfg.pl	2009-06-09 11:19:58 UTC (rev 6939)
@@ -9,6 +9,9 @@
 use MIDI;
 use MIDI::Opus;
 
+use constant MIDI_FIRST_NONCHANNEL => 17;
+use constant MIDI_DRUMS_CHANNEL => 10;
+
 my ($filename, $transpose, $walktime, $staccato, @coords) = @ARGV;
 my @coords_percussion = ();
 my @coords_tuba = ();
@@ -91,17 +94,22 @@
 sub busybot_findfree($$$)
 {
 	my ($time, $vchannel, $note) = @_;
-	my $l = ($vchannel < 16) ? \@busybots_tuba : \@busybots_percussion;
+	my $l = ($vchannel < MIDI_FIRST_NONCHANNEL) ? \@busybots_tuba : \@busybots_percussion;
+	my $c = ($vchannel < MIDI_FIRST_NONCHANNEL) ? \@coords_tuba : \@coords_percussion;
 	for(0..@$l-1)
 	{
 		if(!$l->[$_])
 		{
 			my $bot = {id => $_ + 1, busy => 0, busytime => 0, channel => $vchannel, curtime => -$walktime, curbuttons => 0, noteoffset => 0};
 			$l->[$_] = $bot;
+
+			# let the bot walk to his place
+			printf "m $_ $c->[$_]->[0] $c->[$_]->[1] $c->[$_]->[2]\n";
+
 			return $bot;
 		}
 		return $l->[$_] if
-			(($vchannel < 16) || ($l->[$_]{channel} == $vchannel))
+			(($vchannel < MIDI_FIRST_NONCHANNEL) || ($l->[$_]{channel} == $vchannel))
 			&&
 			!$l->[$_]{busy}
 			&&
@@ -113,7 +121,7 @@
 sub busybot_find($$)
 {
 	my ($vchannel, $note) = @_;
-	my $l = ($vchannel < 16) ? \@busybots_tuba : \@busybots_percussion;
+	my $l = ($vchannel < MIDI_FIRST_NONCHANNEL) ? \@busybots_tuba : \@busybots_percussion;
 	for(0..@$l-1)
 	{
 		return $l->[$_] if
@@ -264,17 +272,14 @@
 sub note_on($$$)
 {
 	my ($t, $channel, $note) = @_;
-	if(busybot_find($channel, $note))
-	{
-		note_off($t, $channel, $note); # MIDI allows redoing a note-on for the same note
-	}
 	++$notes;
-	if($channel == 9)
+	if($channel == MIDI_DRUMS_CHANNEL)
 	{
-		$channel = 16 + $note; # percussion
+		$channel = MIDI_FIRST_NONCHANNEL + $note; # percussion
+		return if !@coords_percussion;
 	}
 	my $bot = busybot_findfree($t, $channel, $note);
-	if($channel < 16)
+	if($channel < MIDI_FIRST_NONCHANNEL)
 	{
 		if(busybot_playnoteandadvance $bot => $t, $note)
 		{
@@ -288,7 +293,7 @@
 			}
 		}
 	}
-	if($channel >= 16)
+	if($channel >= MIDI_FIRST_NONCHANNEL)
 	{
 		busybot_advance $bot => $t;
 		print "p $bot->{id} attack1\n";
@@ -303,14 +308,14 @@
 {
 	my ($t, $channel, $note) = @_;
 	--$notes;
-	if($channel == 9)
+	if($channel == MIDI_DRUMS_CHANNEL)
 	{
-		$channel = 16 + $note; # percussion
+		$channel = MIDI_FIRST_NONCHANNEL + $note; # percussion
 	}
 	my $bot = busybot_find($channel, $note)
 		or return;
 	$bot->{busy} = 0;
-	if($channel < 16)
+	if($channel < MIDI_FIRST_NONCHANNEL)
 	{
 		busybot_stopnoteandadvance $bot => $t, $note;
 		$bot->{busytime} = $t + 0.25;
@@ -320,22 +325,31 @@
 print 'alias p "sv_cmd bot_cmd $1 presskey $2"' . "\n";
 print 'alias r "sv_cmd bot_cmd $1 releasekey $2"' . "\n";
 print 'alias w "sv_cmd bot_cmd $1 wait_until $2"' . "\n";
+print 'alias m "sv_cmd bot_cmd $1 moveto \"$2 $3 $4\""' . "\n";
 
+my %midinotes = ();
 for(@allmidievents)
 {
 	my $t = tick2sec $_->[1];
 	my $track = $_->[3];
 	if($_->[0] eq 'note_on')
 	{
-		my $chan = $_->[4];
-		#next if $chan != 6;
+		my $chan = $_->[4] + 1;
+		if($midinotes{$chan}{$_->[5]})
+		{
+			note_off($t, $chan, $_->[5]);
+		}
 		note_on($t, $chan, $_->[5]);
+		$midinotes{$chan}{$_->[5]} = 1;
 	}
 	elsif($_->[0] eq 'note_off')
 	{
-		my $chan = $_->[4];
-		#next if $chan != 6;
-		note_off($t, $chan, $_->[5]);
+		my $chan = $_->[4] + 1;
+		if($midinotes{$chan}{$_->[5]})
+		{
+			note_off($t, $chan, $_->[5]);
+		}
+		$midinotes{$chan}{$_->[5]} = 0;
 	}
 }
 
@@ -351,5 +365,7 @@
 }
 if($n)
 {
+	use Data::Dumper;
+	print STDERR Dumper \%midinotes;
 	die "$n channels blocked ($notes MIDI notes)";
 }

Added: trunk/misc/tools/midichannels.pl
===================================================================
--- trunk/misc/tools/midichannels.pl	                        (rev 0)
+++ trunk/misc/tools/midichannels.pl	2009-06-09 11:19:58 UTC (rev 6939)
@@ -0,0 +1,92 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use MIDI;
+use MIDI::Opus;
+
+my ($filename) = @ARGV;
+my $opus = MIDI::Opus->new({from_file => $filename});
+
+my %chanpos = (
+	note_off => 2,
+	note_on => 2,
+	key_after_touch => 2,
+	control_change => 2,
+	patch_change => 2,
+	channel_after_touch => 2,
+	pitch_wheel_change => 2
+);
+
+while(<STDIN>)
+{
+	chomp;
+	my @arg = split /\s+/, $_;
+	my $cmd = shift @arg;
+	print "Executing: $cmd @arg\n";
+	if($cmd eq 'ticks')
+	{
+		if(@arg)
+		{
+			$opus->ticks($arg[0]);
+		}
+		else
+		{
+			print "Ticks: ", $opus->ticks(), "\n";
+		}
+	}
+	elsif($cmd eq 'tricks')
+	{
+		print "haha, very funny\n";
+	}
+	elsif($cmd eq 'tracks')
+	{
+		my $tracks = $opus->tracks_r();
+		if(@arg)
+		{
+			my %taken = (0 => 1);
+			my @t = ($tracks->[0]);
+			for(@arg)
+			{
+				next if $taken{$_}++;
+				push @t, $tracks->[$_];
+			}
+			$opus->tracks_r(\@t);
+		}
+		else
+		{
+			for(1..@$tracks-1)
+			{
+				print "Track $_:";
+				my $name = undef;
+				my %channels = ();
+				my $notes = 0;
+				for($tracks->[$_]->events())
+				{
+					my $p = $chanpos{$_->[0]};
+					if(defined $p)
+					{
+						my $c = $_->[$p] + 1;
+						++$channels{$c};
+					}
+					++$notes if $_->[0] eq 'note_on';
+					$name = $_->[2] if $_->[0] eq 'track_name';
+				}
+				my $channels = join " ", sort keys %channels;
+				print " $name" if defined $name;
+				print " (channel $channels)" if $channels ne "";
+				print " ($notes notes)" if $notes;
+				print "\n";
+			}
+		}
+	}
+	elsif($cmd eq 'save')
+	{
+		$opus->write_to_file($arg[0]);
+	}
+	else
+	{
+		print "Unknown command, allowed commands: ticks, tricks, tracks, save\n";
+	}
+	print "Done with: $cmd @arg\n";
+}



More information about the nexuiz-commits mailing list