#!/usr/bin/perl
use warnings;
use strict;

unless ($ARGV) {
    print "usage: $0 { simon.voc | effects.voc }\n";
    exit(0);
}

my $infile = $ARGV[0];
my $num;

if ($infile =~ /simon.voc$/) {
    $num = 3624;
} elsif ($infile =~ /effects.voc$/) {
    $num = 141;
} else {
    die "Unknown file\n";
}

my $tmpfile = 'tmp.voc';
my $tmpoutfile_all = 'tmpall.mp3';

system("rm $tmpoutfile_all") if stat($tmpoutfile_all);

my $outfile = $infile;
$outfile =~ s/\.voc$/.mp3/;

my $tmpoutfile = $tmpfile;
$tmpoutfile =~ s/\.voc$/.mp3/;

if (stat($outfile)) {
    die "$outfile: File exists. Exiting\n";
}

open(IN, "<$infile") || die "Could not open file: $infile\n";
binmode(IN);

my @offsets;
my @new_offsets;

my $buf;
my $i;

for ($i = 0; $i < $num; $i++) {
    seek(IN, $i * 4, 0);
    read(IN, $buf, 4);

    $offsets[$i] = unpack('L', $buf);
}
$offsets[$i] = (stat(IN))[7];

$new_offsets[0] = 0;
$new_offsets[1] = $num * 4;

my @hdr;
my $size;
my $samplerate;

for ($i = 1; $i < $num; $i++) {
    if ($offsets[$i] == $offsets[$i + 1]) {
        $new_offsets[$i + 1] = $new_offsets[$i];
        next;
    }

    seek(IN, $offsets[$i], 0);
    read(IN, $buf, 32);

    @hdr = unpack('a20SSSCC3CC', $buf);
    undef $buf;

    if ($hdr[0] eq "Creative Voice File\x1A") {
        printf("Audio found at offset: %x\n", $offsets[$i]);
    } else {
        printf("ERROR: No audio found at offset: %x\n", $offsets[$i]);
        die "Exiting.\n";
    }

    $size = $hdr[5] + ($hdr[6] << 8) + ($hdr[7] << 16) - 2;
    $samplerate = int(1000000/(256-$hdr[8]));

    read(IN, $buf, $size);

    open(TMP, ">$tmpfile");
    binmode(TMP);
    print TMP $buf;
    close(TMP);
    undef $buf;

    system("lame -t -q 5 -V 4 -B 64 --resample 22.05 -m m -r -s $samplerate --bitwidth 8 $tmpfile $tmpoutfile");
    system("cat $tmpoutfile >> $tmpoutfile_all");

    $new_offsets[$i + 1] = $new_offsets[$i] + (stat($tmpoutfile))[7];

}
pop(@new_offsets);

close(IN);

open(OUT, ">$outfile");
binmode(OUT);
foreach (@new_offsets) {
    print OUT pack('L', $_);
}
close(OUT);   

system("cat $tmpoutfile_all >> $outfile");

exit(0);
