#!/usr/bin/perl
use lib "/home/ttamura/perl/lib/perl5/site_perl/5.8.0/";
use MIDI;
#use strict;
#use warnings;
require "midihelper.pl";
#$patch="Music Box";
$patch="Acoustic Grand";
$num_tracks=14;
my @events = (
  ['patch_change',0, 0, $::patch2number{$patch}],
  ['patch_change',0, 1, $::patch2number{$patch}],
  ['patch_change',0, 2, $::patch2number{$patch}],
  ['patch_change',0, 3, $::patch2number{$patch}],
  ['patch_change',0, 4, $::patch2number{$patch}],
  ['patch_change',0, 5, $::patch2number{$patch}],
  ['patch_change',0, 6, $::patch2number{$patch}],
  ['patch_change',0, 7, $::patch2number{$patch}],
  ['patch_change',0, 8, $::patch2number{$patch}],
  ['patch_change',0, 10, $::patch2number{$patch}],
  ['patch_change',0, 11, $::patch2number{$patch}],
  ['patch_change',0, 12, $::patch2number{$patch}],
  ['patch_change',0, 13, $::patch2number{$patch}],
  ['patch_change',0, 14, $::patch2number{$patch}],
  ['patch_change',0, 15, $::patch2number{$patch}],
  ['set_tempo', 0, 450_000], # 1qn = .45 seconds
);
for($i=0;$i<16;$i++){
	push @events,
	  ['control_change', 0, $i, 100, 0],
	  ['control_change', 0, $i, 101, 0],
	  ['control_change', 0, $i, 6, 12];
}

@tracks=(0,1,2,3,4,5,6,7,8,10,11,12,13,14,15);
$column=0;
$max=-1e200;
$min=1e200;
$speed=1;
$base_note=72;
$timecol=-1;
while($ARGV[0]=~/^-/){
	if ($ARGV[0] eq "--column"){
		shift;
		$column=$ARGV[0];
		shift;
	}
	if ($ARGV[0] eq "--max"){
		shift;
		$max=$ARGV[0];
		shift;
	}
	if ($ARGV[0] eq "--speed"){
		shift;
		$speed=$ARGV[0];
		$speed=0.001 if $speed<0;
		shift;
	}
	if ($ARGV[0] eq "--tune"){
		shift;
		$tunecol=$ARGV[0];
		shift;
	}
	if ($ARGV[0] eq "--velocity"){
		shift;
		$velocitycol=$ARGV[0];
		shift;
	}
	if ($ARGV[0] eq "--time"){
		shift;
		$timecol=$ARGV[0]-1;
		shift;
	}
	if ($ARGV[0] eq "--tracks"){
		shift;
		$num_tracks=$ARGV[0];
		shift;
	}
	if ($ARGV[0] eq "--log"){
		shift;
		$logcol=$ARGV[0];
		shift;
	}
}
	
$lines=0;
$time0=-1e200;
while(<>){
	next if /^#/;
	s/^\s+//;
	my @cols;
	@cols=split(/\s+/);
	if ($timecol>-1){
		my $time=$cols[$timecol];
		$time0=$time if $time0==-1e200;
		my $dtime=int(($time-$time0)*$speed);
		unshift @cols, $dtime;
		$time0+=$dtime/$speed;
	} else {
		unshift @cols, $speed;
	}
	for($k=1;$k<=$#cols;$k++){
		my $value=$cols[$k];
		if ($k == $logcol){
			$value=log($value);
			$cols[$k]=$value;
		}
		if ($max[$k] eq "" or $max[$k]<$value){$max[$k]=$value};
		if ($min[$k] eq "" or $min[$k]>$value){$min[$k]=$value};
	}
	push @sequence, [@cols];
	$lines++;
}

#print "\n\nmax: ", log($max), "; min: ", log($min),"\n";
for ($i=1;$i<=$#max;$i++){
	$delta[$i]=1/($max[$i]-$min[$i]);
}

$track=0;
for ($i=0;$i<$lines;$i++){
		my $dtime=$sequence[$i][0];
		my $value=$sequence[$i][$tunecol];
		my $velocity0;
		my $velocity;
		my $bend=int(8191*(($value-$min[$tunecol])*2*$delta[$tunecol]-1));
		if ($velocitycol){
			$velocity0=$sequence[$i][$velocitycol];
			$velocity=int(127*($velocity0-$min[$velocitycol])*$delta[$velocitycol]);
		} else {
			$velocity=120;
		}
		print "$tunecol, $dtime, $velocity, $velocity0, $max[$velocitycol], $min[$velocitycol], 2*8192*$delta[$tunecol], $tracks[$track], $bend\n";
		push @events,
			#note_on duration ch note velocity
			['note_off' , $dtime,  $tracks[$track], $base_note, $velocity];
		push @events, ['pitch_wheel_change' ,0 ,  $tracks[$track], $bend];
		push @events,
			#note_on duration ch note velocity
			['note_on' , 0,  $tracks[$track], $base_note, $velocity];
		#push @events,
			##note_on duration ch note velocity
			#['note_off' , 0,  $tracks[$track], $base_note, $velocity];
	$track=($track+1)%$num_tracks;
}

   push @events,
['note_off',  1000,  0, $base_note, 127];
for (my $column=1;$column<=15;$column++){
   push @events,
     ['note_off',  0,  $column, $base_note, 127],
   ;
}
 my $cowbell_track = MIDI::Track->new({ 'events' => \@events });
 my $opus = MIDI::Opus->new(
  { 'format' => 0, 'ticks' => 96, 'tracks' => [ $cowbell_track ] } );
 $opus->write_to_file( 'out.mid' );
