#!/usr/bin/perl -w
# Wrap raw PCM samples into .wav file
use strict;
undef $/;

my $numchan=2;
$numchan=shift @ARGV if(1<@ARGV and "-c" eq $ARGV[0] and $ARGV[1] =~ /^[1-9]\d*$/s and shift @ARGV);
my $swab=0;
$swab=shift @ARGV if(@ARGV and "-e" eq $ARGV[0]);
my $rate=44100;
$rate=shift @ARGV if(1<@ARGV and "-r" eq $ARGV[0] and $ARGV[1] =~ /^[1-9]\d*$/s and shift @ARGV);
my $sampsize=2;
$sampsize=shift @ARGV if(1<@ARGV and "-s" eq $ARGV[0] and $ARGV[1] =~ /^[1-9]\d*$/s and shift @ARGV);
die <<"EOD" unless(2==@ARGV and ("-" eq $ARGV[0] or -f $ARGV[0]));
usage: $0 [-e] [-crs <#>] <in.raw_or_-> <out.wav>
	-c <#>	number of channels (default: $numchan)
	-e    	input samples are in big-endian format
	-r <#>	samples/sec (default: $rate)
	-s <#>	bytes/sample (default: $sampsize)
EOD
my $outfile=pop @ARGV;
die "too many channels" if(0xFFFF<$numchan);
die "sample rate too fast" if(0xFFFFFFFF<$rate);
die "frame size too big" if(0xFFFF<$numchan*$sampsize);
die "byte rate too high" if(0xFFFFFFFF<$rate*$numchan*$sampsize);
die "sample size too big" if(0xFFFF<8*$sampsize);

my $data=<>;
die "non-integer number of samples" if(length($data)%($numchan*$sampsize));
die "file size too big" if(0xFFFFFFFF<=length($data));
my $datahead="data".pack("V",length($data));
my $pad=(0==length($data)%2)?"":"\0";
if($swab and 1<$sampsize) {
	for(my $i=0;$i<length($data);$i+=$sampsize) {
		substr($data,$i,$sampsize)=reverse(substr($data,$i,$sampsize));
	}
}

my $fmthead="fmt ".pack("VvvVVvv",16,1,$numchan,$rate,$rate*$numchan*$sampsize,$numchan*$sampsize,$sampsize*8);

my $riffhead="RIFF".pack("V",4+length($fmthead)+length($datahead)+length($data)+length($pad))."WAVE";

open(OUT,">",$outfile) or die "open: $!";
print OUT $riffhead,$fmthead,$datahead,$data,$pad or die;
close(OUT) or die;
0;
