#general parameters
use Time::HiRes qw (sleep gettimeofday);
use List::Util qw[min max];

$twopi=2*3.141592654;
$samplerate = 44100;
#create wav header for 16 bit, stereo, 44100Hz
	$samples = $samplerate*6*3600; #this makes it 6 hours long...
	$bits = 16;
	$channels = 2;
	$byterate = $samplerate * $channels * $bits / 8;
	$blockalign = $channels * $bits / 8;
	$filesize = $samples * ($bits/8) * $channels + 36;
	$riff = pack('a4Va4','RIFF',$filesize,'WAVE');
	$format = pack('a4VvvVVvv',
	                'fmt ',
	                16,1,
	                $channels,
	                $samplerate,
	                $byterate,
	                $blockalign,
	                $bits);
	$dataChunk = pack('a4V','data',$blockalign * $samples);
	$header = $riff . $format . $dataChunk; 

#preset for first time period:

open (FILE,"<wavgen.txt") || die "Could not open parameter file";
@param = <FILE>;
close FILE;
chomp @param;
($freq1,$freq2,$nh1[1],$nh1[2],$nh1[3],$nh1[4],$nh1[5],$nh1[6],$nh1[7],$nh1[8],$nh1[9],$nh2[1],$nh2[2],$nh2[3],$nh2[4],$nh2[5],$nh2[6],$nh2[7],$nh2[8],$nh2[9],$d1,$d2,$ih1,$ih2,$vol1,$vol2,$chan,$stop)=@param;
for($i=1;$i<=9;$i++){$step1[$i]=$freq1*($twopi/$samplerate)*$i*sqrt(1+$ih1*$i**2);$ph1[$i]=0};
for($i=1;$i<=9;$i++){$step2[$i]=$freq2*($twopi/$samplerate)*$i*sqrt(1+$ih2*$i**2);$ph2[$i]=0};
$count=0;

#open pipe to vlc and write out wav header

#UNCOMMENT THE ONE FOR YOUR SYSTEM:
#$vlcname="\"c:\\Program Files\\VideoLAN\\VLC\\vlc.exe\"";
$vlcname="/cygdrive/c/Program\\ Files/VideoLAN/VLC/vlc.exe";

#system("cat begin.mp3 | $vlcname -");
$vlcpid = open (AFILE,"|$vlcname -") || die "Could not launch $vlcname";
binmode AFILE;
print AFILE $header;

$time=gettimeofday();

#Main loop

LOOP:

if($count>=$samplerate/2){ #write out to pipe enough samples for 1/2 second then check for control updates, and wait if needed

	sleep(max(0,0.51-(gettimeofday()-$time))); # make sure it actually took just over half a second (or buffer gets too long)
	$time=gettimeofday();
#	print "$time\n";
	
	open (FILE,"<wavgen.txt");
	@param = <FILE>;
	close FILE;
	chomp @param;
	($freq1,$freq2,$nh1[1],$nh1[2],$nh1[3],$nh1[4],$nh1[5],$nh1[6],$nh1[7],$nh1[8],$nh1[9],$nh2[1],$nh2[2],$nh2[3],$nh2[4],$nh2[5],$nh2[6],$nh2[7],$nh2[8],$nh2[9],$d1,$d2,$ih1,$ih2,$vol1,$vol2,$chan,$stop)=@param;
	if($stop==1){
		goto STOP
		}elsif($stop==2){
		$vol1=0;
		$vol2=0;
		};
	$count=0;
	@n1array=();
	@n2array=();
	for($i=1;$i<=9;$i++){
	if($nh1[$i]){push (@n1array,$i)};
	if($nh2[$i]){push (@n2array,$i)};
	};
	foreach $i (@n1array){
		$step1[$i]=$freq1*($twopi/$samplerate)*$i*sqrt(1+$ih1*$i**2);
		$ph1[$i]=$ph1[$i]-$twopi*int($ph1[$i]/$twopi);
		};
	foreach $i (@n2array){
		$step2[$i]=$freq2*($twopi/$samplerate)*$i*sqrt(1+$ih2*$i**2);
		$ph2[$i]=$ph2[$i]-$twopi*int($ph2[$i]/$twopi);
		};
	}
$count++;

#Left channel:

$v1=0;
foreach $i (@n1array){
	$ph1[$i] += $step1[$i];
	$v1 += $d1**($i-1)*sin($ph1[$i]);
	};
	$v1 *= $vol1;

#Right channel:

$v2=0;
foreach $i (@n2array){
	$ph2[$i] += $step2[$i];
	$v2 += $d2**($i-1)*sin($ph2[$i]);
	};
	$v2 *= $vol2;

#select channel combination:

if($chan==0){;
	$v2=$v1;
	}elsif($chan==1){
	$v1=$v2;
	}elsif($chan==2){
	$v=$v1+$v2;
	$v1=$v;
	$v2=$v;
	};

#write audio to vlc:

$audio="";
$audio .= pack("ss", $v1, $v2);
print AFILE $audio;

#return to loop:

goto LOOP;

#stop program

STOP:

$param[27]=0; #make sure to reset stop flag so it runs next time
$outline=join("\n",@param);
open (FILE,">wavgen.txt");
print FILE $outline;
close FILE;
kill 23, $vlcpid;  # SIGSTOP
sleep (1);
close AFILE;

exit;