#!/usr/bin/perl -w

# ./init_data.pl train_data

use strict;
use File::Basename;

if (@ARGV != 1) {
    print STDERR "Usage: init_data.pl <training data dir>\n";
    exit 2;
}

my ($train_data) = @ARGV;

if (! -d $train_data) {
    print STDERR "Training data directory '$train_data' not found\n";
    exit 2;
}

my $tmpdir = "tmp";
if (! -d $tmpdir) {
    mkdir $tmpdir;
}

# Figure out which label and sound files to use

print "Figuring out which sound files are transcribed...\n";

my @labelfiles = glob "$train_data/*.lab";
my @allsoundfiles = glob "$train_data/*.wav";
my @soundfiles = ();
foreach (@allsoundfiles) {
    (my $l = $_) =~ s/\.wav$/.lab/;
    if (! -f $l) {
	print STDERR "No transcription for $_, skipping.\n";
    } elsif ((stat($l))[7] == 0) {
	print STDERR "Transcription for $_ is empty, skipping.\n";
    } else {
	push @soundfiles, $_;
    }
}

printf("Using %d out of %d files.\n", 
       scalar(@soundfiles), 
       scalar(@allsoundfiles));

# Create a list of all the phones used in the training data.

print "Creating monophone list from training data...\n";

my %monophones = ();
foreach my $labf (@labelfiles) {
    open LABF, $labf;
    while (<LABF>) {
	chomp;
	s/^\d+\s+\d+\s+(\S+).*$/$1/;
	$monophones{$_} = 1;
    }
    close LABF;
}

open MONO, ">$tmpdir/monophones";
foreach (sort (keys %monophones)) {
    print MONO "$_\n";
}
close MONO;


# Decide on a parametrization configuration. Currently this
# uses the fixed configuration recommended in the HTK tutorial.

print "Parametrizing training data...\n";

open PARAM_CONFIG, ">$tmpdir/param_config";
print PARAM_CONFIG<<END;
SOURCEFORMAT = WAV
TARGETKIND = MFCC_0
TARGETRATE = 100000.0
SAVECOMPRESSED = T
SAVEWITHCRC = T
WINDOWSIZE = 250000.0
USEHAMMING = T
PREEMCOEF = 0.97
NUMCHANS = 26
CEPLIFTER = 22
NUMCEPS = 12
ENORMALISE = F
END
close PARAM_CONFIG;

open PARAM_CONFIG, "$tmpdir/param_config";
open TRAIN_CONFIG, ">$tmpdir/train_config";
while (<PARAM_CONFIG>) {
    if (/^TARGETKIND/) {
	print TRAIN_CONFIG "TARGETKIND = MFCC_0_D_A\n";
    } elsif (!/^SOURCEFORMAT/) {
	print TRAIN_CONFIG;
    }
}
close TRAIN_CONFIG;
close PARAM_CONFIG;

# Create a simple prototype model to start each model from.

print "Creating prototype model...\n";

open PROTO, ">$tmpdir/proto";
print PROTO<<END;
~o <VecSize> 39 <MFCC_0_D_A>
~h "proto"
<BeginHMM>
     <NumStates> 5
     <State> 2
        <Mean> 39
          0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
        <Variance> 39
          1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
     <State> 3
        <Mean> 39
          0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
        <Variance> 39
          1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
     <State> 4
        <Mean> 39
          0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
        <Variance> 39
          1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
     <TransP> 5
      0.0 1.0 0.0 0.0 0.0
      0.0 0.6 0.4 0.0 0.0
      0.0 0.0 0.6 0.4 0.0
      0.0 0.0 0.0 0.7 0.3
      0.0 0.0 0.0 0.0 0.0
<EndHMM>
END
close PROTO;



# Parametrize the recorded data.

mkdir "$tmpdir/train_param";

open CODETR, ">$tmpdir/codetr.scp";
open TRAIN, ">$tmpdir/train.scp";
foreach my $u (@soundfiles) {
    my ($f,$dir,$ext) = fileparse($u, qr/\.[^.]*/);
    my $mfc = "$tmpdir/train_param/$f.mfc";
    print CODETR "$u $mfc\n";
    print TRAIN "$mfc\n";
}
close TRAIN;
close CODETR;

run("HCopy32 -C $tmpdir/param_config -S $tmpdir/codetr.scp");





sub run {
    my $command = shift;
    print "$command\n";
    system($command) == 0 || die "Failed: $?";
}

sub replace_ext {
  return (fileparse($_[0], qr/\.[^.]*/))[0] . "." . $_[1];
}
