[Subject Prev][Subject Next][Thread Prev][Thread Next][Date Index][Thread Index]

[hts-users:03310] Re: How to improve performance of TTS without manual phoneme alignment


Hi,

I cannot provide you my latest receipts yet (because of various reasons), but, I will give you my old scripts that I had used for the EMIME project. Please find the attachment. You will be able to see my receipts (that I used at that time, 2008 or something) to train the average voice models in a similar conditions (284 speakers x 150 sentences). This will help you to improve the performance/quality of your average voice models. 

Please note that they are old scripts. The options may change in the latest HTS ver 2.2. 

I think that 200 sentences per speaker would be enough, but you would need to increase the amount of training data of average voice models more (3,000 sentences are not enough to train a good average voice models in my experience)

Regards,
Junichi 


Attachment: grid-HTS2010-AdaptiveTrain.sh
Description: Binary data

#!/usr/bin/perl
#$ -S /usr/bin/perl
###########################################################################
## The system as a whole and most of the files in it are distributed      #
## under the following copyright and conditions                           #
##                                                                        #
##                The HMM-based Speech Synthesis Systems                  #
##             for the Blizzard Challenge and EMIME project               #
##                Centre for Speech Technology Research                   #
##                     University of Edinburgh, UK                        #
##                      Copyright (c) 2007-2010                           #
##                        All Rights Reserved.                            #
##                                                                        #
##  Permission is hereby granted, free of charge, to use and distribute   #
##  this software and its documentation without restriction, including    #
##  without limitation the rights to use, copy, modify, merge, publish,   #
##  distribute, sublicense, and/or sell copies of this work, and to       #
##  permit persons to whom this work is furnished to do so, subject to    #
##  the following conditions:                                             #
##   1. The code must retain the above copyright notice, this list of     #
##      conditions and the following disclaimer.                          #
##   2. Any modifications must be clearly marked as such.                 #
##   3. Original authors' names are not deleted.                          #
##   4. The authors' names are not used to endorse or promote products    #
##      derived from this software without specific prior written         #
##      permission.                                                       #
##                                                                        #
##  THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK         #
##  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING       #
##  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT    #
##  SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE      #
##  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES     #
##  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN    #
##  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,           #
##  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF        #
##  THIS SOFTWARE.                                                        #
###########################################################################
##                         Author: Junichi Yamagishi                      #
##                         Date:   31 Oct 2010                            #
##                         Contact: jyamagis@xxxxxxxxxxxx                 #
###########################################################################

use File::Path;
$| = 1;


#==============  BASIC INFORMATION =======================================
$WAV             = "";                # list of RIFF waveforms (48k, 44.1k, 32k, 22.05k 16kHz)

$LABEL           = "";                # list of context-dependent labels with time alignment information

$QFILE           = "";                # question file used for context clustering

$OUTPUTDIR       = "";                # output directory 

$SP              = "nck";             # arbitary name of training data
                                      # this is used only for making directory easy-to-understand

$Phoneset        = "unilex";          # arbitary name of phoneset or language
                                      # this is used only for making directory easy-to-understand

@slnt            = ('pau','#');       # silent and pause phoneme

#==============  CONFIGURABLE VARIABLES ================================== 
# Configuration (feature analysis)
$SAMPLINGRATE     = 16000;             # Sampling rate

$SCALE          = 1;                  # Variable for scale (1: Mel 2:Bark by Junichi 3: Bark by Julius 4:ERB by Julius)
                                      # Julius Smith "Bark and ERB Bilinear transforms 
                                      # IEEE Speech & Audio Proc Vol.7 No.6 Nov. 1999

$FRAMESHIFT     = 5;                  # Frame shift in ms

$CEPSTRALORDER  = 39;                 # Order for Mel-cepstral or 
                                      # Mel-generalized cepstral analysis 

$ANALYSISMETHOD = 1;                  # 1)STRAIGHT Mel-cepstrum 
                                      # 2)STRAIGHT Mel-generalized cepstrum (MGC) 
                                      # 3)STRAIGHT Mel-LSP (log gain)
                                      # 4)STRAIGHT MGC-LSP (log gain)

$MGCGAMMA       = 2;                  # Positive variable (>=1) for MGC analysis methods 2) and 4). 
                                      # Use $MGCGAMMA = 3 for instance.

$F0METHOD       = 4;                  # 1)IFAS method (if_getf0
                                      # 2)Fixed-point analysis (TEMPO)
                                      # 3)ESPS get_f0
                                      # 4)Voting of 1) to 3)

$F0SCALE        = 1;                  # Variable for F0 transform (1: log transform 2:generalized log transform 3: mel transform)
                                      # For Mel transform of F0, see Rabiner's book titled
                                      # 'Introduction to DSP'

$F0GAMMA        = 0.770387;           # parameter for generalized log transform of F0 (optimized value for a female speaker Meg)


$NOISEMASK      = 30 ;                 # Noise mask level against hum noise

$NUMBANDAP      = &calcnumband($SAMPLINGRATE);
                                      # Number of bands for aperiodicity measures
                                      # Decide the number of aperiodicity bands basd on crtical bandwidth of Bark 

$DELTAWINDOWLENGTH = 5;                # length for delta-window coefficents (e.g. 3 --> [ -0.5 0 0.5])

$ACCWINDOWLENGTH   = 5;                # length for acc-window coefficients

# Configuration (HMM)
$NUMSTATE       = 5;                  # number of states for a HMM

$TREETYPE       = 1;                  # Variable for structure of decision trees 
                                      # 1) single tree 2) phonetic tree (typically used for ASR)

$NUMMIXTURE     = 16;                 # number of mixtures used for regression classes

$MINOCCCMP      = 5;                  # minimum state occupancy of each leaf node in context clustering

$MINOCCDUR      = 10;                 # minimum state-duration occupancy of each leaf node in context clustering

$TREETHRESH     = 1;                  # Variable for threshold/criterion used for stopping growing of decision trees
                                      # 1) MDL criterion 2) state-occupancy thresholds and leaf nodes mergin
                                      # This is a variable for HTK experts 

$OCCTHRESHOLD   = 600.0;              # The above state-occpucancy thresholds for decision-tree-based clustering
                                      # If MDL is used for clustering, this varialbe is ignored.


# Configuration (misc. for parallel processing)
$USESTRAIGHT4   = 0;                  # Variable for MATLAB STRAIGHT (USESTRAIGHT4=1) 
                                      # Normally please use C++ STRAIGHT (USESTRAIGHT4=0) 

$USESGE         = 0;                  # Variable for Sun Grid Engine (USESGE=1). 
                                      # For a standalone machine, please use USESGE=0  

$USEICCOPENMP   = 1;                  # Variable for multi-thread processing using 
                                      # icc with Open MP. For a normal single thread  
                                      # processing please use USEOPENMP=0; 

$NUMSPLIT       = 100;                # Number of sentences of each subset 
                                      # used for parallel processing

$MAXCONTEXTSPLIT = 50;                # Number of subsets used for 
                                      # sentence-level model slitting 

#============== Initialization (do not change these values) ===============

$PARALLEL       = -1;                 # pararrel mode
$SSTATE         = 2;                  # HTK normally starts from state 2
$ESTATE         = $NUMSTATE + 1;      # HTK normally starts from state 2
$SITER          = 1;                  # Number of EM iteration (start flag)  
$EITER          = 5;                  # Number of EM iteration (end flag)  
$SITERTRANS     = 1;                  # Number of CMLLR/CSMAPLR iteration 
$EITERTRANS     = 3;                  # Number of CMLLR/CSMAPLR iteration 
$ENV{'OMP_NUM_THREADS'} = 1;          # Number of threads

#============== Arguments operation ========================================

$NUMSTEP        = 60;
$FROM           = 0;
$TO             = $NUMSTEP;

foreach $i (1..$NUMSTEP) {
    $EXEC[$i] = 0;
}

while ($ARGV[0] =~ /^-/) {
    $_ = shift;
    if    (/^-wav$/)        {$WAV = shift;}
    elsif (/^-lab$/)        {$LABEL = shift;}
    elsif (/^-quest$/)      {$QFILE = shift;}
    elsif (/^-out$/)        {$OUTPUTDIR= shift;}
    elsif (/^-sp$/)         {$SP = shift;}
    elsif (/^-ph$/)         {$Phoneset= shift;}
    elsif (/^-from$/)       {$FROM = shift;}
    elsif (/^-to$/)         {$TO = shift;}
    elsif (/^-state$/)      {$NUMSTATE = shift;}
    elsif (/^-treetype$/)   {$TREETYPE = shift;}
    elsif (/^-treethresh$/) {$TREETHRESH = shift;}
    elsif (/^-shift$/)      {$FRAMESHIFT = shift;}
    elsif (/^-order$/)      {$CEPSTRALORDER = shift;}
    elsif (/^-spec$/)       {$ANALYSISMETHOD = shift;}
    elsif (/^-gamma$/)      {$MGCGAMMA = shift;}
    elsif (/^-f0$/)         {$F0METHOD = shift;}
    elsif (/^-si$/)         {$SITER = shift;}
    elsif (/^-ei$/)         {$EITER = shift;}
    elsif (/^-st$/)         {$SITERTRANS = shift;}
    elsif (/^-et$/)         {$EITERTRANS = shift;}
    elsif (/^-pa$/)         {$PARALLEL = shift;}
    elsif (/^-ns$/)         {$NUMSPLIT = shift;}
    elsif (/^-mc$/)         {$MAXCONTEXTSPLIT = shift;}
    elsif (/^-v$/)          {
        printf "\t The HMM-based Speech Synthesis Systems for \n\t the Blizzard Challenge and EMIME project \n\n\t Centre for Speech Technology Research \n\t University of Edinburgh, UK \n\t Copyright (c) 2007-2010  \n\t All Rights Reserved.  \n\t HTS 2007 System Built Tool: version 0.8\n"; 
        exit;}
    elsif (/^-h$/)          {
        print "USAGE: perl HTS2007-Training.pl -wav <file> -lab <file> -quest <file> [options]\n";
        print "\t [required intput files]\n";
        print "\t -wav   <file>    : list of RIFF waveforms (48k, 44.1k, 32k, 22.05k 16kHz PCM) \n";
        print "\t -lab   <file>    : list of context-dependent labels with time alignment information (HTK format)\n";
        print "\t -quest <file>    : question file used for context clustering (HTK format)\n";
        print "\n";
        print "\t [options]: General \n";
        print "\t -out   <string>  : path for output directory\n";
        print "\t -sp    <string>  : arbitrary name of training data; this is used only for\n";
        print "\t                    making output directory easy-to-understand\n";
        print "\t -ph    <string>  : arbitrary name of phoneset; this is used only for \n";
        print "\t                    making output directory easy-to-understand\n";
        print "\t -from  <int>     : training step which you want to start\n";
        print "\t -to    <int>     : training step which you want to stop\n";
        print "\t -Q               : show details of each step \n";
        print "\t -v               : show version of this script\n";
        print "\t -h               : show this help message\n";
        print "\n";
        print "\t [options]: Analysis/feature extraction \n";
        print "\t -shift <int>     : frame-shift used for feature extraction (default 5ms) \n";
        print "\t -order <int>     : order of mel-cepstral/mel-generalized cepstral analysis (default 39th)\n";
        print "\t -spec  <int>     : STRAIGHT Spectral analysis method: (default 1)\n";
        print "\t                    1) Mel-cepstrum 2) Mel-generalized cepstrum 3) Mel-LSP 4) MGC-LSP \n";
        print "\t -f0    <int>     : F0 extraction method: (default 4)\n";
        print "\t                    1) IFAS 2) TEMPO 3) ESPS 4) Voting of all \n";
        print "\n";
        print "\t [options]: HMM \n";
        print "\t -state <int>     : number of states in an HMM (default 5)\n";
        print "\t -treetype <int>  : structure of decision trees for parameter tying (default 1)\n";
        print "\t                    1) single trees 2) phonetic trees \n";
        print "\t -treethresh <int>: threshold/criterion used for stopping growing of decision trees (default 1)\n";
        print "\t                    1) MDL criterion 2) state-occupancy thresholds and leaf nodes mergin \n";
        print "\n";
        exit;
    }
    elsif (/^-Q$/)          {
        print "\t This program consists of 39 steps \n";
        print "\t   Step 0: Data preparation (make config files etc) \n";
        print "\t   Step 1: Feature extraction\n";
        print "\t   Step 2: Variance flooring \n";
        print "\t   Step 3: Segmental K-means and EM estimation \n";
        print "\t   Step 4: Combine monophone HMMs and save them in a MLF file \n";
        print "\t   Step 5: Embedded training of monophone HMMs \n";
        print "\t   Step 6: Linear transform estimation for monophone HMMs 1 \n";
        print "\t   Step 7: Adaptive training of monophone HMMs 1\n";
        print "\t   Step 8: Linear transform estimation for monophone HMMs 2 \n";
        print "\t   Step 9: Adaptive training of monophone HMMs 2\n";
        print "\t   Step 10: Convert monophone HMMs and duration to context-dependent \n";
        print "\t   Step 11: Adaptive training for context-dependent HMMs without tying\n";
        print "\t   Step 12: Compress context-dependent HMMs \n";
        print "\t   Step 13: Context clustering for Spectral streams \n";
        print "\t   Step 14: Context clustering for logF0 streams \n";
        print "\t   Step 15: Context clustering for Bndap streams \n";
        print "\t   Step 16: Context clustering for duration pdfs \n";
        print "\t   Step 17: Combine tied HMMs and save them in a MLF file \n";
        print "\t   Step 18: Embedded training for tied context-dependent HMMs\n";
        print "\t   Step 19: Linear transform estimation for tied context-dependent HMMs 1 \n";
        print "\t   Step 20: Adaptive training of tied context-dependent HMMs 1\n";
        print "\t   Step 21: Linear transform estimation for tied context-dependent HMMs 2 \n";
        print "\t   Step 22: Adaptive training of tied context-dependent HMMs 2\n";
        print "\t   Step 23: Untie the context-dependent HMMs \n";
        print "\t   Step 24: Adaptive training for context-dependent HMMs without tying\n";
        print "\t   Step 25: Compress context-dependent HMMs \n";
        print "\t   Step 26: Context clustering for Spectral streams \n";
        print "\t   Step 27: Context clustering for logF0 streams \n";
        print "\t   Step 28: Context clustering for Bndap streams \n";
        print "\t   Step 29: Context clustering for duration pdfs \n";
        print "\t   Step 30: Combine tied HMMs and save them in a MLF file \n";
        print "\t   Step 31: Embedded training for tied context-dependent HMMs\n";
        print "\t   Step 32: Convert decision trees built in step 26-29 to regression class trees\n";
        print "\t   Step 33: Linear transform estimation for tied context-dependent HMMs 1 \n";
        print "\t   Step 34: Adaptive training of tied context-dependent HMMs 1\n";
        print "\t   Step 35: Linear transform estimation for tied context-dependent HMMs 2 \n";
        print "\t   Step 36: Adaptive training of tied context-dependent HMMs 2\n";
        print "\t   Step 37: Convert HTK models to hts_engine models \n";
        print "\t   Step 38: Save HTK models for HMGenS or further training \n";
        print "\t   Step 39: Convert HSMMs to HMMs for HVite\n";
        print "\t   Step 40: Embedded training for transition probs\n";
        print "\t   Step 41: Viterbi alignment of training data\n";
        print "\t   Step 42: Save HTK models and alignment results for further training\n";
        print "\t   Step 43: Generate hts_engine models for training speakers (optional) \n";
        print "\t   Step 44: Clean unnecessary data \n";
        exit;
    }
}

foreach $i ($FROM..$TO) {
    $EXEC[$i] = 1;
}

# Check required minimum inputs
if (($WAV eq "") || ($LABEL eq "") || ($QFILE eq "")){
    print "intput files are not enough\n";
    print "USAGE: HTS2007-Training.pl requires at least the following three files\n";
    print "\t -wav   <file>   : list of RIFF waveforms (48k, 44.1k, 32k, 22.05k 16kHz) \n";
    print "\t -lab   <file>   : list of context-dependent labels with time alignment information\n";
    print "\t -quest <file>   : question file used for context clustering \n";
    exit;
}

#============= Re-define based on specified arguments  ===================

$ESTATE         = $NUMSTATE + 1;
%STREAM         = ('mcep'  => '1',    # stream structure 
                   'logF0' => '2-4',
                   'bndap' => '5',
                   'dur'   => "1-$NUMSTATE");

#============= Grid Engine Variables ======================================

if($USESGE){
  if($PARALLEL < 0) {  # SGE_TASK_ID must be postive values. 
                       # For $PARALLEL = 0, we need to specify -pa 0 instead of SGE_TASK_ID variable.
     $PARALLEL     = $ENV{'SGE_TASK_ID'};    # Obtain array-job variables for SGE
  }
  $SSTATE       = $ENV{'SGE_TASK_ID'};    # Obtain array-job variables for SGE
  $ESTATE       = $ENV{'SGE_TASK_ID'};    # Obtain array-job variables for SGE
}

if($USEICCOPENMP){
   if (! defined $ENV{MODULE_VERSION} ) {
        $ENV{MODULE_VERSION_STACK}="3.1.6";
        $ENV{MODULE_VERSION}="3.1.6";
   } else {
        $ENV{MODULE_VERSION_STACK}="$MODULE_VERSION";
   }

   sub module {
        local ($exec_prefix);
        $exec_prefix = "/exports/applications/apps/SL5/environment-modules-3.1.6/".$ENV{MODULE_VERSION};

        eval `$exec_prefix/bin/modulecmd perl @_`;
   }

   $ENV{MODULESHOME} = "/exports/applications/apps/SL5/environment-modules-3.1.6/";

   if (! defined $ENV{MODULEPATH} ) {
        $ENV{MODULEPATH} = `sed 's/#.*\$//' $ENV{MODULESHOME}/init/.modulespath | awk 'NF==1{printf("%s:",\$1)}'` 
   }

   if (! defined $ENV{LOADEDMODULES} ) {
        $ENV{LOADEDMODULES} = "";
   }

   &module("load intel/compiler/latest openmpi/ethernet/intel/latest ");  # Load intel compilers
   $ENV{'OMP_NUM_THREADS'} = $ENV{'NSLOTS'};     # Obtain number of threads available for openMP
   printf ("\t Number of threads for OpenMP :%d\n",$ENV{'OMP_NUM_THREADS'});
}


#=======================================================================
# Directories and Files
#=======================================================================
#=============Working Directory==========================================
$BIN                   = "../../tool/bin";
$BASEDIR               = `cd .. ; pwd`; $BASEDIR =~ s/[\r\n]+$//;
$WORK                  = "$BASEDIR";

#=============Analysis directory and files=============================
if($OUTPUTDIR eq "") {
  $OUTDIR              = "$WORK/$SP.$Phoneset.${CEPSTRALORDER}-order.${FRAMESHIFT}-shift.spec-${ANALYSISMETHOD}.f0-${F0METHOD}";
}else{
  $OUTDIR              = "$OUTPUTDIR/$SP.$Phoneset.${CEPSTRALORDER}-order.${FRAMESHIFT}-shift.spec-${ANALYSISMETHOD}.f0-${F0METHOD}";
}
$ANALYSIS              = "$OUTDIR/Analysis";
$TRAINWAV              = "$ANALYSIS/train.$SP.wav";
$TRAIN                 = "$ANALYSIS/train.$SP.$Phoneset";
$WINDIR                = "$ANALYSIS/win";

$SPKLIST               = "$ANALYSIS/spk.list";
if(-e $SPKLIST){
    %SPEAKER = ();
    $i = 1;
    open(SPKLIST, "<$SPKLIST");
    while (<SPKLIST>) {
      chomp;
      $SPEAKER{$i} = $_;
      $i++
    }
}
$LISTDIR               = "$OUTDIR/list";
$MONOLIST              = "$LISTDIR/mono.lst.$SP.$Phoneset";
$FULLLIST              = "$LISTDIR/full.lst.$SP.$Phoneset";
$MONOMLF               = "$LISTDIR/mono.mlf";
$FULLMLF               = "$LISTDIR/full.mlf";

#=============Config Files ==============================================
$CONFIG                = "$OUTDIR/config/general.conf";
$UNFCONFIG             = "$OUTDIR/config/general-unfloor.conf";
$REMFLOORCONFIG        = "$OUTDIR/config/removefloor.conf";
$CONFIGCLUST           = "$OUTDIR/config/clust.conf";
$CONFIGDURCLUST        = "$OUTDIR/config/clust-dur.conf";
$CONFIGCMLLR           = "$OUTDIR/config/cmllr-regressionclass.conf";
$CONFIGCMLLRDEC        = "$OUTDIR/config/cmllr-decisiontree.conf";

#=============HMM-training common directory and files ==================
$HMMDIR                = "$OUTDIR/hmm.${NUMSTATE}-state.treetype-${TREETYPE}";
$FLOORMMF{'cmp'}       = "vFloor.cmp.mmf";
$MONOMMF{'cmp'}        = "mono.cmp.mmf";
$MONOMMF{'dur'}        = "mono.dur.mmf";
$FULLMMF{'cmp'}        = "full.cmp.mmf";
$FULLMMF{'dur'}        = "full.dur.mmf";
$CLSTMMF{'cmp'}        = "clustered.cmp.mmf";
$CLSTMMF{'dur'}        = "clustered.dur.mmf";
#=============Floor=====================================================
$HCOMPVDIR             = "$HMMDIR/VarianceFloor";
$PROTO                 = "$HCOMPVDIR/cmp.prt";
$VFLOORDUR             = "$HCOMPVDIR/dur/vFloors";
#=============Segmental K-means=========================================
$HINITDIR              = "$HMMDIR/SegmentalKmeans";
$HRESTDIR              = "$HMMDIR/MonophoneEMEstimation";
$HRESTDURDIR           = "$HMMDIR/MonophoneEMEstimation/duration";
#=============Cat Monophone HMM==========================================
$HHEDCATDIR            = "$HMMDIR/CatMonophone";
$CATMONOHED{'cmp'}     = "$HHEDCATDIR/catmono.cmp.hed";
$CATMONOHED{'dur'}     = "$HHEDCATDIR/catmono.dur.hed";
$COMPRESSHED           = "$HHEDCATDIR/compress.hed";
$COMPRESSSTREAMHED     = "$HHEDCATDIR/compstream.hed";
#=============Embedded Training=========================================
$HERESTMONO            = "$HMMDIR/MonophoneEmbeddedTraining";
$OUTBASE               = "$HERESTMONO/regclass.cmpbase";
$DURBASE               = "$HERESTMONO/regclass.durbase";
#=============Convert to CD ============================================
$HHEDCONVDIR           = "$HMMDIR/ConvertMono2Full";
$MONO2FULLHED{'cmp'}   = "$HHEDCONVDIR/mono2full.cmp.hed";
$MONO2FULLHED{'dur'}   = "$HHEDCONVDIR/mono2full.dur.hed";
#=============Embedded Training (CD)====================================
#$HERESTFULL            = "$HMMDIR/EmbeddedTraining";
$HERESTFULL            = $HHEDCONVDIR;
$STAFILE{'cmp'}        = "$HERESTFULL/cmp.sts";
#=============Clustering (Spec)==========================================
$HHEDCLUSTRINGSPEC     = "$HMMDIR/ContextClustering-Spec";
$CLSTHED{'mcep'}       = "$HHEDCLUSTRINGSPEC/cluster.mcep.hed";
$INFFILE{'mcep'}       = "$HHEDCLUSTRINGSPEC/tree.mcep.inf";
#=============Clustering (logF0)=========================================
$HHEDCLUSTRINGLOGF0    = "$HMMDIR/ContextClustering-logF0";
$CLSTHED{'logF0'}      = "$HHEDCLUSTRINGLOGF0/cluster.logF0.hed";
$INFFILE{'logF0'}      = "$HHEDCLUSTRINGLOGF0/tree.logF0.inf";
#=============Clustering (Bndap)=========================================
$HHEDCLUSTRINGBND      = "$HMMDIR/ContextClustering-Bndap";
$CLSTHED{'bndap'}      = "$HHEDCLUSTRINGBND/cluster.bndap.hed";
$INFFILE{'bndap'}      = "$HHEDCLUSTRINGBND/tree.bndap.inf";
$TIEDHED{'cmp'}        = "$HHEDCLUSTRINGBND/tied.cmp.hed";
$TIEDHED{'dur'}        = "$HHEDCLUSTRINGBND/tied.dur.hed";
$CATTREEHED            = "$HHEDCLUSTRINGBND/cattree.hed";
$JOINHED               = "$HHEDCLUSTRINGBND/join.hed";
$TIEDLIST{'cmp'}       = "$HHEDCLUSTRINGBND/full.train.lst.tiedlst";
$TIEDLIST{'dur'}       = "$HHEDCLUSTRINGBND/full.train.lst.tiedlst.duration";
#=============Clustering (Duration)=========================================
$HHEDCLUSTRINGDUR      = "$HMMDIR/ContextClustering-Duration";
$STAFILE{'dur'}        = "$HHEDCLUSTRINGDUR/dur.sts";
$CLSTHED{'dur'}        = "$HHEDCLUSTRINGDUR/cluster.dur.hed";
$INFFILE{'dur'}        = "$HHEDCLUSTRINGDUR/tree.dur.inf";
#=============Embedded Training (Tied CD HMM)=================================
$HERESTCLUSTED         = "$HMMDIR/EmbeddedTrainingCluster";
$REGTREEHED{'cmp'}     = "$HERESTCLUSTED/regtree.cmp.hed";
$REGTREEHED{'dur'}     = "$HERESTCLUSTED/regtree.dur.hed";
#=============Untie====================================================
$HHEDUNTIE             = "$HMMDIR/UntiedClust";
$UNTIEED{'cmp'}        = "$HHEDUNTIE/untie.cmp.hed";
$UNTIEED{'dur'}        = "$HHEDUNTIE/untie.dur.hed";
#=============Re-alignment=================================================
#$HERESTREALIGN         = "$HMMDIR/EmbeddedTrainingReAlignment";
$HERESTREALIGN         = $HHEDUNTIE;
$REALIGNSTAFILE{'cmp'} = "$HERESTREALIGN/cmp.sts";
$REALIGNSTAFILE{'dur'} = "$HERESTREALIGN/dur.sts";
#=============Clustering (Spec)==============================================
$HHEDRECLUSTRINGSPEC   = "$HMMDIR/ContextReClustering-Spec";
$RECLSTHED{'mcep'}     = "$HHEDRECLUSTRINGSPEC/cluster.mcep.hed";
$REINFFILE{'mcep'}     = "$HHEDRECLUSTRINGSPEC/tree.mcep.inf";
#=============Clustering (logF0)==============================================
$HHEDRECLUSTRINGLOGF0  = "$HMMDIR/ContextReClustering-logF0";
$RECLSTHED{'logF0'}    = "$HHEDRECLUSTRINGLOGF0/cluster.logF0.hed";
$REINFFILE{'logF0'}    = "$HHEDRECLUSTRINGLOGF0/tree.logF0.inf";
#=============Clustering (Bndap)===============================================
$HHEDRECLUSTRINGBND    = "$HMMDIR/ContextReClustering-Bndap";
$RECLSTHED{'bndap'}    = "$HHEDRECLUSTRINGBND/cluster.bndap.hed";
$REINFFILE{'bndap'}    = "$HHEDRECLUSTRINGBND/tree.bndap.inf";
$RETIEDHED{'cmp'}      = "$HHEDRECLUSTRINGBND/retied.cmp.hed";
$RETIEDHED{'dur'}      = "$HHEDRECLUSTRINGBND/retied.dur.hed";
$RECATTREEHED          = "$HHEDRECLUSTRINGBND/cattree.hed";
$REJOINHED             = "$HHEDRECLUSTRINGBND/join.hed";
$RETIEDLIST{'cmp'}     = "$HHEDRECLUSTRINGBND/full.train.lst.tiedlst";
$RETIEDLIST{'dur'}     = "$HHEDRECLUSTRINGBND/full.train.lst.tiedlst.duration";
#=============Clustering (duration)============================================
$HHEDRECLUSTRINGDUR    = "$HMMDIR/ContextReClustering-Duration";
$RECLSTHED{'dur'}      = "$HHEDRECLUSTRINGDUR/cluster.dur.hed";
$REINFFILE{'dur'}      = "$HHEDRECLUSTRINGDUR/tree.dur.inf";
#=============Embedded Training===============================================
$HERESTRECLUSTED       = "$HMMDIR/EmbeddedTrainingReCluster";
$REREGTREEHED{'cmp'}   = "$HERESTRECLUSTED/regtree.cmp.hed";
$REREGTREEHED{'dur'}   = "$HERESTRECLUSTED/regtree.dur.hed";

#=============Convert====================================================
$SPSYNTHE              = "$OUTDIR/hts_engine";
$SPTREE{'mcep'}        = "tree-mcep.inf";
$SPTREE{'logF0'}       = "tree-logF0.inf";
$SPTREE{'bndap'}       = "tree-bndap.inf";
$SPTREE{'dur'}         = "tree-duration.inf";
$SPPDF{'mcep'}         = "mcep.pdf";
$SPPDF{'logF0'}        = "logF0.pdf";
$SPPDF{'bndap'}        = "bndap.pdf";
$SPPDF{'dur'}          = "duration.pdf";
$CHSHED{'mcep'}        = "$SPSYNTHE/chs.mcep.hed";
$CHSHED{'logF0'}       = "$SPSYNTHE/chs.logF0.hed";
$CHSHED{'bndap'}       = "$SPSYNTHE/chs.bndap.hed";
$CHSHED{'dur'}         = "$SPSYNTHE/chs.dur.hed";
#=============Convert====================================================
$OUTHMMs               = "$OUTDIR/models";
$MODELINFO             = "$OUTDIR/models/info.txt";
$GVMMF                 = "$OUTHMMs/gv.mmf";
$SEGMENTMLF            = "$OUTHMMs/align.mlf";

#=============Convert-to-HMM=============================================
$ADDTRANSDIR           = "$HMMDIR/AddTransitionProbs";
$ADDTRANSHED           = "$ADDTRANSDIR/addtrans.hed";
$VOCAB                 = "$ADDTRANSDIR/align.vocab";
$ALIGNMLF              = "$ADDTRANSDIR/align.mlf";


#=======================================================================
# Main Program
#=======================================================================
#-----------------------------------------------------------------------
# Step0 Prepare Files
#-----------------------------------------------------------------------

if ($EXEC[0]) {
  print_step("Preparation for Analysis");
  print_time("Started at");
  makedir("$ANALYSIS");
  makedir("$LISTDIR");
  makedir("$WINDIR");
  makedir("$OUTDIR/config");

  printf ("HTS-2007 Training:                \n");
  printf ("\t Speaker/training data ID  :%s\n",$SP);
  printf ("\t Phoneset/language ID      :%s\n",$Phoneset);
  printf ("\t Mel-cestral analysis order:%d\n",$CEPSTRALORDER);
  printf ("\t Frame-shift for Analysis  :%d\n",$FRAMESHIFT);
  printf ("\t # of HMM states           :%d\n",$NUMSTATE);


  if(! -x "$BIN/HLEd") {
      print "Please install HLEd of HTS-2.1\n";
  }else{
      shell("$BIN/HLEd -V");
  }
  if(! -x "$BIN/HCompV") {
      print "Please install HCompV of HTS-2.1\n";
  }else{
      shell("$BIN/HCompV -V");
  }
  if(! -x "$BIN/HInit") {
      print "Please install HInit of HTS-2.1\n";
  }else{
      shell("$BIN/HInit -V");
  }
  if(! -x "$BIN/HRest") {
      print "Please install HRest of HTS-2.1\n";
  }else{
      shell("$BIN/HRest -V");
  }
  if(! -x "$BIN/HERest") {
      print "Please install HERest of HTS-2.1\n";
  }else{
      shell("$BIN/HERest -V");
  }
  if(! -x "$BIN/HHEd") {
      print "Please install HHEd of HTS-2.1\n";
  }else{
      shell("$BIN/HHEd -V");
  }

  if(! -x "$BIN/x2x") {
      print "Please install x2x of SPTK 3.1\n";
  }else{
      shell("$BIN/x2x -h");
  }
  if(! -x "$BIN/step") {
      print "Please install step of SPTK 3.1\n";
  }else{
      shell("$BIN/step -h");
  }
  if(! -x "$BIN/sopr") {
      print "Please install sopr of SPTK 3.1\n";
  }else{
      shell("$BIN/sopr -h");
  }
  if(! -x "$BIN/vstat") {
      print "Please install vstat of SPTK 3.1\n";
  }else{
      shell("$BIN/vstat -h");
  }

  if(! -x "$BIN/tempo") {
      print "Please install tempo of STRAIGHT\n";
  }
  if(! -x "$BIN/straight_mcep") {
      print "Please install straight_mcep of STRAIGHT\n";
  }
  if(! -x "$BIN/straight_bndap") {
      print "Please install straight_bndap of STRAIGHT\n";
  }
  if(! -x "$BIN/synthesis") {
      print "Please install synthesis for STRAIGHT\n";
  }

  if(! -x "$BIN/if_getf0") {
      print "Please install if_getf0\n";
  }
  if(! -x "$BIN/cmpdat") {
      print "Please install cmpdat\n";
  }
  if(! -x "$BIN/Hhead") {
      print "Please install Hhead\n";
  }

  # Generate config files for HTK/HTS
  shell("rm -f $OUTDIR/config/*");
  make_config();

  # Generate window files (delta)
  shell("$BIN/calcwin -l $DELTAWINDOWLENGTH > $WINDIR/mcep_d1.win");
  shell("$BIN/calcwin -l $DELTAWINDOWLENGTH > $WINDIR/logF0_d1.win");
  shell("$BIN/calcwin -l $DELTAWINDOWLENGTH > $WINDIR/bndap_d1.win");

  # Generate window files (delta-delta)
  shell("$BIN/calcwin -l $ACCWINDOWLENGTH -a > $WINDIR/mcep_d2.win");
  shell("$BIN/calcwin -l $ACCWINDOWLENGTH -a > $WINDIR/logF0_d2.win");
  shell("$BIN/calcwin -l $ACCWINDOWLENGTH -a > $WINDIR/bndap_d2.win");

  # Split list of wav files for parallel processing
  shell("perl $WORK/src/split.pl -input $WAV -output $TRAINWAV -line $NUMSPLIT");


  # Split list of wav files by speakers
  %SPEAKER = ();
  $i = 1;
  shell("cat $WAV | awk -F \/ '{print substr(\$NF,1,3)}' | sort -u > $SPKLIST ");
  open(SPKLIST, "<$SPKLIST");
  while (<SPKLIST>) {
      chomp;
      shell("rm -f $TRAINWAV.speaker$_");
      shell("awk -F \/ '{print \$NF}' $WAV | grep '^$_' > $LISTDIR/speaker$_");
      shell("grep -f $LISTDIR/speaker$_ $WAV > $TRAINWAV.speaker$_");
      shell("rm -f $LISTDIR/speaker$_");
      $SPEAKER{$i} = $_;
      $i++;
  }

  print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step1 Analysis Adaptation Data
#-----------------------------------------------------------------------

if ($EXEC[1]) {
  print_step("Analysis Adaptation Data");
  print_time("Started at");
  makedir("$ANALYSIS");

  $maxf0 = 480;
  $minf0 = 55;



  if($PARALLEL<0){
      # Fix wav file
     makedir("$ANALYSIS/raw");
     shell("csh $WORK/src/fix-wav.sh $WAV $ANALYSIS/raw $SAMPLINGRATE");
      
      # F0 extraction
      makedir("$ANALYSIS/lf0");
      shell("csh $WORK/src/estimate-logf0.sh $WAV $ANALYSIS/raw $ANALYSIS/lf0 $maxf0 $minf0 $FRAMESHIFT $F0METHOD $NOISEMASK $SAMPLINGRATE $F0SCALE $F0GAMMA");
      
      if($USESTRAIGHT4){
          # Mel-cepstral analysis & Aperiodic energy analysis
          makedir("$ANALYSIS/st-mcep");
          makedir("$ANALYSIS/bndap");
          shell("csh $WORK/src/st-mcep-bndap.sh $WAV $ANALYSIS/raw $ANALYSIS/lf0 $ANALYSIS/st-mcep $ANALYSIS/st-mcep $ANALYSIS/bndap $ANALYSIS/bndap $maxf0 $minf0 $FRAMESHIFT $CEPSTRALORDER");
      }else{
          # Mel-cepstral analysis 
          makedir("$ANALYSIS/st-mcep");
          shell("csh $WORK/src/st-mcep.sh $WAV $ANALYSIS/raw $ANALYSIS/lf0 $ANALYSIS/st-mcep $FRAMESHIFT $CEPSTRALORDER $ANALYSISMETHOD $MGCGAMMA $SAMPLINGRATE $SCALE");
      
          # Aperiodic energy analysis
          makedir("$ANALYSIS/bndap");
          shell("csh $WORK/src/st-bndap.sh $WAV $ANALYSIS/raw $ANALYSIS/lf0 $ANALYSIS/bndap $FRAMESHIFT $SAMPLINGRATE $NUMBANDAP");
      }

      # Calculate Delta
      makedir("$ANALYSIS/obs");
      shell("csh $WORK/src/estimate-delta.sh $WAV $ANALYSIS/st-mcep $ANALYSIS/lf0 $ANALYSIS/bndap $ANALYSIS/obs $WINDIR $FRAMESHIFT $CEPSTRALORDER $NUMBANDAP");

      # Prepare list of cmp files
      shell("find $ANALYSIS/obs/ -name '*.cmp' -print > $TRAIN");
      
      # Global variances
      makedir("$ANALYSIS/gv");
      shell("csh $WORK/src/gv-lf0.sh $WAV $ANALYSIS/lf0 $ANALYSIS/gv/gv-lf0.pdf");
      shell("csh $WORK/src/gv-mcep.sh $WAV $ANALYSIS/st-mcep $ANALYSIS/gv/gv-mcep.pdf $CEPSTRALORDER");
      shell("csh $WORK/src/gv-bndap.sh $WAV $ANALYSIS/bndap $ANALYSIS/gv/gv-bndap.pdf $NUMBANDAP");

      # Global variances for individual training speakers
      $numsp = keys(%SPEAKER);
      $i = 1;
      while ($i <= $numsp){ 
          print "\n========== $SPEAKER{$i} ==========\n"; 
          makedir("$ANALYSIS/gv/training-speakers/$SPEAKER{$i}");
          shell("csh $WORK/src/gv-lf0.sh $TRAINWAV.speaker$SPEAKER{$i}  $ANALYSIS/lf0 $ANALYSIS/gv/training-speakers/$SPEAKER{$i}/gv-lf0.pdf");
          shell("csh $WORK/src/gv-mcep.sh $TRAINWAV.speaker$SPEAKER{$i} $ANALYSIS/st-mcep $ANALYSIS/gv/training-speakers/$SPEAKER{$i}/gv-mcep.pdf $CEPSTRALORDER");
          shell("csh $WORK/src/gv-bndap.sh $TRAINWAV.speaker$SPEAKER{$i} $ANALYSIS/bndap $ANALYSIS/gv/training-speakers/$SPEAKER{$i}/gv-bndap.pdf $NUMBANDAP");
          $i++;
      }
      
      # Analysis-bs-Synthesis (Mel-cepstral analysis)
      if($USESTRAIGHT4){
          makedir("$ANALYSIS/resyn");
          shell("csh $WORK/src/AbS-STRAIGHT.sh $WAV $ANALYSIS/st-mcep $ANALYSIS/lf0 $ANALYSIS/bndap $ANALYSIS/resyn $FRAMESHIFT $CEPSTRALORDER");
      }else{
          makedir("$ANALYSIS/resyn");
          shell("csh $WORK/src/AbS.sh $WAV $ANALYSIS/st-mcep $ANALYSIS/lf0 $ANALYSIS/bndap $ANALYSIS/resyn $FRAMESHIFT $CEPSTRALORDER $ANALYSISMETHOD $MGCGAMMA $SAMPLINGRATE $SCALE");
      }

      shell("rm -rf $ANALYSIS/raw $ANALYSIS/lf0 $ANALYSIS/bndap $ANALYSIS/st-mcep $ANALYSIS/st-mcep");

  }elsif($PARALLEL>0){
      # Fix wav file
      makedir("$ANALYSIS/raw");
      shell("csh $WORK/src/fix-wav.sh $TRAINWAV.$PARALLEL $ANALYSIS/raw $SAMPLINGRATE");
      
      # F0 extraction
      makedir("$ANALYSIS/lf0");
      shell("csh $WORK/src/estimate-logf0.sh $TRAINWAV.$PARALLEL $ANALYSIS/raw $ANALYSIS/lf0 $maxf0 $minf0 $FRAMESHIFT $F0METHOD $NOISEMASK $SAMPLINGRATE $F0SCALE $F0GAMMA");
      
      if($USESTRAIGHT4){
          # Mel-cepstral analysis & Aperiodic energy analysis
          makedir("$ANALYSIS/st-mcep");
          makedir("$ANALYSIS/bndap");
          shell("csh $WORK/src/st-mcep-bndap.sh $TRAINWAV.$PARALLEL $ANALYSIS/raw $ANALYSIS/lf0 $ANALYSIS/st-mcep $ANALYSIS/st-mcep $ANALYSIS/bndap $ANALYSIS/bndap $maxf0 $minf0 $FRAMESHIFT $CEPSTRALORDER");
      }else{
          # Mel-cepstral analysis 
          makedir("$ANALYSIS/st-mcep");
          shell("csh $WORK/src/st-mcep.sh $TRAINWAV.$PARALLEL $ANALYSIS/raw $ANALYSIS/lf0 $ANALYSIS/st-mcep $FRAMESHIFT $CEPSTRALORDER $ANALYSISMETHOD $MGCGAMMA $SAMPLINGRATE $SCALE");
  
          # Aperiodic energy analysis
          makedir("$ANALYSIS/bndap");
          shell("csh $WORK/src/st-bndap.sh $TRAINWAV.$PARALLEL $ANALYSIS/raw $ANALYSIS/lf0 $ANALYSIS/bndap $FRAMESHIFT $SAMPLINGRATE $NUMBANDAP");
      }

      # Calculate Delta
      makedir("$ANALYSIS/obs");
      shell("csh $WORK/src/estimate-delta.sh $TRAINWAV.$PARALLEL $ANALYSIS/st-mcep $ANALYSIS/lf0 $ANALYSIS/bndap $ANALYSIS/obs $WINDIR $FRAMESHIFT $CEPSTRALORDER $NUMBANDAP");
      
      # Analysis-bs-Synthesis (Mel-cepstral analysis)
      if($USESTRAIGHT4){
          makedir("$ANALYSIS/resyn");
          shell("csh $WORK/src/AbS-STRAIGHT.sh $TRAINWAV.$PARALLEL $ANALYSIS/st-mcep $ANALYSIS/lf0 $ANALYSIS/bndap $ANALYSIS/resyn $FRAMESHIFT $CEPSTRALORDER");
      }else{
          makedir("$ANALYSIS/resyn");
          shell("csh $WORK/src/AbS.sh $TRAINWAV.$PARALLEL $ANALYSIS/st-mcep $ANALYSIS/lf0 $ANALYSIS/bndap $ANALYSIS/resyn $FRAMESHIFT $CEPSTRALORDER $ANALYSISMETHOD $MGCGAMMA $SAMPLINGRATE $SCALE");
      }

  }elsif($PARALLEL==0){
      # Prepare list of cmp files
      shell("find $ANALYSIS/obs/ -name '*.cmp' -print > $TRAIN");

      # Global variances
      makedir("$ANALYSIS/gv");
      shell("csh $WORK/src/gv-lf0.sh $WAV $ANALYSIS/lf0 $ANALYSIS/gv/gv-lf0.pdf");
      shell("csh $WORK/src/gv-mcep.sh $WAV $ANALYSIS/st-mcep $ANALYSIS/gv/gv-mcep.pdf $CEPSTRALORDER");
      shell("csh $WORK/src/gv-bndap.sh $WAV $ANALYSIS/bndap $ANALYSIS/gv/gv-bndap.pdf $NUMBANDAP");

      # Global variances for individual training speakers
      $numsp = keys(%SPEAKER);
      $i = 1;
      while ($i <= $numsp){ 
          print "\n========== $SPEAKER{$i} ==========\n"; 
          makedir("$ANALYSIS/gv/training-speakers/$SPEAKER{$i}");
          shell("csh $WORK/src/gv-lf0.sh $TRAINWAV.speaker$SPEAKER{$i}  $ANALYSIS/lf0 $ANALYSIS/gv/training-speakers/$SPEAKER{$i}/gv-lf0.pdf");
          shell("csh $WORK/src/gv-mcep.sh $TRAINWAV.speaker$SPEAKER{$i} $ANALYSIS/st-mcep $ANALYSIS/gv/training-speakers/$SPEAKER{$i}/gv-mcep.pdf $CEPSTRALORDER");
          shell("csh $WORK/src/gv-bndap.sh $TRAINWAV.speaker$SPEAKER{$i} $ANALYSIS/bndap $ANALYSIS/gv/training-speakers/$SPEAKER{$i}/gv-bndap.pdf $NUMBANDAP");
          $i++;
      }
      
      shell("rm -rf $ANALYSIS/raw $ANALYSIS/lf0 $ANALYSIS/bndap $ANALYSIS/st-mcep $ANALYSIS/st-mcep");
  }

  print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step2 Flooring of Covariance
#-----------------------------------------------------------------------

if ($EXEC[2]) {
    print_step("Flooring of Covariance");
    print_time("Started at");
    makedir("$LISTDIR");
    makedir("$HMMDIR");
    makedir("$HCOMPVDIR");
    makedir("$HCOMPVDIR/dur");

    shell("perl $WORK/src/split.pl -input $TRAIN -output $TRAIN -line $NUMSPLIT");

    %SPEAKER = ();
    $i = 1;
    shell("cat $TRAIN | awk -F \/ '{print substr(\$NF,1,3)}' | sort -u > $SPKLIST ");
    open(SPKLIST, "<$SPKLIST");
    while (<SPKLIST>) {
      chomp;
      shell("rm -f $TRAIN.speaker$_");
      shell("awk -F \/ '{print \$NF}' $TRAIN | grep '^$_' > $LISTDIR/speaker$_");
      shell("grep -f $LISTDIR/speaker$_ $TRAIN > $TRAIN.speaker$_");
      shell("rm -f $LISTDIR/speaker$_");
      $SPEAKER{$i} = $_;
      $i++;
    }

    # Ignore files which caused some errors in feature extraction
    shell("awk -F \/ '{print \$NF}' $TRAIN | sed 's/\\.cmp//g' > $LISTDIR/cmp.lst");
    shell("fgrep -f $LISTDIR/cmp.lst $LABEL > $LISTDIR/label.lst");

    shell("touch null.hed");
    shell("$BIN/HLEd -A -D -T 1 -V -l '*' -n $FULLLIST -i $FULLMLF -S $LISTDIR/label.lst null.hed");
    shell("$BIN/HLEd -A -D -T 1 -V -l '*' -n $MONOLIST -i $MONOMLF -m null.hed $FULLMLF");
    shell("rm -f null.hed ");

    if($MAXCONTEXTSPLIT > 1){
        shell("perl $WORK/src/split-context.pl -mlf $FULLMLF -output $FULLLIST -maxsplit $MAXCONTEXTSPLIT");
        $splt=1;
        while($splt <= $MAXCONTEXTSPLIT) { 
            if(-e "$FULLLIST.$splt"){
                shell("fgrep -f $FULLLIST.$splt.cmp $TRAIN | sort > $TRAIN.split$splt");
                shell("rm -f $FULLLIST.$splt.cmp");
            }
            $splt++;
        }
    }

    make_proto();  
    shell("$BIN/HCompV -A -C $CONFIG -D -V -S $TRAIN -T 1 -M $HCOMPVDIR $PROTO");
    shell("head -n 1 $PROTO | cat - $HCOMPVDIR/vFloors > $HCOMPVDIR/$FLOORMMF{'cmp'} ");
    mkvfloordur();

    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step3 Segmental K-means Algorithm and EM-based Estimation of Monohphone
#-----------------------------------------------------------------------

if ($EXEC[3]) {
    print_step("Segmental K-means Algorithm and EM-based Estimation of Monohphone");
    print_time("Started at");
    makedir($HINITDIR);
    makedir($HRESTDIR);
    makedir($HRESTDURDIR);
    
    open(HMMLIST, "<$MONOLIST");
    if($PARALLEL<0){
        while (<HMMLIST>) {
            chomp;
            print "\n========== $_ ==========\n"; 
            shell("$BIN/HInit -A -C $CONFIG -D -V -H $HCOMPVDIR/$FLOORMMF{'cmp'} -I $MONOMLF -M $HINITDIR -S $TRAIN -T 1 -l $_ -m 1 -o $_ -u tmvw  -w 3 $PROTO");
            shell("$BIN/HRest -A -C $CONFIG -D -V -H $HINITDIR/$FLOORMMF{'cmp'} -I $MONOMLF -M $HRESTDIR -S $TRAIN -T 1 -l $_ -g $HRESTDURDIR/$_ -m 1 -u tmvw -w 3 $HINITDIR/$_");
        }
        shell("rm -rf $HINITDIR ");
    }elsif ($PARALLEL>0){ # subset = phoneme
        @array = <HMMLIST> ;
        $phoneindex= $PARALLEL-1;
        chomp $array[$phoneindex] ;
        print "\n========== $array[$phoneindex] ==========\n"; 
        shell("$BIN/HInit -A -C $CONFIG -D -V -H $HCOMPVDIR/$FLOORMMF{'cmp'} -I $MONOMLF -M $HINITDIR -S $TRAIN -T 1 -l $array[$phoneindex] -m 1 -o $array[$phoneindex] -u tmvw  -w 3 $PROTO");
        shell("$BIN/HRest -A -C $CONFIG -D -V -H $HINITDIR/$FLOORMMF{'cmp'} -I $MONOMLF -M $HRESTDIR -S $TRAIN -T 1 -l $array[$phoneindex] -g $HRESTDURDIR/$array[$phoneindex] -m 1 -u tmvw -w 3 $HINITDIR/$array[$phoneindex]");
    }
    close(HMMLIST);
    print_time("Finished at");

}

#-----------------------------------------------------------------------
# Step4 Cat Monophone HMMs
#-----------------------------------------------------------------------

if ($EXEC[4]) {
    print_step("Cat Monophones");
    print_time("Started at");
    makedir("$HHEDCATDIR");
    makedir("$HERESTMONO");
    
    mkcathed('cmp');
    shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -d $HRESTDIR -p -i -w $HHEDCATDIR/$MONOMMF{'cmp'} $CATMONOHED{'cmp'} $MONOLIST");
    
    mkcathed('dur');
    shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -d $HRESTDURDIR -p -i -w $HHEDCATDIR/$MONOMMF{'dur'} $CATMONOHED{'dur'} $MONOLIST");

    generate_base();

    shell("rm -rf $CATMONOHED{'cmp'} $CATMONOHED{'dur'} $HRESTDIR $HRESTDURDIR ");
    shell("rm -rf $HINITDIR ");

    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step5 Embedded Training for Monophone HMM 
#-----------------------------------------------------------------------

if ($EXEC[5]) {
    print_step(" Embedded Training for Monophone HMM");
    print_time("Started at");
    makedir("$HERESTMONO");
    
    $i = $SITER;
    while ($i <= $EITER) {
        print("\n\nIteration ", $i, " of Embedded Training for Monophone HMM\n");
        makedir("$HERESTMONO/$i");
        if($i==1){
            if($PARALLEL<0){
                shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HHEDCATDIR/$MONOMMF{'cmp'} -N $HHEDCATDIR/$MONOMMF{'dur'}  -I $MONOMLF -M $HERESTMONO/$i -R $HERESTMONO/$i -S $TRAIN -T 1 -m 1 -t 5000 5000 10000 -u mvwtdmv -w 3 $MONOLIST $MONOLIST");
                shell("rm -rf  $HHEDCATDIR/$MONOMMF{'cmp'} $HHEDCATDIR/$MONOMMF{'dur'} ");
            }elsif ($PARALLEL>0){
                shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HHEDCATDIR/$MONOMMF{'cmp'} -N $HHEDCATDIR/$MONOMMF{'dur'} -I $MONOMLF -M $HERESTMONO/$i -R $HERESTMONO/$i -S $TRAIN.$PARALLEL -T 1 -m 1 -t 5000 5000 10000 -p $PARALLEL -u mvwtdmv -w 3 $MONOLIST $MONOLIST");
            }elsif ($PARALLEL==0){
                shell("find $HERESTMONO/$i/ -name '*.acc' -print | sort > $HERESTMONO/$i/AccList");
                shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HHEDCATDIR/$MONOMMF{'cmp'} -N $HHEDCATDIR/$MONOMMF{'dur'}  -I $MONOMLF -M $HERESTMONO/$i -R $HERESTMONO/$i -S $HERESTMONO/$i/AccList -T 1 -m 1 -t 5000 5000 10000 -p $PARALLEL -u mvwtdmv -w 3 $MONOLIST $MONOLIST");
                shell("echo $HERESTMONO/$i/*.acc | xargs rm -rf");
                shell("rm -rf  $HHEDCATDIR/$MONOMMF{'cmp'} $HHEDCATDIR/$MONOMMF{'dur'} ");
            }
        }else{
            $ii=$i-1;
            if($PARALLEL<0){
                shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTMONO/$ii/$MONOMMF{'cmp'} -N $HERESTMONO/$ii/$MONOMMF{'dur'} -I $MONOMLF -M $HERESTMONO/$i -R $HERESTMONO/$i -S $TRAIN -T 1 -m 1 -t 5000 5000 10000 -u mvwtdmv -w 3 $MONOLIST $MONOLIST");
                shell("rm -rf $HERESTMONO/$ii/$MONOMMF{'cmp'} $HERESTMONO/$ii/$MONOMMF{'dur'} ");
            }elsif ($PARALLEL>0){
                shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTMONO/$ii/$MONOMMF{'cmp'} -N $HERESTMONO/$ii/$MONOMMF{'dur'} -I $MONOMLF -M $HERESTMONO/$i -R $HERESTMONO/$i -S $TRAIN.$PARALLEL -T 1 -m 1 -t 5000 5000 10000 -p $PARALLEL -u mvwtdmv -w 3 $MONOLIST $MONOLIST");
            }elsif ($PARALLEL==0){
                shell("find $HERESTMONO/$i/ -name '*.acc' -print | sort > $HERESTMONO/$i/AccList");
                shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTMONO/$ii/$MONOMMF{'cmp'} -N $HERESTMONO/$ii/$MONOMMF{'dur'} -I $MONOMLF -M $HERESTMONO/$i -R $HERESTMONO/$i -S $HERESTMONO/$i/AccList -T 1 -m 1 -t 5000 5000 10000 -p $PARALLEL -u mvwtdmv -w 3 $MONOLIST $MONOLIST");
                shell("echo $HERESTMONO/$i/*.acc | xargs rm -rf");
                shell("rm -rf $HERESTMONO/$ii/$MONOMMF{'cmp'} $HERESTMONO/$ii/$MONOMMF{'dur'} ");
            }
        }
        $i++;
    }

    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step6 Transformation Estimation for Monophone HMM 
#-----------------------------------------------------------------------

if ($EXEC[6]) {
    print_step(" Transformation Estimation for Monophone HMM");
    print_time("Started at");
    makedir("$HERESTMONO");
    
    print("Transform Estimation 1 for Monophone HMM \n");
    makedir("$HERESTMONO/cmllr");
    
    $INPUTTRANSFORM = "";
    $i = $SITERTRANS;
    while ($i <= $EITERTRANS) {
        $in = $i-1;
        if($i>1){
            $INPUTTRANSFORM = "-J $HERESTMONO/cmllr cmp.cmllr$in -Y $HERESTMONO/cmllr dur.cmllr$in -a -b";
        }
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -H $HERESTMONO/5/$MONOMMF{'cmp'} -N $HERESTMONO/5/$MONOMMF{'dur'} -I $MONOMLF -J $HERESTMONO -Y $HERESTMONO $INPUTTRANSFORM -K $HERESTMONO/cmllr cmp.cmllr$i -Z $HERESTMONO/cmllr dur.cmllr$i -M $HERESTMONO/cmllr -R $HERESTMONO/cmllr -S $TRAIN -T 1 -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u ada -w 3 $MONOLIST $MONOLIST");
            shell("echo $HERESTMONO/cmllr/*.cmllr$in | xargs rm -rf");
        }elsif ($PARALLEL>0){ # subset = speaker
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -H $HERESTMONO/5/$MONOMMF{'cmp'} -N $HERESTMONO/5/$MONOMMF{'dur'} -I $MONOMLF -J $HERESTMONO -Y $HERESTMONO $INPUTTRANSFORM -K $HERESTMONO/cmllr cmp.cmllr$i -Z $HERESTMONO/cmllr dur.cmllr$i -M $HERESTMONO/cmllr -R $HERESTMONO/cmllr -S $TRAIN.speaker$SPEAKER{$PARALLEL} -T 1 -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u ada -w 3 $MONOLIST $MONOLIST");
        }
        $i++;
    }
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step7 SAT for Monophone HMM 
#-----------------------------------------------------------------------

if ($EXEC[7]) {
    print_step(" SAT for Monophone HMM");
    print_time("Started at");
    makedir("$HERESTMONO");
    
    $i = 5+$SITER;
    while ($i <= 5+$EITER) {
        print("\n\nIteration ", $i, " of Speaker Adaptive Training for Monophone HMM\n");
        makedir("$HERESTMONO/$i");
        $ii=$i-1;
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -E $HERESTMONO/cmllr cmp.cmllr3 -W $HERESTMONO/cmllr dur.cmllr3 -H $HERESTMONO/$ii/$MONOMMF{'cmp'} -N $HERESTMONO/$ii/$MONOMMF{'dur'} -I $MONOMLF -J $HERESTMONO -Y $HERESTMONO -J $HERESTMONO/cmllr cmp.cmllr3 -Y $HERESTMONO/cmllr dur.cmllr3 -K $HERESTMONO/$i -Z $HERESTMONO/$i -M $HERESTMONO/$i -R $HERESTMONO/$i -S $TRAIN -T 1 -a -b -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u mvwtdmv -w 3 $MONOLIST $MONOLIST");
            shell("rm -rf $HERESTMONO/$ii/$MONOMMF{'cmp'} $HERESTMONO/$ii/$MONOMMF{'dur'} ");
        }elsif ($PARALLEL>0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -E $HERESTMONO/cmllr cmp.cmllr3 -W $HERESTMONO/cmllr dur.cmllr3 -H $HERESTMONO/$ii/$MONOMMF{'cmp'} -N $HERESTMONO/$ii/$MONOMMF{'dur'} -I $MONOMLF -J $HERESTMONO -Y $HERESTMONO -J $HERESTMONO/cmllr cmp.cmllr3 -Y $HERESTMONO/cmllr dur.cmllr3 -K $HERESTMONO/$i -Z $HERESTMONO/$i -M $HERESTMONO/$i -R $HERESTMONO/$i -S $TRAIN.$PARALLEL -T 1 -a -b -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -p $PARALLEL -u mvwtdmv -w 3 $MONOLIST $MONOLIST");
        }elsif ($PARALLEL==0){
            shell("find $HERESTMONO/$i/ -name '*.acc' -print | sort > $HERESTMONO/$i/AccList");
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -H $HERESTMONO/$ii/$MONOMMF{'cmp'} -N $HERESTMONO/$ii/$MONOMMF{'dur'}  -I $MONOMLF -M $HERESTMONO/$i -R $HERESTMONO/$i -S $HERESTMONO/$i/AccList -T 1 -m 1 -t 5000 5000 30000 -p $PARALLEL -u mvwtdmv -w 3 $MONOLIST $MONOLIST");
            shell("echo $HERESTMONO/$i/*.acc | xargs rm -rf");
            shell("rm -rf $HERESTMONO/$ii/$MONOMMF{'cmp'} $HERESTMONO/$ii/$MONOMMF{'dur'} ");
        }
        $i++;
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step8 Transformation Estimation 2 for Monophone HMM 
#-----------------------------------------------------------------------

if ($EXEC[8]) {
    print_step(" Transformation Estimation 2 for Monophone HMM");
    print_time("Started at");
    makedir("$HERESTMONO");
    
    print("Transform Estimation 1 for Monophone HMM \n");
    makedir("$HERESTMONO/cmllr");

    $INPUTTRANSFORM = "";
    $i = $SITERTRANS+3;
    while ($i <= $EITERTRANS+3) {
        $in = $i-1;
        $INPUTTRANSFORM = "-J $HERESTMONO/cmllr cmp.cmllr$in -Y $HERESTMONO/cmllr dur.cmllr$in -a -b ";
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -H $HERESTMONO/10/$MONOMMF{'cmp'} -N $HERESTMONO/10/$MONOMMF{'dur'} -I $MONOMLF -J $HERESTMONO -Y $HERESTMONO $INPUTTRANSFORM -K $HERESTMONO/cmllr cmp.cmllr$i -Z $HERESTMONO/cmllr dur.cmllr$i -M $HERESTMONO/cmllr -R $HERESTMONO/cmllr -S $TRAIN -T 1 -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u ada -w 3 $MONOLIST $MONOLIST");
            shell("echo $HERESTMONO/cmllr/*.cmllr$in | xargs rm -rf");
        }elsif ($PARALLEL>0){ # subset = speaker
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -H $HERESTMONO/10/$MONOMMF{'cmp'} -N $HERESTMONO/10/$MONOMMF{'dur'} -I $MONOMLF -J $HERESTMONO -Y $HERESTMONO $INPUTTRANSFORM -K $HERESTMONO/cmllr cmp.cmllr$i -Z $HERESTMONO/cmllr dur.cmllr$i -M $HERESTMONO/cmllr -R $HERESTMONO/cmllr -S $TRAIN.speaker$SPEAKER{$PARALLEL} -T 1 -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u ada -w 3 $MONOLIST $MONOLIST");
        }
        $i++;
    }

    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step9 SAT 2 for Monophone HMM 
#-----------------------------------------------------------------------

if ($EXEC[9]) {
    print_step(" SAT 2 for Monophone HMM");
    print_time("Started at");
    makedir("$HERESTMONO");
    
    $i = 10+$SITER;
    while ($i <= 10+$EITER) {
        print("\n\nIteration ", $i, " of Speaker Adaptive Training for Monophone HMM\n");
        makedir("$HERESTMONO/$i");
        $ii=$i-1;
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -E $HERESTMONO/cmllr cmp.cmllr6 -W $HERESTMONO/cmllr dur.cmllr6 -H $HERESTMONO/$ii/$MONOMMF{'cmp'} -N $HERESTMONO/$ii/$MONOMMF{'dur'} -I $MONOMLF -J $HERESTMONO -Y $HERESTMONO -J $HERESTMONO/cmllr cmp.cmllr6 -Y $HERESTMONO/cmllr dur.cmllr6 -K $HERESTMONO/$i -Z $HERESTMONO/$i -M $HERESTMONO/$i -R $HERESTMONO/$i -S $TRAIN -T 1 -a -b -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u mvwtdmv -w 3 $MONOLIST $MONOLIST");
            shell("rm -rf $HERESTMONO/$ii/$MONOMMF{'cmp'} $HERESTMONO/$ii/$MONOMMF{'dur'} ");
        }elsif ($PARALLEL>0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -E $HERESTMONO/cmllr cmp.cmllr6 -W $HERESTMONO/cmllr dur.cmllr6 -H $HERESTMONO/$ii/$MONOMMF{'cmp'} -N $HERESTMONO/$ii/$MONOMMF{'dur'} -I $MONOMLF -J $HERESTMONO -Y $HERESTMONO -J $HERESTMONO/cmllr cmp.cmllr6 -Y $HERESTMONO/cmllr dur.cmllr6  -K $HERESTMONO/$i -Z $HERESTMONO/$i -M $HERESTMONO/$i -R $HERESTMONO/$i -S $TRAIN.$PARALLEL -T 1 -a -b -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -p $PARALLEL -u mvwtdmv -w 3 $MONOLIST $MONOLIST");
        }elsif ($PARALLEL==0){
            shell("find $HERESTMONO/$i/ -name '*.acc' -print | sort > $HERESTMONO/$i/AccList");
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -H $HERESTMONO/$ii/$MONOMMF{'cmp'} -N $HERESTMONO/$ii/$MONOMMF{'dur'} -I $MONOMLF -M $HERESTMONO/$i -R $HERESTMONO/$i -S $HERESTMONO/$i/AccList -T 1 -m 1 -t 5000 5000 30000 -p $PARALLEL -u mvwtdmv -w 3 $MONOLIST $MONOLIST");
            shell("echo $HERESTMONO/$i/*.acc | xargs rm -rf");
            shell("rm -rf $HERESTMONO/$ii/$MONOMMF{'cmp'} $HERESTMONO/$ii/$MONOMMF{'dur'} ");
        }
        $i++;
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step10 Convert Monophone HMM to FullContext HMM
#-----------------------------------------------------------------------

if ($EXEC[10]) {
    print_step("Convert Monophone to FullContext");
    print_time("Started at");
    makedir("$HHEDCONVDIR");
    
    if($PARALLEL >= 1){
        if(-e "$FULLLIST.$PARALLEL"){
            mkm2splithed('cmp', $PARALLEL);
            mkm2splithed('dur', $PARALLEL);
            shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HERESTMONO/15/$MONOMMF{'cmp'} -p -i -w $HHEDCONVDIR/$FULLMMF{'cmp'}.$PARALLEL $MONO2FULLHED{'cmp'}.$PARALLEL $MONOLIST");
            shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HERESTMONO/15/$MONOMMF{'dur'} -p -i -w $HHEDCONVDIR/$FULLMMF{'dur'}.$PARALLEL $MONO2FULLHED{'dur'}.$PARALLEL $MONOLIST");
            shell("rm -f $MONO2FULLHED{'cmp'}.$PARALLEL");
            shell("rm -f $MONO2FULLHED{'dur'}.$PARALLEL");
        }
    }elsif($PARALLEL == -1){
        if($MAXCONTEXTSPLIT > 1){
            $splt=1;
            while($splt <= $MAXCONTEXTSPLIT) { 
                if(-e "$FULLLIST.$splt"){
                    mkm2splithed('cmp', $splt);
                    mkm2splithed('dur', $splt);
                    shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HERESTMONO/15/$MONOMMF{'cmp'} -p -i -w $HHEDCONVDIR/$FULLMMF{'cmp'}.$splt $MONO2FULLHED{'cmp'}.$splt $MONOLIST");
                    shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HERESTMONO/15/$MONOMMF{'dur'} -p -i -w $HHEDCONVDIR/$FULLMMF{'dur'}.$splt $MONO2FULLHED{'dur'}.$splt $MONOLIST");
                    shell("rm -f $MONO2FULLHED{'cmp'}.$splt");
                    shell("rm -f $MONO2FULLHED{'dur'}.$splt");
                }
                $splt++;
            }
        }else{
            mkm2splithed('cmp', 0);
            mkm2splithed('dur', 0);
            shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HERESTMONO/15/$MONOMMF{'cmp'} -p -i -w $HHEDCONVDIR/$FULLMMF{'cmp'} $MONO2FULLHED{'cmp'} $MONOLIST");
            shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HERESTMONO/15/$MONOMMF{'dur'} -p -i -w $HHEDCONVDIR/$FULLMMF{'dur'} $MONO2FULLHED{'dur'} $MONOLIST");
            shell("rm -rf $HERESTMONO/15/$MONOMMF{'cmp'} $MONO2FULLHED{'cmp'} ");
            shell("rm -rf $HERESTMONO/15/$MONOMMF{'dur'} $MONO2FULLHED{'dur'} ");
        }
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step11 Embedded Training for FullContext HMM 
#-----------------------------------------------------------------------

if ($EXEC[11]) {
    print_step(" Embedded Training for FullContext HMM");
    print_time("Started at");
    makedir("$HERESTFULL");
    print("Embedded Training for FullContext HMM \n");

    $INPUTTRANSFORM = "-C $CONFIGCMLLR -a -b -h \"*/%%%*.cmp\" -E $HERESTMONO/cmllr cmp.cmllr6 -W $HERESTMONO/cmllr dur.cmllr6 -J $HERESTMONO -Y $HERESTMONO -J $HERESTMONO/cmllr cmp.cmllr6 -Y $HERESTMONO/cmllr dur.cmllr6 ";

    if($PARALLEL >= 1){
        if(-e "$FULLLIST.$PARALLEL"){     
            shell("$BIN/HERest -A -B -C $UNFCONFIG -C $REMFLOORCONFIG -D -V $INPUTTRANSFORM -H $HHEDCONVDIR/$FULLMMF{'cmp'}.$PARALLEL -N $HHEDCONVDIR/$FULLMMF{'dur'}.$PARALLEL -I $FULLMLF -M $HERESTFULL/ -R $HERESTFULL/ -S $TRAIN.split$PARALLEL -T 1 -m 1 -t 5000 5000 10000 -s $STAFILE{'cmp'}.$PARALLEL -u mvwtdmv -w 0.0 $FULLLIST.$PARALLEL $FULLLIST.$PARALLEL");
        }

    }elsif($PARALLEL == -1){ 
        if($MAXCONTEXTSPLIT > 1){
            $splt=1;
            while($splt <= $MAXCONTEXTSPLIT) {  
                if(-e "$FULLLIST.$splt"){     
                     shell("$BIN/HERest -A -B -C $UNFCONFIG -C $REMFLOORCONFIG -D -V $INPUTTRANSFORM -H $HHEDCONVDIR/$FULLMMF{'cmp'}.$splt -N $HHEDCONVDIR/$FULLMMF{'dur'}.$splt -I $FULLMLF -M $HERESTFULL/ -R $HERESTFULL/ -S $TRAIN.split$splt -T 1 -m 1 -t 5000 5000 10000 -s $STAFILE{'cmp'}.$splt -u mvwtdmv -w 0.0 $FULLLIST.$splt $FULLLIST.$splt");
                }
                $splt++;
            }
        }else{
            shell("$BIN/HERest -A -B -C $UNFCONFIG -C $CONFIGCMLLR -C $REMFLOORCONFIG -D -V $INPUTTRANSFORM -H $HHEDCONVDIR/$FULLMMF{'cmp'} -N $HHEDCONVDIR/$FULLMMF{'dur'} -I $FULLMLF -M $HERESTFULL/ -R $HERESTFULL/ -S $TRAIN -T 1 -m 1 -t 5000 5000 10000 -s $STAFILE{'cmp'} -u mvwtdmv -w 0.0 $FULLLIST $FULLLIST");
        }

    }elsif($PARALLEL == 0){ 
        shell("cat $STAFILE{'cmp'}.* > $STAFILE{'cmp'}");
        shell("rm -rf $STAFILE{'cmp'}.* ");
        shell("rm -rf $HERESTMONO/15/$MONOMMF{'cmp'} $HERESTMONO/15/$MONOMMF{'dur'}  ");
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step12 Compress FullContext HMM 
#-----------------------------------------------------------------------

if ($EXEC[12]) {
    print_step(" Compress FullContext HMM");
    print_time("Started at");
    makedir("$HERESTFULL");
    print("Compress FullContext HMM \n");

    if($MAXCONTEXTSPLIT > 1){
        $state = $SSTATE;
        while ($state <= $ESTATE) {
            makedir("$HERESTFULL/$state");
            $splt=1;
            while($splt <= $MAXCONTEXTSPLIT) {
                if(-e "$FULLLIST.$splt"){
                   compstatehed($state, $splt);
                   compstreamsplithed($state, $splt);  
                   shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTFULL/$FULLMMF{'cmp'}.$splt -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.$splt $COMPRESSHED.$state.$splt $FULLLIST.$splt");
                   shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTFULL/$state/$FULLMMF{'cmp'}.$splt -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.mcep.$splt $COMPRESSSTREAMHED.mcep.$state.$splt $FULLLIST.$splt");
                   shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTFULL/$state/$FULLMMF{'cmp'}.$splt -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.logf0.$splt $COMPRESSSTREAMHED.logf0.$state.$splt $FULLLIST.$splt");
                   shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTFULL/$state/$FULLMMF{'cmp'}.$splt -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.bndap.$splt $COMPRESSSTREAMHED.bndap.$state.$splt $FULLLIST.$splt");
                   shell("rm -f $HERESTFULL/$state/$FULLMMF{'cmp'}.$splt $COMPRESSHED.$state.$splt $COMPRESSSTREAMHED.mcep.$state.$splt $COMPRESSSTREAMHED.logf0.$state.$splt $COMPRESSSTREAMHED.bndap.$state.$splt");  
                }
                $splt++;
            }
            
            $splt=1;
            $MODELARGMCEP = " ";
            $MODELARGF0 = " ";
            $MODELARGBND = " ";
            while($splt <= $MAXCONTEXTSPLIT) {
                if(-e "$FULLLIST.$splt"){
                   $MODELARGMCEP = $MODELARGMCEP . " -H $HERESTFULL/$state/$FULLMMF{'cmp'}.mcep.$splt ";
                   $MODELARGF0 = $MODELARGF0 . " -H $HERESTFULL/$state/$FULLMMF{'cmp'}.logf0.$splt ";
                   $MODELARGBND = $MODELARGBND . " -H $HERESTFULL/$state/$FULLMMF{'cmp'}.bndap.$splt ";
                }
                $splt++;
            }
            compstateallhed($state);
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 $MODELARGMCEP -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.mcep $COMPRESSHED.$state.mcep $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 $MODELARGF0 -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.logf0 $COMPRESSHED.$state.logf0 $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 $MODELARGBND -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.bndap $COMPRESSHED.$state.bndap $FULLLIST");
            shell("rm -f $HERESTFULL/$state/$FULLMMF{'cmp'}.mcep.* $HERESTFULL/$state/$FULLMMF{'cmp'}.logf0.* $HERESTFULL/$state/$FULLMMF{'cmp'}.bndap.* $COMPRESSHED.$state.mcep $COMPRESSHED.$state.logf0 $COMPRESSHED.$state.bndap");
            
            # unused model
            shell("touch null.hed");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTFULL/$state/$FULLMMF{'cmp'}.mcep -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.mcep null.hed $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTFULL/$state/$FULLMMF{'cmp'}.logf0 -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.logf0 null.hed $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTFULL/$state/$FULLMMF{'cmp'}.bndap -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.bndap null.hed $FULLLIST");
#            shell("rm -f null.hed");
            $state++;
            
        }
    }else{ 
        $state = $SSTATE;
        while ($state <= $ESTATE) {
            makedir("$HERESTFULL/$state");
            compstatehed($state, 0);
            compstreamsplithed($state, 0);  
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTFULL/$FULLMMF{'cmp'} -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'} $COMPRESSHED.$state $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTFULL/$state/$FULLMMF{'cmp'} -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.mcep $COMPRESSSTREAMHED.mcep.$state $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTFULL/$state/$FULLMMF{'cmp'} -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.logf0 $COMPRESSSTREAMHED.logf0.$state $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTFULL/$state/$FULLMMF{'cmp'} -p -i -w $HERESTFULL/$state/$FULLMMF{'cmp'}.bndap $COMPRESSSTREAMHED.bndap.$state $FULLLIST");
            shell("rm -f $HERESTFULL/$state/$FULLMMF{'cmp'} $COMPRESSHED.$state $COMPRESSSTREAMHED.mcep.$state $COMPRESSSTREAMHED.logf0.$state $COMPRESSSTREAMHED.bndap.$state");  
            $state++; 
        }
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step13. Context Clustering for Spec
#-----------------------------------------------------------------------

if ($EXEC[13]) {
    print_step("Context Clustering for Spec");
    print_time("Started at");
    makedir("$HHEDCLUSTRINGSPEC");
    
    $MDLOPT = "";
    if($TREETHRESH == 1){ # MDL
        $MDLOPT = "-m -a 1";
    }
    $state = $SSTATE;
    while ($state <= $ESTATE) {
        makedir("$HHEDCLUSTRINGSPEC/$state");
        mkclsthed('mcep',$state);
        shell("$BIN/HHEd -A -B -C $CONFIG -C $CONFIGCLUST -D -V -H $HERESTFULL/$state/$FULLMMF{'cmp'}.mcep -T 1 -i $MDLOPT -p -r 1 -w $HHEDCLUSTRINGSPEC/$state/$CLSTMMF{'cmp'} $CLSTHED{'mcep'}.$state $FULLLIST");
        shell("rm -f $HERESTFULL/$state/$FULLMMF{'cmp'}.mcep $CLSTHED{'mcep'}.$state");  
        $state++;
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step14. Context Clustering for LogF0
#-----------------------------------------------------------------------

if ($EXEC[14]) {
    print_step("Context Clustering for logF0");
    print_time("Started at");
    makedir("$HHEDCLUSTRINGLOGF0");
    
    $MDLOPT = "";
    if($TREETHRESH == 1){ # MDL
        $MDLOPT = "-m -a 1";
    }
    $state = $SSTATE;
    while ($state <= $ESTATE) {  
        makedir("$HHEDCLUSTRINGLOGF0/$state");
        mkclsthed('logF0',$state);
        shell("$BIN/HHEd -A -B -C $CONFIG -C $CONFIGCLUST -D -V -H $HERESTFULL/$state/$FULLMMF{'cmp'}.logf0 -T 1 $MDLOPT -i -p -r 1 -w $HHEDCLUSTRINGLOGF0/$state/$CLSTMMF{'cmp'} $CLSTHED{'logF0'}.$state $FULLLIST");
        shell("rm -f $HERESTFULL/$state/$FULLMMF{'cmp'}.logf0 $CLSTHED{'logF0'}.$state");  
        $state++;
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step15. Context Clustering for Bndap
#-----------------------------------------------------------------------

if ($EXEC[15]) {
    print_step("Context Clustering for Bndap");
    print_time("Started at");
    makedir("$HHEDCLUSTRINGBND");
    
    $MDLOPT = "";
    if($TREETHRESH == 1){ # MDL
        $MDLOPT = "-m -a 1";
    }
    $state = $SSTATE;
    while ($state <= $ESTATE) {
        makedir("$HHEDCLUSTRINGBND/$state");  
        mkclsthed('bndap',$state);
        shell("$BIN/HHEd -A -B -C $CONFIG -C $CONFIGCLUST -D -V -H $HERESTFULL/$state/$FULLMMF{'cmp'}.bndap -T 1 $MDLOPT -i -p -r 1 -w $HHEDCLUSTRINGBND/$state/$CLSTMMF{'cmp'} $CLSTHED{'bndap'}.$state $FULLLIST");
        shell("rm -f $HERESTFULL/$state/$FULLMMF{'cmp'}.bndap $CLSTHED{'bndap'}.$state");  
        $state++;
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step16. Context Clustering for Duration
#-----------------------------------------------------------------------

if ($EXEC[16]) {
    print_step("Context Clustering for Duration");
    print_time("Started at");
    makedir("$HHEDCLUSTRINGDUR");
    
    $MDLOPT = "";
    if($TREETHRESH == 1){ # MDL
        $MDLOPT = "-m -a 1";
    }
    conv_stat();
    mkclsthed('dur', 1);
    if($MAXCONTEXTSPLIT > 1){
        $splt=1;
        $MODELARG = " ";
        while($splt <= $MAXCONTEXTSPLIT) {
            if(-e "$FULLLIST.$splt"){
               $MODELARG = $MODELARG . " -H $HERESTFULL/$FULLMMF{'dur'}.$splt ";
            }
            $splt++;
        }
    }else{
        $MODELARG = " -H $HERESTFULL/$FULLMMF{'dur'} ";
    }
    shell("$BIN/HHEd -A -B -C $CONFIG -C $CONFIGDURCLUST -D -V $MODELARG -T 1 $MDLOPT -i -p -r 1 -w $HHEDCLUSTRINGDUR/$CLSTMMF{'dur'} $CLSTHED{'dur'} $FULLLIST");
    shell("rm -f $HERESTFULL/$state/$FULLMMF{'dur'}* $CLSTHED{'dur'}");  
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step17 Cat Model
#-----------------------------------------------------------------------

if ($EXEC[17]) {
    print_step("Cat Model");
    print_time("Started at");
    makedir("$HERESTCLUSTED/0");
    
    # Model cat 
    # Since UT requires huge memory space, combine states separetely and save model
    shell("rm -f $HHEDCLUSTRINGBND/$CLSTMMF{'cmp'}.*");
    shell("ln -s $HHEDCLUSTRINGSPEC/2/$CLSTMMF{'cmp'} $HHEDCLUSTRINGBND/$CLSTMMF{'cmp'}.1");
    for ($i=2;$i<=$NUMSTATE+1;$i++) {
      joinmodeled($i);
      $ii = $i-1;
      if($i == $NUMSTATE+1){ 
         shell("$BIN/HHEd -A -B -C $CONFIG -D -V -H $HHEDCLUSTRINGBND/$CLSTMMF{'cmp'}.$ii -T 1 -a 1 -i -m -p -s -w $HHEDCLUSTRINGBND/$CLSTMMF{'cmp'} $JOINHED.$i $FULLLIST");
      }else{
         shell("$BIN/HHEd -A -B -C $CONFIG -D -V -H $HHEDCLUSTRINGBND/$CLSTMMF{'cmp'}.$ii -T 1 -a 1 -i -m -p -s -w $HHEDCLUSTRINGBND/$CLSTMMF{'cmp'}.$i $JOINHED.$i $FULLLIST");
 
      }
    }
    
    # Tied List 
    mktieded('cmp');
    shell("$BIN/HHEd -A -B -C $CONFIG -D -V -H $HHEDCLUSTRINGBND/$CLSTMMF{'cmp'} -T 1 -a 1 -i -m -p -s -w $HERESTCLUSTED/0/$CLSTMMF{'cmp'} $TIEDHED{'cmp'} $FULLLIST");
    mktieded('dur');
    shell("$BIN/HHEd -A -B -C $CONFIG -D -V -H $HHEDCLUSTRINGDUR/$CLSTMMF{'dur'} -T 1 -a 1 -i -m -p -w $HERESTCLUSTED/0/$CLSTMMF{'dur'} $TIEDHED{'dur'} $FULLLIST");

    cattreehed();
    shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTCLUSTED/0/$CLSTMMF{'cmp'} -i -p $CATTREEHED.mcep $TIEDLIST{'cmp'}");
    shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTCLUSTED/0/$CLSTMMF{'cmp'} -i -p $CATTREEHED.logF0 $TIEDLIST{'cmp'}");
    shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTCLUSTED/0/$CLSTMMF{'cmp'} -i -p $CATTREEHED.bndap $TIEDLIST{'cmp'}");
    
    shell("cp $OUTBASE $HERESTCLUSTED/");
    shell("cp $DURBASE $HERESTCLUSTED/");

    shell("rm -f $STAFILE{'cmp'} $STAFILE{'dur'}");
    shell("rm -f $HERESTFULL/*/$FULLMMF{'cmp'}*");
    shell("rm -f $HHEDCLUSTRINGSPEC/*/$CLSTMMF{'cmp'} $TIEDHED{'cmp'} $TIEDHED{'dur'} $CATTREEHED.mcep");
    shell("rm -f $HHEDCLUSTRINGLOGF0/*/$CLSTMMF{'cmp'} $CATTREEHED.logF0");
    shell("rm -f $HHEDCLUSTRINGBND/*/$CLSTMMF{'cmp'} $HHEDCLUSTRINGBND/$CLSTMMF{'cmp'} $HHEDCLUSTRINGBND/$CLSTMMF{'cmp'}.* $CATTREEHED.bndap $JOINHED");
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step18  Embedded Training for Clustered HMM
#-----------------------------------------------------------------------

if ($EXEC[18]) {
    print_step(" Embedded Training for Clustered HMM ");
    print_time("Started at");
    makedir("$HERESTCLUSTED");
    
    $i = $SITER;
    while ($i <= $EITER) {
        print("\n\nIteration ", $i, " of Embedded Training for Clustered HMM\n");
        makedir("$HERESTCLUSTED/$i");
        $ii=$i-1;
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -M $HERESTCLUSTED/$i -R $HERESTCLUSTED/$i -S $TRAIN -T 1 -m 1 -t 5000 5000 10000 -u mvwtdmv -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
             shell("rm -rf $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'}");
        }elsif ($PARALLEL>0){
            shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -M $HERESTCLUSTED/$i -R $HERESTCLUSTED/$i -S $TRAIN.$PARALLEL -T 1 -m 1 -t 5000 5000 10000 -p $PARALLEL -u mvwtdmv -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
        }elsif ($PARALLEL==0){
            shell("find $HERESTCLUSTED/$i/ -name '*.acc' -print | sort > $HERESTCLUSTED/$i/AccList");
            shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -M $HERESTCLUSTED/$i -R $HERESTCLUSTED/$i -S $HERESTCLUSTED/$i/AccList -T 1 -m 1 -t 5000 5000 10000 -p $PARALLEL -u mvwtdmv -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
            shell("echo $HERESTCLUSTED/$i/*.acc | xargs rm -rf");
            shell("rm -rf $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'}");
        }
        $i++;
    }

    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step19  Transformation Estimation for Clustered HMM
#-----------------------------------------------------------------------

if ($EXEC[19]) {
    print_step(" Transformation Estimation for Clustered HMM ");
    print_time("Started at");
    makedir("$HERESTCLUSTED");
    
    print("Transform Estimation 1 for Clustered HMM \n");
    makedir("$HERESTCLUSTED/cmllr");
    $INPUTTRANSFORM = "";
    $i = $SITERTRANS;
    while ($i <= $EITERTRANS) {
        $in = $i-1;
        if($i>1){
            $INPUTTRANSFORM = "-J $HERESTMONO -Y $HERESTMONO -J $HERESTCLUSTED/cmllr cmp.cmllr$in -Y $HERESTCLUSTED/cmllr dur.cmllr$in -a -b ";
        }else{
            $INPUTTRANSFORM = "-J $HERESTMONO -Y $HERESTMONO -J $HERESTMONO/cmllr cmp.cmllr6 -Y $HERESTMONO/cmllr dur.cmllr6 -a -b ";
        }
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -H $HERESTCLUSTED/5/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/5/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTCLUSTED -Y $HERESTCLUSTED $INPUTTRANSFORM -K $HERESTCLUSTED/cmllr cmp.cmllr$i -Z $HERESTCLUSTED/cmllr dur.cmllr$i -M $HERESTCLUSTED/cmllr -R $HERESTCLUSTED/cmllr -S $TRAIN -T 1 -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u ada -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
            shell("echo $HERESTCLUSTED/cmllr/*.cmllr$in | xargs rm -rf");    
        }elsif ($PARALLEL>0){ # subset = speaker
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -H $HERESTCLUSTED/5/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/5/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTCLUSTED -Y $HERESTCLUSTED $INPUTTRANSFORM -K $HERESTCLUSTED/cmllr cmp.cmllr$i -Z $HERESTCLUSTED/cmllr dur.cmllr$i -M $HERESTCLUSTED/cmllr -R $HERESTCLUSTED/cmllr -S $TRAIN.speaker$SPEAKER{$PARALLEL} -T 1 -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u ada -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
        }
        $i++;
    }
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step20  SAT 1 for Clustered HMM
#-----------------------------------------------------------------------

if ($EXEC[20]) {
    print_step(" SAT 1 for Clustered HMM ");
    print_time("Started at");
    makedir("$HERESTCLUSTED");
    
    $i = 5+$SITER;
    while ($i <= 5+$EITER) {
        print("\n\nIteration ", $i, " of Speaker Adaptive Training for Clustered HMM\n");
        makedir("$HERESTCLUSTED/$i");
        $ii=$i-1;
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -E $HERESTCLUSTED/cmllr cmp.cmllr3 -W $HERESTCLUSTED/cmllr dur.cmllr3 -H $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTMONO -Y $HERESTMONO -J $HERESTCLUSTED -Y $HERESTCLUSTED -J $HERESTCLUSTED/cmllr cmp.cmllr3 -Y $HERESTCLUSTED/cmllr dur.cmllr3 -K $HERESTCLUSTED/$i -Z $HERESTCLUSTED/$i -M $HERESTCLUSTED/$i -R $HERESTCLUSTED/$i -S $TRAIN -T 1 -a -b -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u mvwtdmv -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
            shell("rm -rf $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'}");
        }elsif ($PARALLEL>0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -E $HERESTCLUSTED/cmllr cmp.cmllr3 -W $HERESTCLUSTED/cmllr dur.cmllr3 -H $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTMONO -Y $HERESTMONO -J $HERESTCLUSTED -Y $HERESTCLUSTED -J $HERESTCLUSTED/cmllr cmp.cmllr3 -Y $HERESTCLUSTED/cmllr dur.cmllr3 -K $HERESTCLUSTED/$i -Z $HERESTCLUSTED/$i -M $HERESTCLUSTED/$i -R $HERESTCLUSTED/$i -S $TRAIN.$PARALLEL -T 1 -a -b -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -p $PARALLEL -u mvwtdmv -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
        }elsif ($PARALLEL==0){
            shell("find $HERESTCLUSTED/$i/ -name '*.acc' -print | sort > $HERESTCLUSTED/$i/AccList");
            shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -M $HERESTCLUSTED/$i -R $HERESTCLUSTED/$i -S $HERESTCLUSTED/$i/AccList -T 1 -m 1 -t 5000 5000 10000 -p $PARALLEL -u mvwtdmv -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
            shell("echo $HERESTCLUSTED/$i/*.acc | xargs rm -rf");
            shell("rm -rf $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'}");
        }
        $i++;
    }

    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step21  Transformation Estimation 2 for Clustered HMM
#-----------------------------------------------------------------------

if ($EXEC[21]) {
    print_step(" Transformation Estimation 2 for Clustered HMM ");
    print_time("Started at");
    makedir("$HERESTCLUSTED");
    
    print("Transform Estimation 2 for Clustered HMM \n");
    makedir("$HERESTCLUSTED/cmllr");
    $INPUTTRANSFORM = "";
    $i = $SITERTRANS+3;
    while ($i <= $EITERTRANS+3) {
        $in = $i-1;
        $INPUTTRANSFORM = "-J $HERESTMONO -Y $HERESTMONO -J $HERESTCLUSTED/cmllr cmp.cmllr$in -Y $HERESTCLUSTED/cmllr dur.cmllr$in -a -b ";
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -H $HERESTCLUSTED/10/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/10/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTCLUSTED -Y $HERESTCLUSTED $INPUTTRANSFORM -K $HERESTCLUSTED/cmllr cmp.cmllr$i -Z $HERESTCLUSTED/cmllr dur.cmllr$i -M $HERESTCLUSTED/cmllr -R $HERESTCLUSTED/cmllr -S $TRAIN -T 1 -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u ada -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
            shell("echo $HERESTCLUSTED/cmllr/*.cmllr$in | xargs rm -rf");    
        }elsif ($PARALLEL>0){ # subset = speaker
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -H $HERESTCLUSTED/10/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/10/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTCLUSTED -Y $HERESTCLUSTED $INPUTTRANSFORM -K $HERESTCLUSTED/cmllr cmp.cmllr$i -Z $HERESTCLUSTED/cmllr dur.cmllr$i -M $HERESTCLUSTED/cmllr -R $HERESTCLUSTED/cmllr -S $TRAIN.speaker$SPEAKER{$PARALLEL} -T 1 -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u ada -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
        }
        $i++;
    }

    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step22  SAT 2 for Clustered HMM
#-----------------------------------------------------------------------

if ($EXEC[22]) {
    print_step(" SAT 2 for Clustered HMM ");
    print_time("Started at");
    makedir("$HERESTCLUSTED");
    
    $i = 10+$SITER;
    while ($i <= 10+$EITER) {
        print("\n\nIteration ", $i, " of Speaker Adaptive Training for Clustered HMM\n");
        makedir("$HERESTCLUSTED/$i");
        $ii=$i-1;
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -E $HERESTCLUSTED/cmllr cmp.cmllr6 -W $HERESTCLUSTED/cmllr dur.cmllr6 -H $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTMONO -Y $HERESTMONO -J $HERESTCLUSTED -Y $HERESTCLUSTED -J $HERESTCLUSTED/cmllr cmp.cmllr6 -Y $HERESTCLUSTED/cmllr dur.cmllr6 -K $HERESTCLUSTED/$i -Z $HERESTCLUSTED/$i -M $HERESTCLUSTED/$i -R $HERESTCLUSTED/$i -S $TRAIN -T 1 -a -b -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u mvwtdmv -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
            shell("rm -rf $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'}");
        }elsif ($PARALLEL>0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLR -D -V -E $HERESTCLUSTED/cmllr cmp.cmllr6 -W $HERESTCLUSTED/cmllr dur.cmllr6 -H $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTMONO -Y $HERESTMONO -J $HERESTCLUSTED -Y $HERESTCLUSTED -J $HERESTCLUSTED/cmllr cmp.cmllr6 -Y $HERESTCLUSTED/cmllr dur.cmllr6 -K $HERESTCLUSTED/$i -Z $HERESTCLUSTED/$i -M $HERESTCLUSTED/$i -R $HERESTCLUSTED/$i -S $TRAIN.$PARALLEL -T 1 -a -b -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -p $PARALLEL -u mvwtdmv -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
        }elsif ($PARALLEL==0){
            shell("find $HERESTCLUSTED/$i/ -name '*.acc' -print | sort > $HERESTCLUSTED/$i/AccList");
            shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -M $HERESTCLUSTED/$i -R $HERESTCLUSTED/$i -S $HERESTCLUSTED/$i/AccList -T 1 -m 1 -t 5000 5000 30000 -p $PARALLEL -u mvwtdmv -w 3 $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
            shell("echo $HERESTCLUSTED/$i/*.acc | xargs rm -rf");
            shell("rm -rf $HERESTCLUSTED/$ii/$CLSTMMF{'dur'} $HERESTCLUSTED/$ii/$CLSTMMF{'cmp'}");
        }
        $i++;
    }
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step23 Untying of Clustered HMM
#-----------------------------------------------------------------------

if ($EXEC[23]) {
    print_step("Untying of Clustered HSMM");
    print_time("Started at");
    makedir("$HHEDUNTIE");
    
    if($PARALLEL >= 1){
        if(-e "$FULLLIST.$PARALLEL"){
            mkuntieed('cmp', $PARALLEL);
            shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HERESTCLUSTED/15/$CLSTMMF{'cmp'} -p -i -w $HHEDUNTIE/$FULLMMF{'cmp'}.$PARALLEL $UNTIEED{'cmp'}.$PARALLEL $TIEDLIST{'cmp'}");
            mkuntieed('dur', $PARALLEL);
            shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HERESTCLUSTED/15/$CLSTMMF{'dur'} -p -i -w $HHEDUNTIE/$FULLMMF{'dur'}.$PARALLEL $UNTIEED{'dur'}.$PARALLEL $TIEDLIST{'dur'}");
            # remove unused models
            shell("touch null.hed");            
            shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HHEDUNTIE/$FULLMMF{'cmp'}.$PARALLEL -p -i -w $HHEDUNTIE/$FULLMMF{'cmp'}.$PARALLEL null.hed $FULLLIST.$PARALLEL");
            shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HHEDUNTIE/$FULLMMF{'dur'}.$PARALLEL -p -i -w $HHEDUNTIE/$FULLMMF{'dur'}.$PARALLEL null.hed $FULLLIST.$PARALLEL");
            shell("rm -f $UNTIEED{'dur'}.$PARALLEL $UNTIEED{'cmp'}.$PARALLEL ");
        }
    }elsif($PARALLEL == -1){
        if($MAXCONTEXTSPLIT > 1){
            $splt=1;
            while($splt <= $MAXCONTEXTSPLIT) { 
                if(-e "$FULLLIST.$splt"){
                    mkuntieed('cmp', $splt);
                    shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HERESTCLUSTED/15/$CLSTMMF{'cmp'} -p -i -w $HHEDUNTIE/$FULLMMF{'cmp'}.$splt $UNTIEED{'cmp'}.$splt $TIEDLIST{'cmp'}");
                    mkuntieed('dur', $splt);
                    shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HERESTCLUSTED/15/$CLSTMMF{'dur'} -p -i -w $HHEDUNTIE/$FULLMMF{'dur'}.$splt $UNTIEED{'dur'}.$splt $TIEDLIST{'dur'}");
                    # remove unused models
                    shell("touch null.hed");            
                    shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HHEDUNTIE/$FULLMMF{'cmp'}.$splt -p -i -w $HHEDUNTIE/$FULLMMF{'cmp'}.$splt null.hed $FULLLIST.$splt");
                    shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HHEDUNTIE/$FULLMMF{'dur'}.$splt -p -i -w $HHEDUNTIE/$FULLMMF{'dur'}.$splt null.hed $FULLLIST.$splt");
                    shell("rm -f $UNTIEED{'dur'}.$splt $UNTIEED{'cmp'}.$splt ");
                }
                $splt++;
            }
        }else{
            mkuntieed('cmp', 0);
            shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HERESTCLUSTED/15/$CLSTMMF{'cmp'} -p -i -w $HHEDUNTIE/$FULLMMF{'cmp'} $UNTIEED{'cmp'} $TIEDLIST{'cmp'}");
            mkuntieed('dur', 0);
            shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HERESTCLUSTED/15/$CLSTMMF{'dur'} -p -i -w $HHEDUNTIE/$FULLMMF{'dur'} $UNTIEED{'dur'} $TIEDLIST{'dur'}");
    
            # remove unused models
            shell("touch null.hed");            
            shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HHEDUNTIE/$FULLMMF{'cmp'} -p -i -w $HHEDUNTIE/$FULLMMF{'cmp'} null.hed $FULLLIST");
            shell("$BIN/HHEd -A -B -C $CONFIG -D -V -T 1 -H $HHEDUNTIE/$FULLMMF{'dur'} -p -i -w $HHEDUNTIE/$FULLMMF{'dur'} null.hed $FULLLIST");
    
            shell("rm -f $UNTIEED{'dur'} $UNTIEED{'cmp'}");
            shell("rm -rf $HERESTCLUSTED/15/$CLSTMMF{'dur'} $HERESTCLUSTED/15/$CLSTMMF{'cmp'} $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
        }
    }

    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step24 Embedded Training for Re-Alignment
#-----------------------------------------------------------------------

if ($EXEC[24]) {
    print_step(" Embedded Training for Re-Alignment");
    print_time("Started at");
    makedir("$HERESTREALIGN");
    print("Embedded Training for Re-Alignment \n");

    $INPUTTRANSFORM = "-C $CONFIGCMLLR -a -b -h \"*/%%%*.cmp\" -E $HERESTCLUSTED/cmllr cmp.cmllr6 -W $HERESTCLUSTED/cmllr dur.cmllr6 -J $HERESTMONO -Y $HERESTMONO -J $HERESTCLUSTED -Y $HERESTCLUSTED -J $HERESTCLUSTED/cmllr cmp.cmllr6 -Y $HERESTCLUSTED/cmllr dur.cmllr6 ";

    if($PARALLEL >= 1){    
        if(-e "$FULLLIST.$PARALLEL"){
            shell("$BIN/HERest -A -B -C $UNFCONFIG -C $REMFLOORCONFIG -D -V $INPUTTRANSFORM -H $HHEDUNTIE/$FULLMMF{'cmp'}.$PARALLEL -N $HHEDUNTIE/$FULLMMF{'dur'}.$PARALLEL -I $FULLMLF -M $HERESTREALIGN/ -R $HERESTREALIGN/  -S $TRAIN.split$PARALLEL -T 1 -m 1 -t 5000 5000 10000 -s $REALIGNSTAFILE{'cmp'}.$PARALLEL -u mvwtdmv -w 0.0 $FULLLIST.$PARALLEL $FULLLIST.$PARALLEL");
        }
        
    }elsif($PARALLEL == -1){ 
        if($MAXCONTEXTSPLIT > 1 ){
            $splt=1;
            while($splt <= $MAXCONTEXTSPLIT) {
                if(-e "$FULLLIST.$splt"){
                    shell("$BIN/HERest -A -B -C $UNFCONFIG -C $REMFLOORCONFIG -D -V $INPUTTRANSFORM -H $HHEDUNTIE/$FULLMMF{'cmp'}.$splt -N $HHEDUNTIE/$FULLMMF{'dur'}.$splt -I $FULLMLF -M $HERESTREALIGN/ -R $HERESTREALIGN/  -S $TRAIN.split$splt -T 1 -m 1 -t 5000 5000 10000 -s $REALIGNSTAFILE{'cmp'}.$splt -u mvwtdmv -w 0.0 $FULLLIST.$splt $FULLLIST.$splt");
                }
                $splt++;
            }
        }else{
            shell("$BIN/HERest -A -B -C $UNFCONFIG -C $REMFLOORCONFIG -D -V $INPUTTRANSFORM -H $HHEDUNTIE/$FULLMMF{'cmp'} -N $HHEDUNTIE/$FULLMMF{'dur'} -I $FULLMLF -M $HERESTREALIGN/ -R $HERESTREALIGN/ -S $TRAIN -T 1 -m 1 -t 5000 5000 10000 -s $REALIGNSTAFILE{'cmp'} -u mvwtdmv -w 0.0 $FULLLIST $FULLLIST");
        }
        
    }elsif($PARALLEL == 0){ 
        shell("cat $REALIGNSTAFILE{'cmp'}.* > $REALIGNSTAFILE{'cmp'}");
        shell("rm -rf $REALIGNSTAFILE{'cmp'}.* ");
        shell("rm -rf $HERESTCLUSTED/15/$CLSTMMF{'dur'} $HERESTCLUSTED/15/$CLSTMMF{'cmp'} $TIEDLIST{'cmp'} $TIEDLIST{'dur'}");
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step25 Compress FullContext HMM 
#-----------------------------------------------------------------------

if ($EXEC[25]) {
    print_step(" Compress FullContext HMM");
    print_time("Started at");
    makedir("$HERESTREALIGN");
    print("Compress FullContext HMM \n");

    if($MAXCONTEXTSPLIT >= 1){
        $state = $SSTATE;
        while ($state <= $ESTATE) {
            makedir("$HERESTREALIGN/$state");
            $splt=1;
            while($splt <= $MAXCONTEXTSPLIT) {
                if(-e "$FULLLIST.$splt"){
                   compstatehed($state, $splt);
                   compstreamsplithed($state, $splt);  
                   shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTREALIGN/$FULLMMF{'cmp'}.$splt -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.$splt $COMPRESSHED.$state.$splt $FULLLIST.$splt");
                   shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTREALIGN/$state/$FULLMMF{'cmp'}.$splt -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.mcep.$splt $COMPRESSSTREAMHED.mcep.$state.$splt $FULLLIST.$splt");
                   shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTREALIGN/$state/$FULLMMF{'cmp'}.$splt -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.logf0.$splt $COMPRESSSTREAMHED.logf0.$state.$splt $FULLLIST.$splt");
                   shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTREALIGN/$state/$FULLMMF{'cmp'}.$splt -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.bndap.$splt $COMPRESSSTREAMHED.bndap.$state.$splt $FULLLIST.$splt");
                   shell("rm -f $HERESTREALIGN/$state/$FULLMMF{'cmp'}.$splt $COMPRESSHED.$state.$splt $COMPRESSSTREAMHED.mcep.$state.$splt $COMPRESSSTREAMHED.logf0.$state.$splt $COMPRESSSTREAMHED.bndap.$state.$splt");
                }
                $splt++;
            }
            
            $splt=1;
            $MODELARGMCEP = " ";
            $MODELARGF0 = " ";
            $MODELARGBND = " ";
            while($splt <= $MAXCONTEXTSPLIT) {
                if(-e "$FULLLIST.$splt"){
                   $MODELARGMCEP = $MODELARGMCEP . " -H $HERESTREALIGN/$state/$FULLMMF{'cmp'}.mcep.$splt ";
                   $MODELARGF0 = $MODELARGF0 . " -H $HERESTREALIGN/$state/$FULLMMF{'cmp'}.logf0.$splt ";
                   $MODELARGBND = $MODELARGBND . " -H $HERESTREALIGN/$state/$FULLMMF{'cmp'}.bndap.$splt ";
                }
                $splt++;
            }
            compstateallhed($state);
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 $MODELARGMCEP -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.mcep $COMPRESSHED.$state.mcep $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 $MODELARGF0 -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.logf0 $COMPRESSHED.$state.logf0 $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 $MODELARGBND -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.bndap $COMPRESSHED.$state.bndap $FULLLIST");
            shell("rm -f $HERESTREALIGN/$state/$FULLMMF{'cmp'}.mcep.* $HERESTREALIGN/$state/$FULLMMF{'cmp'}.logf0.* $HERESTREALIGN/$state/$FULLMMF{'cmp'}.bndap.* $COMPRESSHED.$state.mcep $COMPRESSHED.$state.logf0 $COMPRESSHED.$state.bndap");
            
            # unused model
            shell("touch null.hed");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTREALIGN/$state/$FULLMMF{'cmp'}.mcep -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.mcep null.hed $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTREALIGN/$state/$FULLMMF{'cmp'}.logf0 -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.logf0 null.hed $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTREALIGN/$state/$FULLMMF{'cmp'}.bndap -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.bndap null.hed $FULLLIST");            
#            shell("rm -f null.hed");
            $state++;
        }
    }else{
        $state = $SSTATE;
        while ($state <= $ESTATE) {
            makedir("$HERESTREALIGN/$state");
            compstatehed($state, 0);
            compstreamsplithed($state, 0);  
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTREALIGN/$FULLMMF{'cmp'} -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'} $COMPRESSHED.$state $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTREALIGN/$state/$FULLMMF{'cmp'} -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.mcep $COMPRESSSTREAMHED.mcep.$state $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTREALIGN/$state/$FULLMMF{'cmp'} -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.logf0 $COMPRESSSTREAMHED.logf0.$state $FULLLIST");
            shell("$BIN/HHEd -A -B -C $UNFCONFIG -D -V -T 1 -H $HERESTREALIGN/$state/$FULLMMF{'cmp'} -p -i -w $HERESTREALIGN/$state/$FULLMMF{'cmp'}.bndap $COMPRESSSTREAMHED.bndap.$state $FULLLIST");
            shell("rm -f $HERESTREALIGN/$state/$FULLMMF{'cmp'} $COMPRESSHED.$state $COMPRESSSTREAMHED.mcep.$state $COMPRESSSTREAMHED.logf0.$state $COMPRESSSTREAMHED.bndap.$state");
            $state++;
        }
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step26. Context Re-Clustering for Spec
#-----------------------------------------------------------------------

if ($EXEC[26]) {
    print_step("Context Re-Clustering for Spec");
    print_time("Started at");
    makedir("$HHEDRECLUSTRINGSPEC");
    
    $MDLOPT = "";
    if($TREETHRESH == 1){ # MDL
        $MDLOPT = "-m -a 1";
    }
    $state = $SSTATE;
    while ($state <= $ESTATE) {
        makedir("$HHEDRECLUSTRINGSPEC/$state");
        mkreclsthed('mcep',$state);
        shell("$BIN/HHEd -A -B -C $CONFIG -C $CONFIGCLUST -D -V -H $HERESTREALIGN/$state/$FULLMMF{'cmp'}.mcep -T 1 $MDLOPT -i -p -r 1 -w $HHEDRECLUSTRINGSPEC/$state/$CLSTMMF{'cmp'} $RECLSTHED{'mcep'}.$state $FULLLIST");
        shell("rm -f $HERESTREALIGN/$state/$FULLMMF{'cmp'}.mcep $RECLSTHED{'mcep'}.$state");
        $state++;
    }
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step27. Context Re-Clustering for LogF0
#-----------------------------------------------------------------------

if ($EXEC[27]) {
    print_step("Context Re-Clustering for logF0");
    print_time("Started at");
    makedir("$HHEDRECLUSTRINGLOGF0");

    $MDLOPT = "";
    if($TREETHRESH == 1){ # MDL
        $MDLOPT = "-m -a 1";
    }
    $state = $SSTATE;
    while ($state <= $ESTATE) {
        makedir("$HHEDRECLUSTRINGLOGF0/$state");
        mkreclsthed('logF0',$state);
        shell("$BIN/HHEd -A -B -C $CONFIG -C $CONFIGCLUST -D -V -H $HERESTREALIGN/$state/$FULLMMF{'cmp'}.logf0 -T 1 $MDLOPT -i -p -r 1 -w $HHEDRECLUSTRINGLOGF0/$state/$CLSTMMF{'cmp'} $RECLSTHED{'logF0'}.$state $FULLLIST");
        shell("rm -f $HERESTREALIGN/$state/$FULLMMF{'cmp'}.logf0 $RECLSTHED{'logF0'}.$state");
        $state++;
    }
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step28. Context Re-Clustering for Bndap
#-----------------------------------------------------------------------

if ($EXEC[28]) {
    print_step("Context Re-Clustering for Bndap");
    print_time("Started at");
    makedir("$HHEDRECLUSTRINGBND");

    $MDLOPT = "";
    if($TREETHRESH == 1){ # MDL
        $MDLOPT = "-m -a 1";
    }
    $state = $SSTATE;
    while ($state <= $ESTATE) {
        makedir("$HHEDRECLUSTRINGBND/$state");
        mkreclsthed('bndap',$state);
        shell("$BIN/HHEd -A -B -C $CONFIG -C $CONFIGCLUST -D -H $HERESTREALIGN/$state/$FULLMMF{'cmp'}.bndap -T 1 $MDLOPT -i -p -r 1 -w $HHEDRECLUSTRINGBND/$state/$CLSTMMF{'cmp'} $RECLSTHED{'bndap'}.$state $FULLLIST");
        shell("rm -f $HERESTREALIGN/$state/$FULLMMF{'cmp'}.bndap $RECLSTHED{'bndap'}.$state");
        $state++;
    }        
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step29. Context Re-Clustering for Duration
#-----------------------------------------------------------------------

if ($EXEC[29]) {
    print_step("Context Re-Clustering for Duration");
    print_time("Started at");
    makedir("$HHEDRECLUSTRINGDUR");

    $MDLOPT = "";
    if($TREETHRESH == 1){ # MDL
        $MDLOPT = "-m -a 1";
    }
    conv_stat_realign();
    mkreclsthed('dur', 1);
    if($MAXCONTEXTSPLIT > 1){
        $splt=1;
        $MODELARG = " ";
        while($splt <= $MAXCONTEXTSPLIT) {           
            if(-e "$FULLLIST.$splt"){
               $MODELARG = $MODELARG . " -H $HERESTREALIGN/$FULLMMF{'dur'}.$splt ";
            }
            $splt++;
        }
    }else{
        $MODELARG = " -H $HERESTREALIGN/$FULLMMF{'dur'} ";
    }
    shell("$BIN/HHEd -A -B -C $CONFIG -C $CONFIGDURCLUST -D -V $MODELARG -T 1 $MDLOPT -i -p -r 1 -w $HHEDRECLUSTRINGDUR/$CLSTMMF{'dur'} $RECLSTHED{'dur'} $FULLLIST");
    shell("rm -f $HERESTREALIGN/$FULLMMF{'dur'}* $RECLSTHED{'dur'}");
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step30 Cat Model
#-----------------------------------------------------------------------

if ($EXEC[30]) {
    print_step("Cat Model");
    print_time("Started at");
    makedir("$HERESTRECLUSTED/0");
    
    # Model cat 
    # Since UT requires huge memory space, combine states separetely and save model
    shell("rm -f $HHEDRECLUSTRINGBND/$CLSTMMF{'cmp'}.*");
    shell("ln -s $HHEDRECLUSTRINGSPEC/2/$CLSTMMF{'cmp'} $HHEDRECLUSTRINGBND/$CLSTMMF{'cmp'}.1");
    for ($i=2;$i<=$NUMSTATE+1;$i++) {
      rejoinmodeled($i);
      $ii = $i-1;
      if($i == $NUMSTATE+1){
         shell("$BIN/HHEd -A -B -C $CONFIG -D -V -H $HHEDRECLUSTRINGBND/$CLSTMMF{'cmp'}.$ii -T 1 -a 1 -i -m -p -s -w $HHEDRECLUSTRINGBND/$CLSTMMF{'cmp'} $REJOINHED.$i $FULLLIST");
      }else{
         shell("$BIN/HHEd -A -B -C $CONFIG -D -V -H $HHEDRECLUSTRINGBND/$CLSTMMF{'cmp'}.$ii -T 1 -a 1 -i -m -p -s -w $HHEDRECLUSTRINGBND/$CLSTMMF{'cmp'}.$i $REJOINHED.$i $FULLLIST");

     }
   }



    # Tied List 
    mkretieded('cmp');
    shell("$BIN/HHEd -A -B -C $CONFIG -D -V -H $HHEDRECLUSTRINGBND/$CLSTMMF{'cmp'} -T 1 -a 1 -i -m -p -s -w $HERESTRECLUSTED/0/$CLSTMMF{'cmp'} $RETIEDHED{'cmp'} $FULLLIST");
    mkretieded('dur');
    shell("$BIN/HHEd -A -B -C $CONFIG -D -V -H $HHEDRECLUSTRINGDUR/$CLSTMMF{'dur'} -T 1 -a 1 -i -m -p -w $HERESTRECLUSTED/0/$CLSTMMF{'dur'} $RETIEDHED{'dur'} $FULLLIST");

    recattreehed();
    shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/0/$CLSTMMF{'cmp'} -i -p $RECATTREEHED.mcep $RETIEDLIST{'cmp'}");
    shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/0/$CLSTMMF{'cmp'} -i -p $RECATTREEHED.logF0 $RETIEDLIST{'cmp'}");
    shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/0/$CLSTMMF{'cmp'} -i -p $RECATTREEHED.bndap $RETIEDLIST{'cmp'}");
    
    shell("rm -f $HERESTREALIGN/$FULLMMF{'cmp'}*");
    shell("rm -f $HHEDRECLUSTRINGSPEC/*/$CLSTMMF{'cmp'} $RECATTREEHED.mcep");
    shell("rm -f $HHEDRECLUSTRINGLOGF0/*/$CLSTMMF{'cmp'} $RECATTREEHED.logF0");
    shell("rm -f $HHEDRECLUSTRINGBND/*/$CLSTMMF{'cmp'} $RECATTREEHED.bndap $HHEDRECLUSTRINGBND/$CLSTMMF{'cmp'} $HHEDRECLUSTRINGBND/$CLSTMMF{'cmp'}.* $REJOINHED");
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step31  Embedded Training for Clustered HMM
#-----------------------------------------------------------------------

if ($EXEC[31]) {
    print_step(" Embedded Training for Clustered HMM ");
    print_time("Started at");
    makedir("$HERESTRECLUSTED");
    
    $i = $SITER;
    while ($i <= $EITER) {
        print("\n\nIteration ", $i, " of Embedded Training for Clustered HMM\n");
        makedir("$HERESTRECLUSTED/$i");
        $ii=$i-1;
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -M $HERESTRECLUSTED/$i -R $HERESTRECLUSTED/$i -S $TRAIN -T 1 -m 1 -t 5000 5000 10000 -u mvwtdmv -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
            shell("rm -f $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'}");
        }elsif ($PARALLEL>0){
            shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -M $HERESTRECLUSTED/$i -R $HERESTRECLUSTED/$i -S $TRAIN.$PARALLEL -T 1 -m 1 -t 5000 5000 10000 -p $PARALLEL -u mvwtdmv -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
        }elsif ($PARALLEL==0){
            shell("find $HERESTRECLUSTED/$i/ -name '*.acc' -print | sort > $HERESTRECLUSTED/$i/AccList");
            shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -M $HERESTRECLUSTED/$i -R $HERESTRECLUSTED/$i -S $HERESTRECLUSTED/$i/AccList -T 1 -m 1 -t 5000 5000 10000 -p $PARALLEL -u mvwtdmv -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
            shell("echo $HERESTRECLUSTED/$i/*.acc | xargs rm -rf");
            shell("rm -f $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'}");
        }
        $i++;
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step32  Build Regression Class Tree for Clustered HMM
#-----------------------------------------------------------------------

if ($EXEC[32]) {
    print_step(" Embedded Training for Clustered HMM ");
    print_time("Started at");
    makedir("$HERESTRECLUSTED");
    
    mkreregtreehed('cmp');
    shell("$BIN/HHEd -A -B -C $CONFIG -C $CONFIGCLUST -D -V -T 1 -H $HERESTRECLUSTED/5/$CLSTMMF{'cmp'} -p -i $REREGTREEHED{'cmp'} $RETIEDLIST{'cmp'}");

    mkreregtreehed('dur');
    shell("$BIN/HHEd -A -B -C $CONFIG -C $CONFIGDURCLUST -D -V -T 1 -H $HERESTRECLUSTED/5/$CLSTMMF{'dur'} -p -i $REREGTREEHED{'dur'} $RETIEDLIST{'dur'}");

    shell("mv dectree_* $HERESTRECLUSTED/");

    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step33  Transformation Estimation for Clustered HMM
#-----------------------------------------------------------------------

if ($EXEC[33]) {
    print_step(" Transformation Estimation for Clustered HMM ");
    print_time("Started at");
    makedir("$HERESTRECLUSTED");
    
    print("Transform Estimation 1 for Clustered HMM \n");
    makedir("$HERESTRECLUSTED/cmllr");
    $INPUTTRANSFORM = "";
    $i = $SITERTRANS;
    while ($i <= $EITERTRANS) {
        $in = $i-1;
        if($i>1){
            $INPUTTRANSFORM = "-J $HERESTRECLUSTED/cmllr cmp.cmllr$in -Y $HERESTRECLUSTED/cmllr dur.cmllr$in -a -b ";
        }
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLRDEC -D -V -H $HERESTRECLUSTED/5/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/5/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTRECLUSTED -Y $HERESTRECLUSTED $INPUTTRANSFORM -K $HERESTRECLUSTED/cmllr cmp.cmllr$i -Z $HERESTRECLUSTED/cmllr dur.cmllr$i -M $HERESTRECLUSTED/cmllr -R $HERESTRECLUSTED/cmllr -S $TRAIN -T 1 -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u ada -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
            shell("echo $HERESTRECLUSTED/cmllr/*.cmllr$in | xargs rm -rf");    
        }elsif ($PARALLEL>0){ # subset = speaker
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLRDEC -D -V -H $HERESTRECLUSTED/5/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/5/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTRECLUSTED -Y $HERESTRECLUSTED $INPUTTRANSFORM -K $HERESTRECLUSTED/cmllr cmp.cmllr$i -Z $HERESTRECLUSTED/cmllr dur.cmllr$i -M $HERESTRECLUSTED/cmllr -R $HERESTRECLUSTED/cmllr -S $TRAIN.speaker$SPEAKER{$PARALLEL} -T 1 -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u ada -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
        }
        $i++;
    }
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step34  SAT 1 for Clustered HMM
#-----------------------------------------------------------------------

if ($EXEC[34]) {
    print_step(" SAT 1 for Clustered HMM ");
    print_time("Started at");
    makedir("$HERESTRECLUSTED");
    
    $i = 5+$SITER;
    while ($i <= 5+$EITER) {
        print("\n\nIteration ", $i, " of Speaker Adaptive Training for Clustered HMM\n");
        makedir("$HERESTRECLUSTED/$i");
        $ii=$i-1;
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLRDEC -D -V -E $HERESTRECLUSTED/cmllr cmp.cmllr3 -W $HERESTRECLUSTED/cmllr dur.cmllr3 -H $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTRECLUSTED -Y $HERESTRECLUSTED -J $HERESTRECLUSTED/cmllr cmp.cmllr3 -Y $HERESTRECLUSTED/cmllr dur.cmllr3 -K $HERESTRECLUSTED/$i -Z $HERESTRECLUSTED/$i -M $HERESTRECLUSTED/$i -R $HERESTRECLUSTED/$i -S $TRAIN -T 1 -a -b -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u mvwtdmv -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
            shell("rm -f $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'}");
        }elsif ($PARALLEL>0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLRDEC -D -V -E $HERESTRECLUSTED/cmllr cmp.cmllr3 -W $HERESTRECLUSTED/cmllr dur.cmllr3 -H $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTRECLUSTED -Y $HERESTRECLUSTED -J $HERESTRECLUSTED/cmllr cmp.cmllr3 -Y $HERESTRECLUSTED/cmllr dur.cmllr3 -K $HERESTRECLUSTED/$i -Z $HERESTRECLUSTED/$i -M $HERESTRECLUSTED/$i -R $HERESTRECLUSTED/$i -S $TRAIN.$PARALLEL -T 1 -a -b -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -p $PARALLEL -u mvwtdmv -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
        }elsif ($PARALLEL==0){
            shell("find $HERESTRECLUSTED/$i/ -name '*.acc' -print | sort > $HERESTRECLUSTED/$i/AccList");
            shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -M $HERESTRECLUSTED/$i -R $HERESTRECLUSTED/$i -S $HERESTRECLUSTED/$i/AccList -T 1 -m 1 -t 5000 5000 30000 -p $PARALLEL -u mvwtdmv -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
            shell("echo $HERESTRECLUSTED/$i/*.acc | xargs rm -rf");
            shell("rm -f $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'}");
        }
        $i++;
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step35  Transformation Estimation 2 for Clustered HMM
#-----------------------------------------------------------------------

if ($EXEC[35]) {
    print_step(" Transformation Estimation 2 for Clustered HMM ");
    print_time("Started at");
    makedir("$HERESTRECLUSTED");
    
    print("Transform Estimation 2 for Clustered HMM \n");
    $INPUTTRANSFORM = "";
    $i = $SITERTRANS+3;
    while ($i <= $EITERTRANS+3) {
        $in = $i-1;
        if($i>1){
            $INPUTTRANSFORM = "-J $HERESTRECLUSTED/cmllr cmp.cmllr$in -Y $HERESTRECLUSTED/cmllr dur.cmllr$in -a -b ";
        }
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLRDEC -D -V -H $HERESTRECLUSTED/10/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/10/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTRECLUSTED -Y $HERESTRECLUSTED $INPUTTRANSFORM -K $HERESTRECLUSTED/cmllr cmp.cmllr$i -Z $HERESTRECLUSTED/cmllr dur.cmllr$i -M $HERESTRECLUSTED/cmllr -R $HERESTRECLUSTED/cmllr -S $TRAIN -T 1 -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u ada -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
            shell("echo $HERESTRECLUSTED/cmllr/*.cmllr$in | xargs rm -rf");    
        }elsif ($PARALLEL>0){ # subset = speaker
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLRDEC -D -V -H $HERESTRECLUSTED/10/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/10/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTRECLUSTED -Y $HERESTRECLUSTED $INPUTTRANSFORM -K $HERESTRECLUSTED/cmllr cmp.cmllr$i -Z $HERESTRECLUSTED/cmllr dur.cmllr$i -M $HERESTRECLUSTED/cmllr -R $HERESTRECLUSTED/cmllr -S $TRAIN.speaker$SPEAKER{$PARALLEL} -T 1 -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u ada -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
        }
        $i++;
    }

    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step36  SAT 2 for Clustered HMM
#-----------------------------------------------------------------------

if ($EXEC[36]) {
    print_step(" SAT 2 for Clustered HMM ");
    print_time("Started at");
    makedir("$HERESTRECLUSTED");
    
    $i = 10+$SITER;
    while ($i <= 10+$EITER) {
        print("\n\nIteration ", $i, " of Speaker Adaptive Training for Clustered HMM\n");
        makedir("$HERESTRECLUSTED/$i");
        $ii=$i-1;
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLRDEC -D -V -E $HERESTRECLUSTED/cmllr cmp.cmllr6 -W $HERESTRECLUSTED/cmllr dur.cmllr6 -H $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTRECLUSTED -Y $HERESTRECLUSTED -J $HERESTRECLUSTED/cmllr cmp.cmllr6 -Y $HERESTRECLUSTED/cmllr dur.cmllr6 -K $HERESTRECLUSTED/$i -Z $HERESTRECLUSTED/$i -M $HERESTRECLUSTED/$i -R $HERESTRECLUSTED/$i -S $TRAIN -T 1 -a -b -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u mvwtdmv -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
            shell("rm -f $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'}");
        }elsif ($PARALLEL>0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLRDEC -D -V -E $HERESTRECLUSTED/cmllr cmp.cmllr6 -W $HERESTRECLUSTED/cmllr dur.cmllr6 -H $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -J $HERESTRECLUSTED -Y $HERESTRECLUSTED -J $HERESTRECLUSTED/cmllr cmp.cmllr6 -Y $HERESTRECLUSTED/cmllr dur.cmllr6 -K $HERESTRECLUSTED/$i -Z $HERESTRECLUSTED/$i -M $HERESTRECLUSTED/$i -R $HERESTRECLUSTED/$i -S $TRAIN.$PARALLEL -T 1 -a -b -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -p $PARALLEL -u mvwtdmv -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
        }elsif ($PARALLEL==0){
            shell("find $HERESTRECLUSTED/$i/ -name '*.acc' -print | sort > $HERESTRECLUSTED/$i/AccList");
            shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'} -N $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} -I $FULLMLF -M $HERESTRECLUSTED/$i -R $HERESTRECLUSTED/$i -S $HERESTRECLUSTED/$i/AccList -T 1 -m 1 -t 5000 5000 30000 -p $PARALLEL -u mvwtdmv -w 3 $RETIEDLIST{'cmp'} $RETIEDLIST{'dur'}");
            shell("echo $HERESTRECLUSTED/$i/*.acc | xargs rm -rf");
            shell("rm -f $HERESTRECLUSTED/$ii/$CLSTMMF{'dur'} $HERESTRECLUSTED/$ii/$CLSTMMF{'cmp'}");
        }
        $i++;
    }
    print_time("Finished at");
}


#-----------------------------------------------------------------------
# Step37 Convert HSMM-model for hts_engine
#-----------------------------------------------------------------------

if ($EXEC[37]) {
  print_step("Convert HSMM-model for hts_engine");
  print_time("Started at");
  makedir("$SPSYNTHE");
  
  mkclchs('mcep');
  shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'cmp'} -i -p $CHSHED{'mcep'} $RETIEDLIST{'cmp'}");
  shell("mv $SPSYNTHE/trees.1 $SPSYNTHE/$SPTREE{'mcep'}");
  shell("mv $SPSYNTHE/pdf.1 $SPSYNTHE/$SPPDF{'mcep'}");
  
  mkclchs('logF0');
  shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'cmp'} -i -p $CHSHED{'logF0'} $RETIEDLIST{'cmp'}");
  shell("mv $SPSYNTHE/trees.2 $SPSYNTHE/$SPTREE{'logF0'}");
  shell("mv $SPSYNTHE/pdf.2 $SPSYNTHE/$SPPDF{'logF0'}");
  
  mkclchs('bndap');
  shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'cmp'} -i -p $CHSHED{'bndap'} $RETIEDLIST{'cmp'}");
  shell("mv $SPSYNTHE/trees.5 $SPSYNTHE/$SPTREE{'bndap'}");
  shell("mv $SPSYNTHE/pdf.5 $SPSYNTHE/$SPPDF{'bndap'}");
  
  mkclchs('dur');
  shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'dur'} -i -p $CHSHED{'dur'} $RETIEDLIST{'dur'}");
  shell("mv $SPSYNTHE/trees.1 $SPSYNTHE/$SPTREE{'dur'}");
  shell("mv $SPSYNTHE/pdf.1 $SPSYNTHE/$SPPDF{'dur'}");

  shell("cp $WINDIR/*.win $SPSYNTHE/");
  shell("cp $ANALYSIS/gv/*.pdf $SPSYNTHE/");

  shell("rm -f $CHSHED{'mcep'}  $CHSHED{'logF0'}  $CHSHED{'bndap'}  $CHSHED{'dur'}");  
  print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step38 Prepare Models and Trees for HMGenS
#-----------------------------------------------------------------------

if ($EXEC[38]) {
  print_step("Prepare Models and Trees for HMGenS");
  print_time("Started at");
  makedir("$OUTHMMs");

  shell("cp $HERESTRECLUSTED/15/$CLSTMMF{'cmp'} $OUTHMMs/");
  shell("cp $HERESTRECLUSTED/15/$CLSTMMF{'dur'} $OUTHMMs/");
  shell("cp $RETIEDLIST{'cmp'} $OUTHMMs/context.cmp.list");
  shell("cp $RETIEDLIST{'dur'} $OUTHMMs/context.dur.list");
  shell("cp $FULLLIST $OUTHMMs/context.full.list");
  shell("cp $REINFFILE{'mcep'} $OUTHMMs/tree.mcep.inf");
  shell("cp $REINFFILE{'logF0'} $OUTHMMs/tree.logF0.inf");
  shell("cp $REINFFILE{'bndap'} $OUTHMMs/tree.bndap.inf");
  shell("cp $REINFFILE{'dur'} $OUTHMMs/tree.dur.inf");
  shell("cp -r $HERESTRECLUSTED/cmllr $OUTHMMs/cmllr");
  shell("cp $HERESTRECLUSTED/dectree_* $OUTHMMs/cmllr/");
  shell("cp $REALIGNSTAFILE{'cmp'} $OUTHMMs/cmllr/");
  shell("cp $REALIGNSTAFILE{'dur'} $OUTHMMs/cmllr/");

  # gv mmf
  conv_gvpdf2mmf();

  # output data/model infromation 
  modelinfo();

  print_time("Finished at");
}


#-----------------------------------------------------------------------
# Step39 Convert trained HSMM to HMM (for HVite)
#-----------------------------------------------------------------------

if ($EXEC[39]) {
  print_step("Convert trained HSMM to HMM (for HVite)");
  print_time("Started at");
  makedir("$ADDTRANSDIR");
  makedir("$ADDTRANSDIR/0");

  mkaddtranshed();
  shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'cmp'} -w $ADDTRANSDIR/0/$CLSTMMF{'cmp'} -i -p -s $ADDTRANSHED $RETIEDLIST{'cmp'}");
  shell("rm -f $ADDTRANSHED");  

  # Create vocab file for alignment 
  shell("awk '{print \$1,\$1}' $FULLLIST > $VOCAB");

  print_time("Finished at");
}


#-----------------------------------------------------------------------
# Step40  Embedded training for transition probs.
#-----------------------------------------------------------------------

if ($EXEC[40]) {
    print_step(" Embedded training for transition probs. ");
    print_time("Started at");
    makedir("$ADDTRANSDIR");

    $i = $SITER;
    while ($i <= $EITER) {
        print("\n\nIteration ", $i, " of embedded training for transition probs.\n");
        makedir("$ADDTRANSDIR/$i");
        $ii=$i-1;
        if($PARALLEL<0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLRDEC -D -V -E $HERESTRECLUSTED/cmllr cmp.cmllr6 -H $ADDTRANSDIR/$ii/$CLSTMMF{'cmp'} -I $FULLMLF -J $HERESTRECLUSTED -J $HERESTRECLUSTED/cmllr cmp.cmllr6 -K $ADDTRANSDIR/$i -M $ADDTRANSDIR/$i -S $TRAIN -T 1 -a -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -u t -w 3 $RETIEDLIST{'cmp'}");
            shell("rm -f $ADDTRANSDIR/$ii/$CLSTMMF{'cmp'}");
        }elsif ($PARALLEL>0){
            shell("$BIN/HERest -A -B -C $CONFIG -C $CONFIGCMLLRDEC -D -V -E $HERESTRECLUSTED/cmllr cmp.cmllr6 -H $ADDTRANSDIR/$ii/$CLSTMMF{'cmp'} -I $FULLMLF -J $HERESTRECLUSTED -J $HERESTRECLUSTED/cmllr cmp.cmllr6 -K $ADDTRANSDIR/$i -M $ADDTRANSDIR/$i -S $TRAIN.$PARALLEL -T 1 -a -h \"*/%%%*.cmp\" -m 1 -t 5000 5000 30000 -p $PARALLEL -u t -w 3 $RETIEDLIST{'cmp'}");
        }elsif ($PARALLEL==0){
            shell("find $ADDTRANSDIR/$i/ -name '*.acc' -print | sort > $ADDTRANSDIR/$i/AccList");
            shell("$BIN/HERest -A -B -C $CONFIG -D -V -H $ADDTRANSDIR/$ii/$CLSTMMF{'cmp'} -I $FULLMLF -M $ADDTRANSDIR/$i -S $ADDTRANSDIR/$i/AccList -T 1 -m 1 -t 5000 5000 10000 -p $PARALLEL -u t -w 3 $RETIEDLIST{'cmp'}");
            shell("echo $ADDTRANSDIR/$i/*.acc | xargs rm -rf");
            shell("rm -f $ADDTRANSDIR/$ii/$CLSTMMF{'cmp'}");
        }
        $i++;
    }
    
    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step41 Viterbi alignment of training data 
#-----------------------------------------------------------------------

if ($EXEC[41]) {
    print_step("Viterbi alignment of training data");
    print_time("Started at");

    $TESTDIR = "$ADDTRANSDIR/5/";

    if($PARALLEL<0){
       shell("touch null.hed");
       shell("$BIN/HVite -A -C $CONFIG -D -V -H $TESTDIR/$CLSTMMF{'cmp'} -i $ALIGNMLF.context -I $FULLMLF -J $HERESTRECLUSTED/cmllr cmp.cmllr6 -H $HERESTRECLUSTED/dectree_cmp.base -H $HERESTRECLUSTED/dectree_cmp.tree -S $TRAIN -T 1 -a -h \"*/%%%*.cmp\" -k -l '*' -o MS -y lab $VOCAB $RETIEDLIST{'cmp'}");
       shell("$BIN/HLEd -l '*' -i $ALIGNMLF null.hed $ALIGNMLF.context");
       shell("rm -rf $ADDTRANSDIR/$ALIGNMLF.* null.hed $VOCAB");
   }elsif ($PARALLEL>0){
       shell("$BIN/HVite -A -C $CONFIG -D -V -H $TESTDIR/$CLSTMMF{'cmp'} -i $ALIGNMLF.context.$PARALLEL -I $FULLMLF -J $HERESTRECLUSTED/cmllr cmp.cmllr6 -H $HERESTRECLUSTED/dectree_cmp.base -H $HERESTRECLUSTED/dectree_cmp.tree -S $TRAIN.$PARALLEL -T 1 -a -h \"*/%%%*.cmp\" -k -l '*' -o MS -y lab $VOCAB $RETIEDLIST{'cmp'}");
   }elsif ($PARALLEL==0){
       shell("touch null.hed");
       shell("$BIN/HLEd -l '*' -i $ALIGNMLF null.hed $ALIGNMLF.context.*");
       shell("rm -rf $ADDTRANSDIR/$ALIGNMLF.* null.hed $VOCAB");
   }

    print_time("Finished at");
}

#-----------------------------------------------------------------------
# Step42 Prepare Models and Trees for HMGenS
#-----------------------------------------------------------------------

if ($EXEC[42]) {
  print_step("Prepare Models and Trees for HMGenS");
  print_time("Started at");
  makedir("$OUTHMMs");
  
  shell("cp $ADDTRANSDIR/5/$CLSTMMF{'cmp'} $OUTHMMs/$CLSTMMF{'cmp'}.hmm");
  if(-e $ALIGNMLF){
      shell("cp $ALIGNMLF $SEGMENTMLF");
  }

  print_time("Finished at");
}


#-----------------------------------------------------------------------
# Step43 Prepare hts_engine models for training speakers 
#-----------------------------------------------------------------------

if ($EXEC[43]) {
  print_step("Prepare hts_engine models for training speakers");
  print_time("Started at");
  makedir("$SPSYNTHE/training-speakers");

   if($PARALLEL<0){
        $numsp = keys(%SPEAKER);
        $i = 1;
        while ($i <= $numsp){ 
          print "\n========== $SPEAKER{$i} ==========\n"; 
          makedir("$SPSYNTHE/training-speakers/$SPEAKER{$i}");
          mkclchsax('mcep', $SPEAKER{$i});
          shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'cmp'} -H $HERESTRECLUSTED/dectree_cmp.base -H $HERESTRECLUSTED/dectree_cmp.tree -i -p $CHSHED{'mcep'}.$SPEAKER{$i} $RETIEDLIST{'cmp'}");
          shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$i}/trees.1 $SPSYNTHE/training-speakers/$SPEAKER{$i}/$SPTREE{'mcep'}");
          shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$i}/pdf.1 $SPSYNTHE/training-speakers/$SPEAKER{$i}/$SPPDF{'mcep'}");

          mkclchsax('logF0', $SPEAKER{$i});
          shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'cmp'} -H $HERESTRECLUSTED/dectree_cmp.base -H $HERESTRECLUSTED/dectree_cmp.tree -i -p $CHSHED{'logF0'}.$SPEAKER{$i} $RETIEDLIST{'cmp'}");
          shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$i}/trees.2 $SPSYNTHE/training-speakers/$SPEAKER{$i}/$SPTREE{'logF0'}");
          shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$i}/pdf.2 $SPSYNTHE/training-speakers/$SPEAKER{$i}/$SPPDF{'logF0'}");

          mkclchsax('bndap', $SPEAKER{$i});
          shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'cmp'} -H $HERESTRECLUSTED/dectree_cmp.base -H $HERESTRECLUSTED/dectree_cmp.tree -i -p $CHSHED{'bndap'}.$SPEAKER{$i} $RETIEDLIST{'cmp'}");
          shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$i}/trees.5 $SPSYNTHE/training-speakers/$SPEAKER{$i}/$SPTREE{'bndap'}");
          shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$i}/pdf.5 $SPSYNTHE/training-speakers/$SPEAKER{$i}/$SPPDF{'bndap'}");

          mkclchsax('dur', $SPEAKER{$i});
          shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'dur'} -H $HERESTRECLUSTED/dectree_dur.base -H $HERESTRECLUSTED/dectree_dur.tree -i -p $CHSHED{'dur'}.$SPEAKER{$i} $RETIEDLIST{'dur'}");
          shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$i}/trees.1 $SPSYNTHE/training-speakers/$SPEAKER{$i}/$SPTREE{'dur'}");
          shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$i}/pdf.1 $SPSYNTHE/training-speakers/$SPEAKER{$i}/$SPPDF{'dur'}");

          shell("cp $WINDIR/*.win $SPSYNTHE/training-speakers/$SPEAKER{$i}");
          shell("cp $ANALYSIS/gv/training-speakers/$SPEAKER{$i}/*.pdf $SPSYNTHE/training-speakers/$SPEAKER{$i}");

          shell("rm -f $CHSHED{'mcep'}.$SPEAKER{$i}  $CHSHED{'logF0'}.$SPEAKER{$i}  $CHSHED{'bndap'}.$SPEAKER{$i} $CHSHED{'dur'}.$SPEAKER{$i}");
        
          $i++;
        }
   }elsif ($PARALLEL>0){ # subset = speaker

        print "\n========== $SPEAKER{$PARALLEL} ==========\n";
        makedir("$SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}");
        mkclchsax('mcep', $SPEAKER{$PARALLEL});
        shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'cmp'} -H $HERESTRECLUSTED/dectree_cmp.base -H $HERESTRECLUSTED/dectree_cmp.tree -i -p $CHSHED{'mcep'}.$SPEAKER{$PARALLEL} $RETIEDLIST{'cmp'}");
        shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/trees.1 $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/$SPTREE{'mcep'}");
        shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/pdf.1 $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/$SPPDF{'mcep'}");

        mkclchsax('logF0', $SPEAKER{$PARALLEL});
        shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'cmp'} -H $HERESTRECLUSTED/dectree_cmp.base -H $HERESTRECLUSTED/dectree_cmp.tree -i -p $CHSHED{'logF0'}.$SPEAKER{$PARALLEL} $RETIEDLIST{'cmp'}");
        shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/trees.2 $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/$SPTREE{'logF0'}");
        shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/pdf.2 $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/$SPPDF{'logF0'}");

        mkclchsax('bndap', $SPEAKER{$PARALLEL});
        shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'cmp'} -H $HERESTRECLUSTED/dectree_cmp.base -H $HERESTRECLUSTED/dectree_cmp.tree -i -p $CHSHED{'bndap'}.$SPEAKER{$PARALLEL} $RETIEDLIST{'cmp'}");
        shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/trees.5 $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/$SPTREE{'bndap'}");
        shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/pdf.5 $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/$SPPDF{'bndap'}");

        mkclchsax('dur', $SPEAKER{$PARALLEL});
        shell("$BIN/HHEd -A -B -C $CONFIG -T 1 -D -V -H $HERESTRECLUSTED/15/$CLSTMMF{'dur'} -H $HERESTRECLUSTED/dectree_dur.base -H $HERESTRECLUSTED/dectree_dur.tree -i -p $CHSHED{'dur'}.$SPEAKER{$PARALLEL} $RETIEDLIST{'dur'}");
        shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/trees.1 $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/$SPTREE{'dur'}");
        shell("mv $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/pdf.1 $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}/$SPPDF{'dur'}");

        shell("cp $WINDIR/*.win $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}");
        shell("cp $ANALYSIS/gv/training-speakers/$SPEAKER{$PARALLEL}/*.pdf $SPSYNTHE/training-speakers/$SPEAKER{$PARALLEL}");

        shell("rm -f $CHSHED{'mcep'}.$SPEAKER{$PARALLEL}  $CHSHED{'logF0'}.$SPEAKER{$PARALLEL}  $CHSHED{'bndap'}.$SPEAKER{$PARALLEL} $CHSHED{'dur'}.$SPEAKER{$PARALLEL}");
  }

  print_time("Finished at");
}



#-----------------------------------------------------------------------
# Step44 Clean Data
#-----------------------------------------------------------------------

if ($EXEC[44]) {
  print_step("Clean Unnecessary Data");
  print_time("Started at");

  shell("rm -rf $HMMDIR $ANALYSIS $LISTDIR $OUTDIR/config ");

  print_time("Finished at");
}

#=======================================================================
# Subroutines
#=======================================================================

sub makedir($) {
  my($targetdir) = @_;
  
  if (! -d $targetdir) {
    rmtree($targetdir);
    mkpath($targetdir, 1, 0755);
  }
}

sub shell($) {
  my($command) = @_;
  my($exit,$start,$end);
  
  print "\n$command\n\n";
  
  $start = time;
  $exit = system($command);
  $end = time;
  
  $h = int(($end-$start)/3600);
  $m = int((($end-$start)-$h*3600)/60);
  $s = $end-$start-$h*3600-$m*60;
  
  print "--------------------------------------------------\n";
  printf(" Realtime %3d:%02d:%02d\n",$h,$m,$s);
  print "--------------------------------------------------\n";
  
  die "Error in this command : $command\n" if($exit/256 != 0);
}

sub print_step($) {
  print "\n";
  print "************************************************************************\n\n";
  print "@_\n\n";
  print "************************************************************************\n\n";
}

sub print_time($) {
  print "\n";
  print "--------------------------------------------------\n";
  print " @_ ".`date`;
  print "--------------------------------------------------\n";
  print "\n";
}

sub print_ls(@) {
  print "\n";
  print "==================================================\n";
  print " ".`ls -l @_`;
  print "==================================================\n";
  print "\n";
}

# Calc bark of the nyquist limit based on conversion equation shown in 
# H. Traunmuller (1990) "Analytical expressions for the tonotopic
#                        sensory scale" J. Acoust. Soc. Am. 88: 97-100.

sub calcnumband($) {
    my($fs) = @_;
    my($nq,$fbark,$numbands);
    $nq = $fs/2;
    $fbark = 26.81 * $nq / (1960 + $nq ) - 0.53;
    
    if($fbark<2){
        $fbark += 0.15*(2-$fbark);
    }
    
    if($fbark>20.1){
        $fbark +=  0.22*($fbark-20.1);
    }
    
    $numbands = int ($fbark + 0.5); 
    print $numbads;
    return $numbands;
}

# sub routine for generating config files for HTS
sub make_config {

   my($vsize,$specthreshold,$bapthreshold);
   $vsize = $CEPSTRALORDER + 1;


   # general.conf
   open(CONFIG,">$CONFIG") || die "Cannot open $!";
   
   # Input/Output variables
   print CONFIG "NATURALREADORDER      = T\n";    # Input byte order (little endian)
   print CONFIG "NATURALWRITEORDER     = T\n";    # Output byte order (little endian)
   
   # Flooring for HMM 
   # Variance flooring ON 
   # HERest, HMap, and HHEd use
   print CONFIG "APPLYVFLOOR           = T\n";    
   # Scaling factor for variance floor of each stream (variance floor = global variance * 0.01)
   # HCompV uses 
   print CONFIG "VFLOORSCALESTR        = \"Vector 5 0.01 0.01 0.01 0.01 0.01\"\n" ;  

   # Flooring for Duration model 
   # HERest
   print CONFIG "APPLYDURVARFLOOR      = T\n";
   # Scaling factor for variance floor of duration model (variance floor = global variance * 1%) 
   # HERest
   print CONFIG "DURVARFLOORPERCENTILE = 1.000000\n";

   # Maximu duration setting for semi-Markov: maximum state duration = mean + 10 * standard deviation
   print CONFIG "MAXSTDDEVCOEF         = 10\n";

   close(CONFIG);


   # general-unfloor.conf
   open(CONFIG,">$UNFCONFIG") || die "Cannot open $!";
   
   # Input/Output variables
   print CONFIG "NATURALREADORDER      = T\n";    # Input byte order (little endian)
   print CONFIG "NATURALWRITEORDER     = T\n";    # Output byte order (little endian)
   
   # Flooring for HMM 
   # Variance flooring ON 
   # HERest, HMap, and HHEd use
   print CONFIG "APPLYVFLOOR           = F\n";    

   # Flooring for Duration model 
   # HERest
   print CONFIG "APPLYDURVARFLOOR      = F\n";
   # Scaling factor for variance floor of duration model (variance floor = global variance * 0%) 
   # HERest
   print CONFIG "DURVARFLOORPERCENTILE = 0.000000\n";

   # Maximu duration setting for semi-Markov: maximum state duration = mean + 10 * standard deviation
   print CONFIG "MAXSTDDEVCOEF         = 10\n";

   close(CONFIG);

   # removefloor.conf
   open(CONFIG,">$REMFLOORCONFIG") || die "Cannot open $!";
   # Removing floor macro  
   print CONFIG "HMODEL:SAVEVARFLOOR = FALSE\n";
   close(CONFIG);



   # clust.conf
   open(CONFIG,">$CONFIGCLUST") || die "Cannot open $!";
   # Mimimum state-occupancy in each leaf nodes
   # HHEd
   print CONFIG "MINLEAFOCC        =  $MINOCCCMP\n";

   # Apply leaf node merging
   if($TREETHRESH == 2){
       print CONFIG "TREEMERGE = T\n";
   }

   # Shrink regression class trees converted from decision trees based on state-occupancy probs. 
   # The number of parameters for each block of linear transforms to be estimated is $vsize*($vsize+1)
   # The samples/state occupancy more than this free parameters should be used for estimation
   # Experientially 15 times of the free parameters seems to be good for SAT
   $specthreshold = sprintf( "%.1f", 15*$vsize*($vsize+1));
   $bapthreshold = sprintf( "%.1f", 15*$NUMBANDAP*($NUMBANDAP + 1));
   print CONFIG "SHRINKOCCTHRESH   = \"Vector 5  $specthreshold 2000.0 2000.0 2000.0 $bapthreshold\" \n";
   close(CONFIG);



   # clust-dur.conf
   open(CONFIG,">$CONFIGDURCLUST") || die "Cannot open $!";
   # Mimimum state-duration occupancy in each leaf nodes
   # HHEd
   print CONFIG "MINLEAFOCC        = $MINOCCDUR\n";

   # Apply leaf node merging
   if($TREETHRESH == 2){
       print CONFIG "TREEMERGE = T\n";
   }

   # Shrink regression class trees converted from decision trees based on state-occupancy probs.
   print CONFIG "SHRINKOCCTHRESH   = \"Vector 5  2000.0 2000.0 2000.0 2000.0 2000.0\" \n";
   close(CONFIG);

   close(CONFIG);



   # cmllr-regressionclass.conf
   open(CONFIG,">$CONFIGCMLLR") || die "Cannot open $!";

   # Change trace level for matrix loading 
   print CONFIG "HADAPT:TRACE           = 61 \n";
   print CONFIG "HMODEL:TRACE           = 512\n";

   # Set regression class format to 'BASE'
   print CONFIG "HADAPT:ADAPTKIND       = BASE  \n";
   print CONFIG "HADAPT:DURADAPTKIND    = BASE  \n";
   print CONFIG "HADAPT:BASECLASS       = regclass.cmpbase  \n";
   print CONFIG "HADAPt:DURBASECLASS    = regclass.durbase  \n";

   # Set linear transform algorithms to 'CMLLLR' for feature-space SAT algorithm
   print CONFIG "HADAPT:TRANSKIND       = CMLLR \n";
   print CONFIG "HADAPT:DURTRANSKIND    = CMLLR \n";
   print CONFIG "HADAPT:USEBIAS         = TRUE \n";
   print CONFIG "HADAPT:DURUSEBIAS      = TRUE  \n";

   # Set thresholds for state occupancy used for each regression class (cmp)
   # The number of parameters for each block of linear transforms to be estimated is $vsize*($vsize+1)
   # The samples/state occupancy more than this free parameters should be used for estimation
   # Experientially 15 times of the free parameters seems to be good for SAT
   $specthreshold = sprintf( "%.1f", 15*$vsize*($vsize+1));
   $bapthreshold = sprintf( "%.1f", 15*$NUMBANDAP*($NUMBANDAP + 1));
   print CONFIG "HADAPT:SPLITTHRESH     = \"Vector 5 $specthreshold 2000.0 2000.0 2000.0 $bapthreshold\" \n";

   # Set thresholds for state occupancy used for each regression class (duration)
   print CONFIG "HADAPT:DURSPLITTHRESH  = \"Vector $NUMSTATE";
   for ($i=1;$i<=$NUMSTATE;$i++) {
       print CONFIG " 2000.0";
   }
   print CONFIG "\"\n";

   # Tri-block linear transform corresponding to static, delta, and delta-delta
   print CONFIG "HADAPT:BLOCKSIZE       = \"IntVec 3 $vsize $vsize $vsize IntVec 1 1 IntVec 1 1 IntVec 1 1 IntVec 3 $NUMBANDAP $NUMBANDAP $NUMBANDAP\" \n";

   # Variable for LSP features
   if(($ANALYSISMETHOD == 3) || ($ANALYSISMETHOD == 4)){
       print CONFIG "HADAPT:BANDWIDTH       = \"IntVec 3 2 2 2 IntVec 1 1 IntVec 1 1 IntVec 1 1 IntVec 3 $NUMBANDAP $NUMBANDAP $NUMBANDAP\" \n";
   }else{
       print CONFIG "HADAPT:BANDWIDTH       = \"IntVec 3 $CEPSTRALORDER $CEPSTRALORDER $CEPSTRALORDER IntVec 1 1 IntVec 1 1 IntVec 1 1 IntVec 3 $NUMBANDAP $NUMBANDAP $NUMBANDAP\" \n";
   }

   close(CONFIG);




   # cmllr-decisiontree.conf
   open(CONFIG,">$CONFIGCMLLRDEC") || die "Cannot open $!";

   # Change trace level for matrix loading 
   print CONFIG "HADAPT:TRACE           = 61 \n";
   print CONFIG "HMODEL:TRACE           = 512\n";

   # Set regression class format to 'TREE'
   print CONFIG "HADAPT:ADAPTKIND       = TREE  \n";
   print CONFIG "HADAPT:DURADAPTKIND    = TREE  \n";
   print CONFIG "HADAPT:REGTREE         = dectree_cmp.tree\n";
   print CONFIG "HADAPt:DURREGTREE      = dectree_dur.tree\n";

   # Set linear transform algorithms to 'CMLLLR' for feature-space SAT algorithm
   # HTK does not support model-space SAT algorithm. so please do not change this to MLLR!
   print CONFIG "HADAPT:TRANSKIND       = CMLLR \n";
   print CONFIG "HADAPT:DURTRANSKIND    = CMLLR \n";
   print CONFIG "HADAPT:USEBIAS         = TRUE \n";
   print CONFIG "HADAPT:DURUSEBIAS      = TRUE  \n";

   # Set thresholds for state occupancy used for each regression class (cmp)
   # The number of parameters for each block of linear transforms to be estimated is $vsize*($vsize+1)
   # The samples/state occupancy more than this free parameters should be used for estimation
   # Experientially 15 times of the free parameters seems to be good for SAT
   $specthreshold = sprintf( "%.1f", 15*$vsize*($vsize+1));
   $bapthreshold = sprintf( "%.1f", 15*$NUMBANDAP*($NUMBANDAP + 1));
   print CONFIG "HADAPT:SPLITTHRESH     = \"Vector 5 $specthreshold 2000.0 2000.0 2000.0 $bapthreshold\" \n";

   # Set thresholds for state occupancy used for each regression class (duration)
   print CONFIG "HADAPT:DURSPLITTHRESH  = \"Vector $NUMSTATE";
   for ($i=1;$i<=$NUMSTATE;$i++) {
       print CONFIG " 2000.0";
   }
   print CONFIG "\"\n";

   # Tri-block linear transform corresponding to static, delta, and delta-delta
   print CONFIG "HADAPT:BLOCKSIZE       = \"IntVec 3 $vsize $vsize $vsize IntVec 1 1 IntVec 1 1 IntVec 1 1 IntVec 3 $NUMBANDAP $NUMBANDAP $NUMBANDAP\" \n";

   # Variable for LSP features
   if(($ANALYSISMETHOD == 3) || ($ANALYSISMETHOD == 4)){
       print CONFIG "HADAPT:BANDWIDTH       = \"IntVec 3 2 2 2 IntVec 1 1 IntVec 1 1 IntVec 1 1 IntVec 3 $NUMBANDAP $NUMBANDAP $NUMBANDAP\" \n";
   }else{
       print CONFIG "HADAPT:BANDWIDTH       = \"IntVec 3 $CEPSTRALORDER $CEPSTRALORDER $CEPSTRALORDER IntVec 1 1 IntVec 1 1 IntVec 1 1 IntVec 3 $NUMBANDAP $NUMBANDAP $NUMBANDAP\" \n";
   }

   close(CONFIG);
   
}

# sub routine for generating proto-type model (Copy from HTS-2.1)
sub make_proto {
   my($i, $j, $k, $s, $vsize, $vsizestream1,$vsizestream5);

   # calculate total number of vectors including delta and delta-delta
   $vsize = ($CEPSTRALORDER + 1 + 1 + $NUMBANDAP)*3;  
   $vsizestream1 = ($CEPSTRALORDER + 1)*3;
   $vsizestream5 = $NUMBANDAP * 3;

   # output prototype definition
   # open proto type definition file 
   open(PROTO,">$PROTO") || die "Cannot open $!";

   # output header 
   # output vector size & feature type
   print PROTO "~o <VecSize> $vsize <USER> <DIAGC>";
   
   # output information about multi-space probability distribution (MSD)
   print PROTO "<MSDInfo> 5 0 1 1 1 0 ";
   
   # output information about stream
   print PROTO "<StreamInfo> 5 $vsizestream1 1 1 1 $vsizestream5";
   print PROTO "\n";

   # output HMMs
   print  PROTO "<BeginHMM>\n";
   printf PROTO "  <NumStates> %d\n", $NUMSTATE+2;

   # output HMM states 
   for ($i=2;$i<=$NUMSTATE+1;$i++) {

      # output state information
      print PROTO "  <State> $i\n";

      # output stream weight
      print PROTO "  <SWeights> 5 1.0 1.0 1.0 1.0 0.0 \n";

      # output stream 1 information
      print  PROTO "  <Stream> 1\n";
      # output mean vector 
      printf PROTO "    <Mean> %d\n", $vsizestream1;
      for ($k=1;$k<=$vsizestream1;$k++) {
          print PROTO "      " if ($k%10==1); 
          print PROTO "0.0 ";
          print PROTO "\n" if ($k%10==0);
      }
      print PROTO "\n" if ($k%10!=1);

      # output covariance matrix (diag)
      printf PROTO "    <Variance> %d\n", $vsizestream1;
      for ($k=1;$k<=$vsizestream1;$k++) {
          print PROTO "      " if ($k%10==1); 
          print PROTO "1.0 ";
          print PROTO "\n" if ($k%10==0);
      }
      print PROTO "\n" if ($k%10!=1);


      # MSD stream 1 
      print  PROTO "  <Stream> 2\n";
      # output MSD
      print  PROTO "  <NumMixes> 2\n";
      # output 1st space (non 0-dimensional space)
      # output space weights
      print  PROTO "  <Mixture> 1 0.5000\n";
     
      # output mean vector 
      printf PROTO "    <Mean> %d\n",1;
      for ($k=1;$k<=1;$k++) {
          print PROTO "      " if ($k%10==1); 
          print PROTO "0.0 ";
          print PROTO "\n" if ($k%10==0);
      }
      print PROTO "\n" if ($k%10!=1);

      # output covariance matrix (diag)
      printf PROTO "    <Variance> %d\n", 1;
      for ($k=1;$k<=1;$k++) {
          print PROTO "      " if ($k%10==1); 
          print PROTO "1.0 ";
          print PROTO "\n" if ($k%10==0);
      }
      print PROTO "\n" if ($k%10!=1);

      # output 2nd space (0-dimensional space)
      print PROTO "  <Mixture> 2 0.5000\n";
      print PROTO "    <Mean> 0\n";
      print PROTO "    <Variance> 0\n";
 

      # MSD stream 2 
      print  PROTO "  <Stream> 3\n";
      # output MSD
      print  PROTO "  <NumMixes> 2\n";
      # output 1st space (non 0-dimensional space)
      # output space weights
      print  PROTO "  <Mixture> 1 0.5000\n";
     
      # output mean vector 
      printf PROTO "    <Mean> %d\n",1;
      for ($k=1;$k<=1;$k++) {
          print PROTO "      " if ($k%10==1); 
          print PROTO "0.0 ";
          print PROTO "\n" if ($k%10==0);
      }
      print PROTO "\n" if ($k%10!=1);

      # output covariance matrix (diag)
      printf PROTO "    <Variance> %d\n", 1;
      for ($k=1;$k<=1;$k++) {
          print PROTO "      " if ($k%10==1); 
          print PROTO "1.0 ";
          print PROTO "\n" if ($k%10==0);
      }
      print PROTO "\n" if ($k%10!=1);

      # output 2nd space (0-dimensional space)
      print PROTO "  <Mixture> 2 0.5000\n";
      print PROTO "    <Mean> 0\n";
      print PROTO "    <Variance> 0\n";
 

      # MSD stream 3
      print  PROTO "  <Stream> 4\n";
      # output MSD
      print  PROTO "  <NumMixes> 2\n";
      # output 1st space (non 0-dimensional space)
      # output space weights
      print  PROTO "  <Mixture> 1 0.5000\n";
     
      # output mean vector 
      printf PROTO "    <Mean> %d\n",1;
      for ($k=1;$k<=1;$k++) {
          print PROTO "      " if ($k%10==1); 
          print PROTO "0.0 ";
          print PROTO "\n" if ($k%10==0);
      }
      print PROTO "\n" if ($k%10!=1);

      # output covariance matrix (diag)
      printf PROTO "    <Variance> %d\n", 1;
      for ($k=1;$k<=1;$k++) {
          print PROTO "      " if ($k%10==1); 
          print PROTO "1.0 ";
          print PROTO "\n" if ($k%10==0);
      }
      print PROTO "\n" if ($k%10!=1);

      # output 2nd space (0-dimensional space)
      print PROTO "  <Mixture> 2 0.5000\n";
      print PROTO "    <Mean> 0\n";
      print PROTO "    <Variance> 0\n";
 

      # output stream 5 information 
      print  PROTO "  <Stream> 5\n";
      # output mean vector 
      printf PROTO "    <Mean> %d\n", $vsizestream5;
      for ($k=1;$k<=$vsizestream5;$k++) {
          print PROTO "      " if ($k%10==1); 
          print PROTO "0.0 ";
          print PROTO "\n" if ($k%10==0);
      }
      print PROTO "\n" if ($k%10!=1);

      # output covariance matrix (diag)
      printf PROTO "    <Variance> %d\n", $vsizestream5;
      for ($k=1;$k<=$vsizestream5;$k++) {
          print PROTO "      " if ($k%10==1); 
          print PROTO "1.0 ";
          print PROTO "\n" if ($k%10==0);
      }
      print PROTO "\n" if ($k%10!=1);

  }

   # output state transition matrix
   printf PROTO "  <TransP> %d\n", $NUMSTATE+2;
   print  PROTO "    ";
   for ($j=1;$j<=$NUMSTATE+2;$j++) {
      print PROTO "1.000e+0 " if ($j==2);
      print PROTO "0.000e+0 " if ($j!=2);
   }
   print PROTO "\n";
   print PROTO "    ";
   for ($i=2;$i<=$NUMSTATE+1;$i++) {
      for ($j=1;$j<=$NUMSTATE+2;$j++) {
         print PROTO "6.000e-1 " if ($i==$j);
         print PROTO "4.000e-1 " if ($i==$j-1);
         print PROTO "0.000e+0 " if ($i!=$j && $i!=$j-1);
      }
      print PROTO "\n";
      print PROTO "    ";
   }
   for ($j=1;$j<=$NUMSTATE+2;$j++) {
      print PROTO "0.000e+0 ";
   }
   print PROTO "\n";

   # output footer
   print PROTO "<EndHMM>\n";

   close(PROTO);
}      

sub mkcathed($) {
  my($kind) = @_;
  
  if($kind eq 'cmp'){
      $VFLOORS = "$HCOMPVDIR/vFloors";
  }else{
      $VFLOORS = "$HCOMPVDIR/dur/vFloors";
  }
  
  open(EDFILE, ">$CATMONOHED{$kind}") || die "Cannot open $CATMONOHED{$kind}\n";
  print EDFILE "FV \"$VFLOORS\"\n";
  close(EDFILE);
}

sub mkvfloordur(){
    my($i);
    
    open(EDFILE, ">$VFLOORDUR") || die "Cannot open $VFLOORDUR\n";
    for ($i=1;$i<=$NUMSTATE;$i++) {
        print EDFILE "~v varFloor$i\n";
        print EDFILE "<Variance> 1\n";
        print EDFILE " 1.0\n";
    }
    close(EDFILE);
}

sub mkm2splithed($) {
  my($kind,$numsplt) = @_;
  my($endstate);
  $endstate = $NUMSTATE + 1;

  if($numsplt > 0){
      open(EDFILE, ">$MONO2FULLHED{$kind}.$numsplt") || die "Cannot open $MONO2FULLHED{$kind}.$numsplt\n";
      if($kind eq 'cmp'){
          print EDFILE "TI \"SWeight_${numsplt}\" { *.state[2-$endstate].weights }\n";
      }
      print EDFILE "MM \"trP_${numsplt}_\"    { *.transP }\n";
      print EDFILE "CL \"$FULLLIST.$numsplt\"\n";
      close(EDFILE);
  }else{
      open(EDFILE, ">$MONO2FULLHED{$kind}") || die "Cannot open $MONO2FULLHED{$kind}\n";
      if($kind eq 'cmp'){
          print EDFILE "TI \"SWeight\" { *.state[2-$endstate].weights }\n";
      }
      print EDFILE "MM \"trP\"    { *.transP }\n";
      print EDFILE "CL \"$FULLLIST\"\n";
      close(EDFILE);
  }
}

sub compstatehed($) {
    my($state,$numsplt) = @_;  
    my($i);  

    if($numsplt > 0){
        open(EDFILE, ">$COMPRESSHED.$state.$numsplt") || die "Cannot open $COMPRESSHED.$state.$numsplt\n";
        for ($i = 2;$i < 2+$NUMSTATE ;$i++){
            if($i != $state){
                print EDFILE "TI \"State${i}_${numsplt}_\"  { *.state[${i}] }\n";
            }
        }
        close(EDFILE);
    }else{
        open(EDFILE, ">$COMPRESSHED.$state") || die "Cannot open $COMPRESSHED.$state\n";
        for ($i = 2;$i < 2+$NUMSTATE ;$i++){
            if($i != $state){
                print EDFILE "TI \"State${i}_\"  { *.state[${i}] }\n";
            }
        }
        close(EDFILE);
    }
}

sub compstreamsplithed($) {
    my($state,$numsplt) = @_;  
    my($endstate);
    $endstate = $NUMSTATE + 1;

    if($numsplt > 0) {
        open(EDFILE, ">$COMPRESSSTREAMHED.mcep.$state.$numsplt") || die "Cannot open $COMPRESSSTREAMHED.mcep.$state.$numsplt\n";
        print EDFILE "TI \"Stream2-4_${numsplt}_\"  { *.state[2-$endstate].stream[2-4] }\n";
        print EDFILE "TI \"Stream5_${numsplt}_\"    { *.state[2-$endstate].stream[5] }\n";
        close(EDFILE);
        
        open(EDFILE, ">$COMPRESSSTREAMHED.logf0.$state.$numsplt") || die "Cannot open $COMPRESSSTREAMHED.logf0.$state.$numsplt\n";
        print EDFILE "TI \"Stream1_${numsplt}_\"  { *.state[2-$endstate].stream[1] }\n";
        print EDFILE "TI \"Stream5_${numsplt}_\"  { *.state[2-$endstate].stream[5] }\n";
        close(EDFILE);
        
        open(EDFILE, ">$COMPRESSSTREAMHED.bndap.$state.$numsplt") || die "Cannot open $COMPRESSSTREAMHED.bndap.$state.$numsplt\n";
        print EDFILE "TI \"Stream1_${numsplt}_\"    { *.state[2-$endstate].stream[1] }\n";
        print EDFILE "TI \"Stream2-4_${numsplt}_\"  { *.state[2-$endstate].stream[2-4] }\n";
        close(EDFILE);
    }else{
        open(EDFILE, ">$COMPRESSSTREAMHED.mcep.$state") || die "Cannot open $COMPRESSSTREAMHED.mcep.$state\n";
        print EDFILE "TI \"Stream2-4_\"  { *.state[2-$endstate].stream[2-4] }\n";
        print EDFILE "TI \"Stream5_\"    { *.state[2-$endstate].stream[5] }\n";
        close(EDFILE);
        
        open(EDFILE, ">$COMPRESSSTREAMHED.logf0.$state") || die "Cannot open $COMPRESSSTREAMHED.logf0.$state\n";
        print EDFILE "TI \"Stream1_\"  { *.state[2-$endstate].stream[1] }\n";
        print EDFILE "TI \"Stream5_\"  { *.state[2-$endstate].stream[5] }\n";
        close(EDFILE);
        
        open(EDFILE, ">$COMPRESSSTREAMHED.bndap.$state") || die "Cannot open $COMPRESSSTREAMHED.bndap.$state\n";
        print EDFILE "TI \"Stream1_\"    { *.state[2-$endstate].stream[1] }\n";
        print EDFILE "TI \"Stream2-4_\"  { *.state[2-$endstate].stream[2-4] }\n";
        close(EDFILE);
    }
}

sub compstateallhed($) {
    my($state) = @_; 
    my($i);  
    my($endstate);
    $endstate = $NUMSTATE + 1;


    open(EDFILE, ">$COMPRESSHED.$state.mcep") || die "Cannot open $COMPRESSHED.$state.mcep\n";
    for ($i = 2;$i < 2+$NUMSTATE ;$i++){
        if($i != $state){
            print EDFILE "TI \"State${i}_\"  { *.state[${i}] }\n";
        }
    }
    print EDFILE "TI \"Stream2-4\"  { *.state[2-$endstate].stream[2-4] }\n";
    print EDFILE "TI \"Stream5\"    { *.state[2-$endstate].stream[5] }\n";    
    close(EDFILE);
    
    open(EDFILE, ">$COMPRESSHED.$state.logf0") || die "Cannot open $COMPRESSHED.$state.logf0\n";
    for ($i = 2;$i < 2+$NUMSTATE ;$i++){
        if($i != $state){
            print EDFILE "TI \"State${i}_\"  { *.state[${i}] }\n";
        }
    }
    print EDFILE "TI \"Stream1\"  { *.state[2-$endstate].stream[1] }\n";
    print EDFILE "TI \"Stream5\"  { *.state[2-$endstate].stream[5] }\n";
    close(EDFILE);
    
    open(EDFILE, ">$COMPRESSHED.$state.bndap") || die "Cannot open $COMPRESSHED.$state.bndap\n";
    for ($i = 2;$i < 2+$NUMSTATE ;$i++){
        if($i != $state){
            print EDFILE "TI \"State${i}_\"  { *.state[${i}] }\n";
        }
    }
    print EDFILE "TI \"Stream1\"    { *.state[2-$endstate].stream[1] }\n";
    print EDFILE "TI \"Stream2-4\"  { *.state[2-$endstate].stream[2-4] }\n";
    close(EDFILE);
}

sub mkclsthed($) {
  my($kind,$sti) = @_;
  my($state,$rothr,$tbthr,$stats,$lines,$i,$j,@set,$second);
  
  if($kind eq 'mcep'){
    $stats = 'cmp';
    $state = $NUMSTATE;    
  }elsif($kind eq 'logF0'){
    $stats = 'cmp';
    $state = $NUMSTATE;
  }elsif($kind eq 'bndap'){
    $stats = 'cmp';
    $state = $NUMSTATE;
  }elsif($kind eq 'dur'){
    $stats = 'dur';
    $state = 1;    
  }
  
  open(F, "<$QFILE");
  @lines = <F>;
  close(F);
  
  if($sti > 1){
      open(EDFILE,">$CLSTHED{$kind}.${sti}");
      print EDFILE "RO 0 \"$STAFILE{$stats}\"\n";
      print EDFILE "\nTR 1\n\n";
      print EDFILE @lines;
      print EDFILE "\nTR 1\n\n";
      if($TREETYPE == 1){ # single tree
          if($TREETHRESH == 1){ # MDL
              $OCCTHRESHOLD = 0;
          }
          print EDFILE "TB $OCCTHRESHOLD ${kind}_s${sti}_ {*.state[${sti}].stream[$STREAM{$kind}]}\n";
      }else{ # phonetic tree
          if($TREETHRESH == 1){ # MDL
              $OCCTHRESHOLD = 0;
          }
          open(HMMLIST, "<$MONOLIST");
          while (<HMMLIST>) {
              chomp;
              print EDFILE "TB $OCCTHRESHOLD ${kind}_s${sti}_${_}_ {(*-$_+*).state[${sti}].stream[$STREAM{$kind}]}\n";
          }
          close(HMMLIST);      
      }
      print EDFILE "\nTR 1\n\n";
      print EDFILE "ST \"$INFFILE{$kind}.${sti}\"\n";      
      close(EDFILE);
  }else{
      open(EDFILE,">$CLSTHED{$kind}");
      print EDFILE "RO 0 \"$STAFILE{$stats}\"\n";
      print EDFILE "\nTR 1\n\n";
      print EDFILE @lines;
      print EDFILE "\nTR 1\n\n";
      for ($i = 2;$i < 2+$state;$i++){
          if($TREETYPE == 1){ # single tree
              if($TREETHRESH == 1){ # MDL
                  $OCCTHRESHOLD = 0;
              }
              print EDFILE "TB $OCCTHRESHOLD ${kind}_s${i}_ {*.state[${i}].stream[$STREAM{$kind}]}\n";
          }else{ # phonetic tree
              if($TREETHRESH == 1){ # MDL
                  $OCCTHRESHOLD = 0;
              }
              open(HMMLIST, "<$MONOLIST");
              while (<HMMLIST>) {
                  chomp;
                  print EDFILE "TB $OCCTHRESHOLD ${kind}_s${i}_${_}_ {(*-$_+*).state[${i}].stream[$STREAM{$kind}]}\n";
              }
              close(HMMLIST);      
          }
      }
      print EDFILE "\nTR 1\n\n";
      print EDFILE "ST \"$INFFILE{$kind}\"\n";      
      close(EDFILE);
  }
}

sub conv_stat() {
  my(@l);
  
  open(CMP, "<$STAFILE{'cmp'}") || die "Cannot open $STAFILE{'cmp'}\n";
  open(DUR, ">$STAFILE{'dur'}") || die "Cannot open $STAFILE{'dur'}\n";
  while(<CMP>){
    @l = split(' ');
    printf(DUR "%4d %14s %4d %4d\n",$l[0],$l[1],$l[2],$l[2]) if ($l[2] > 0);
  }
  close(CMP);
  close(DUR);
}

sub joinmodeled($){

    my($i) = @_;
    my($endstate);
    $endstate = $NUMSTATE + 1;

    open(EDFILE, ">$JOINHED.$i") || die "Cannot open $JOINHED.$i\n";
    print EDFILE "UT {*.state[${i}]}\n" if ($i != 2);
    print EDFILE "JM $HHEDCLUSTRINGSPEC/$i/$CLSTMMF{'cmp'} {*.state[${i}].stream[1]}\n" if ($i !=2);
    print EDFILE "JM $HHEDCLUSTRINGLOGF0/$i/$CLSTMMF{'cmp'} {*.state[${i}].stream[2-4]}\n";
    print EDFILE "JM $HHEDCLUSTRINGBND/$i/$CLSTMMF{'cmp'} {*.state[${i}].stream[5]}\n";
    print EDFILE "TI \"SWeights\" { *.state[2-$endstate].weights }\n" if ($i == $endstate);
    close(EDFILE);

}

sub rejoinmodeled($){

    my($i) = @_;
    my($endstate);
    $endstate = $NUMSTATE + 1;


    open(EDFILE, ">$REJOINHED.$i") || die "Cannot open $REJOINHED.$i\n";
    print EDFILE "UT {*.state[${i}]}\n" if($i != 2);
    print EDFILE "JM $HHEDRECLUSTRINGSPEC/$i/$CLSTMMF{'cmp'} {*.state[${i}].stream[1]}\n" if($i !=2);
    print EDFILE "JM $HHEDRECLUSTRINGLOGF0/$i/$CLSTMMF{'cmp'} {*.state[${i}].stream[2-4]}\n";
    print EDFILE "JM $HHEDRECLUSTRINGBND/$i/$CLSTMMF{'cmp'} {*.state[${i}].stream[5]}\n";
    print EDFILE "TI \"SWeightall\" { *.state[2-$endstate].weights }\n" if ($i == $endstate);
    close(EDFILE);

}

sub mktieded($) {
    my($kind) = @_;
    
    if($kind eq 'cmp'){
      $VFLOORS = "$HCOMPVDIR/vFloors";
    }else{
      $VFLOORS = "$HCOMPVDIR/dur/vFloors";
    }

    open(EDFILE, ">$TIEDHED{$kind}") || die "Cannot open $TIEDHED{$kind}\n";
    print EDFILE "CO \"$TIEDLIST{$kind}\"\n";
    print EDFILE "FV \"$VFLOORS\"\n";

    close(EDFILE);
}

sub cattreehed() {
  
  open(EDFILE,">$CATTREEHED.mcep") || die "Cannot open $CATTREEHED.mcep\n";
  print EDFILE "\nTR 2\n\n";
  for ($i = 2;$i < 2+$NUMSTATE ;$i++){
    print EDFILE "LT \"$INFFILE{'mcep'}.${i}\"\n";
  }
  print EDFILE "ST \"$INFFILE{'mcep'}\"\n";
  close(EDFILE);

  open(EDFILE,">$CATTREEHED.logF0") || die "Cannot open $CATTREEHED.logF0\n";
  for ($i = 2;$i < 2+$NUMSTATE ;$i++){
    print EDFILE "LT \"$INFFILE{'logF0'}.${i}\"\n";
  }
  print EDFILE "ST \"$INFFILE{'logF0'}\"\n";

  open(EDFILE,">$CATTREEHED.bndap") || die "Cannot open $CATTREEHED.bndap\n";
  for ($i = 2;$i < 2+$NUMSTATE ;$i++){
    print EDFILE "LT \"$INFFILE{'bndap'}.${i}\"\n";
  }
  print EDFILE "ST \"$INFFILE{'bndap'}\"\n";
  close(EDFILE);
}

sub mkuntieed($) {

  my($kind,$numsplt) = @_;
  my($i);  
  my($endstate);
  $endstate = $NUMSTATE + 1;


  if($numsplt > 0){
      open(EDFILE, ">$UNTIEED{$kind}.$numsplt") || die "Cannot open $UNTIEED{$kind}.$numsplt\n";
      if($kind eq 'cmp'){
          print EDFILE "\nTR 2\n\n";
          for ($i = 2;$i < 2+$NUMSTATE ;$i++){
              print EDFILE "LT \"$INFFILE{'mcep'}.${i}\"\n";
              print EDFILE "LT \"$INFFILE{'logF0'}.${i}\"\n";
              print EDFILE "LT \"$INFFILE{'bndap'}.${i}\"\n";
          }
      }elsif($kind eq 'dur'){
          print EDFILE "LT \"$INFFILE{'dur'}\"\n";
      }
      print EDFILE "AU \"$FULLLIST.$numsplt\"\n";
      if($kind eq 'cmp'){
        print EDFILE "UT {*.state[2-$endstate].stream[1-5]}\n";
        print EDFILE "UT {*.state[2-$endstate] }\n";
        print EDFILE "TI \"SWeight_${numsplt}\" { *.state[2-$endstate].weights }\n";
      }elsif($kind eq 'dur'){
        print EDFILE "UT {*.state[2]}\n";
      }
      print EDFILE "UT {*.transP}\n";
      print EDFILE "TI TrP_${numsplt} {*.transP}";
      close(EDFILE);
  }else{
      open(EDFILE, ">$UNTIEED{$kind}") || die "Cannot open $UNTIEED{$kind}\n";
      if($kind eq 'cmp'){
          print EDFILE "\nTR 2\n\n";
          for ($i = 2;$i < 2+$NUMSTATE ;$i++){
              print EDFILE "LT \"$INFFILE{'mcep'}.${i}\"\n";
              print EDFILE "LT \"$INFFILE{'logF0'}.${i}\"\n";
              print EDFILE "LT \"$INFFILE{'bndap'}.${i}\"\n";
          }
      }elsif($kind eq 'dur'){
          print EDFILE "LT \"$INFFILE{'dur'}\"\n";
      }
      print EDFILE "AU \"$FULLLIST\"\n";
      if($kind eq 'cmp'){
        print EDFILE "UT {*.state[2-$endstate].stream[1-5]}\n";
        print EDFILE "UT {*.state[2-$endstate] }\n";
        print EDFILE "TI \"SWeight\" { *.state[2-$endstate].weights }\n";
      }elsif($kind eq 'dur'){
        print EDFILE "UT {*.state[2]}\n";
      }
      print EDFILE "UT {*.transP}\n";
      print EDFILE "TI TrP {*.transP}";
      close(EDFILE);
  }
}

sub mkreclsthed($) {
  my($kind,$sti) = @_;
  my($state,$rothr,$tbthr,$stats,$lines,$i,$j,@set,$second);
  
  if($kind eq 'mcep'){
    $stats = 'cmp';
    $state = $NUMSTATE;    
  }elsif($kind eq 'logF0'){
    $stats = 'cmp';
    $state = $NUMSTATE;
  }elsif($kind eq 'bndap'){
    $stats = 'cmp';
    $state = $NUMSTATE;
  }elsif($kind eq 'dur'){
    $stats = 'dur';
    $state = 1;    
  }
  
  open(F, "<$QFILE");
  @lines = <F>;
  close(F);
  
  if($sti > 1){
      open(EDFILE,">$RECLSTHED{$kind}.${sti}");
      print EDFILE "RO 0 \"$REALIGNSTAFILE{$stats}\"\n";
      print EDFILE "\nTR 1\n\n";
      print EDFILE @lines;
      print EDFILE "\nTR 1\n\n";
      if($TREETYPE == 1){ # single tree
          if($TREETHRESH == 1){ # MDL
              $OCCTHRESHOLD = 0;
          }
          print EDFILE "TB $OCCTHRESHOLD ${kind}_s${sti}_ {*.state[${sti}].stream[$STREAM{$kind}]}\n";
      }else{ # phonetic tree
          if($TREETHRESH == 1){ # MDL
              $OCCTHRESHOLD = 0;
          }
          open(HMMLIST, "<$MONOLIST");
          while (<HMMLIST>) {
              chomp;
              print EDFILE "TB $OCCTHRESHOLD ${kind}_s${sti}_${_}_ {(*-$_+*).state[${sti}].stream[$STREAM{$kind}]}\n";
          }
          close(HMMLIST);
      }
      print EDFILE "\nTR 1\n\n";
      print EDFILE "ST \"$REINFFILE{$kind}.${sti}\"\n";      
      close(EDFILE);
  }else{
      open(EDFILE,">$RECLSTHED{$kind}");
      print EDFILE "RO 0 \"$REALIGNSTAFILE{$stats}\"\n";
      print EDFILE "\nTR 1\n\n";
      print EDFILE @lines;
      print EDFILE "\nTR 1\n\n";
      for ($i = 2;$i < 2+$state;$i++){
          if($TREETYPE == 1){ # single tree
              if($TREETHRESH == 1){ # MDL
                  $OCCTHRESHOLD = 0;
              }
              print EDFILE "TB $OCCTHRESHOLD ${kind}_s${i}_ {*.state[${i}].stream[$STREAM{$kind}]}\n";
          }else{ # phonetic trees
              if($TREETHRESH == 1){ # MDL
                  $OCCTHRESHOLD = 0;
              }
              open(HMMLIST, "<$MONOLIST");
              while (<HMMLIST>) {
                  chomp;
                  print EDFILE "TB $OCCTHRESHOLD ${kind}_s${i}_${_}_ {(*-$_+*).state[${i}].stream[$STREAM{$kind}]}\n";
              }
              close(HMMLIST);
          }
      }
      print EDFILE "\nTR 1\n\n";
      print EDFILE "ST \"$REINFFILE{$kind}\"\n";      
      close(EDFILE);
  }
}

sub conv_stat_realign() {
  my(@l);
  
  open(CMP, "<$REALIGNSTAFILE{'cmp'}") || die "Cannot open $REALIGNSTAFILE{'cmp'}\n";
  open(DUR, ">$REALIGNSTAFILE{'dur'}") || die "Cannot open $REALIGNSTAFILE{'dur'}\n";
  while(<CMP>){
    @l = split(' ');
    printf(DUR "%4d %14s %4d %4d\n",$l[0],$l[1],$l[2],$l[2]) if ($l[2] > 0);
  }
  close(CMP);
  close(DUR);
}

sub mkretieded($) {
    my($kind) = @_;
    
    if($kind eq 'cmp'){
      $VFLOORS = "$HCOMPVDIR/vFloors";
    }else{
      $VFLOORS = "$HCOMPVDIR/dur/vFloors";
    }

    open(EDFILE, ">$RETIEDHED{$kind}") || die "Cannot open $RETIEDHED{$kind}\n";
    print EDFILE "FV \"$VFLOORS\"\n";
    print EDFILE "CO \"$RETIEDLIST{$kind}\"\n";
    close(EDFILE);
}

sub recattreehed() {
  
  open(EDFILE,">$RECATTREEHED.mcep") || die "Cannot open $RECATTREEHED.mcep\n";
  print EDFILE "\nTR 2\n\n";
  for ($i = 2;$i < 2+$NUMSTATE ;$i++){
    print EDFILE "LT \"$REINFFILE{'mcep'}.${i}\"\n";
  }
  print EDFILE "ST \"$REINFFILE{'mcep'}\"\n";
  close(EDFILE);

  open(EDFILE,">$RECATTREEHED.logF0") || die "Cannot open $RECATTREEHED.logF0\n";
  for ($i = 2;$i < 2+$NUMSTATE ;$i++){
    print EDFILE "LT \"$REINFFILE{'logF0'}.${i}\"\n";
  }
  print EDFILE "ST \"$REINFFILE{'logF0'}\"\n";

  open(EDFILE,">$RECATTREEHED.bndap") || die "Cannot open $RECATTREEHED.bndap\n";
  for ($i = 2;$i < 2+$NUMSTATE ;$i++){
    print EDFILE "LT \"$REINFFILE{'bndap'}.${i}\"\n";
  }
  print EDFILE "ST \"$REINFFILE{'bndap'}\"\n";
  close(EDFILE);
}

sub mkclchs($) {
  my($kind) = @_;

  open(EDFILE,">$CHSHED{$kind}");
  print EDFILE "\nTR 2\n\n"; 
  print EDFILE "LT \"$REINFFILE{$kind}\"\n";
  print EDFILE "CT \"$SPSYNTHE\"\n";
  print EDFILE "CM \"$SPSYNTHE\"\n";
  close(EDFILE);
}

sub mkclchsax($) {
  my($kind,$speaker) = @_;

  open(EDFILE,">$CHSHED{$kind}.$speaker");
  print EDFILE "\nTR 2\n\n";
  if($kind eq 'mcep'){
      print EDFILE "\nAX $HERESTRECLUSTED/cmllr/$speaker.cmp.cmllr6\n\n";
  }elsif($kind eq 'logF0'){
      print EDFILE "\nAX $HERESTRECLUSTED/cmllr/$speaker.cmp.cmllr6\n\n";
  }elsif($kind eq 'bndap'){
      print EDFILE "\nAX $HERESTRECLUSTED/cmllr/$speaker.cmp.cmllr6\n\n";
  }elsif($kind eq 'dur'){
      print EDFILE "\nAX $HERESTRECLUSTED/cmllr/$speaker.dur.cmllr6\n\n";
  }
  print EDFILE "LT \"$REINFFILE{$kind}\"\n";
  print EDFILE "CT \"$SPSYNTHE/training-speakers/$speaker\"\n";
  print EDFILE "CM \"$SPSYNTHE/training-speakers/$speaker\"\n";
  close(EDFILE);
}

# sub routine for gv_{mgc,lf0}.pdf -> gv.mmf
sub conv_gvpdf2mmf {
   my($vsize, $vsizestream1, $data, $PI, @pdf); 
   $PI = 3.14159265358979;

   # cepstral analysis + c0 + log F0 + 5 bndap measures 
   $vsize = $CEPSTRALORDER + 1 + 1 + $NUMBANDAP; 
   $vsizestream1 = $CEPSTRALORDER + 1;
   
   open(OUT,">$GVMMF") || die "cannot open file: $GVMMF";
 
   # output header
   printf OUT "~o\n";
   printf OUT "<STREAMINFO> 3 $vsizestream1 1 $NUMBANDAP\n";
   printf OUT "<VECSIZE> $vsize <NULLD><USER><DIAGC>\n";
   printf OUT "~h \"gv\"\n";
   printf OUT "<BEGINHMM>\n";
   printf OUT "<NUMSTATES> 3\n";
   printf OUT "<STATE> 2\n";
 
   open(IN,"$ANALYSIS/gv/gv-mcep.pdf") || die "cannot open file: $ANALYSIS/gv/gv-mcep.pdf";
   @STAT=stat(IN);
   read(IN,$data,$STAT[7]);
   close(IN);

   $n = $STAT[7]/4;
   @pdf = unpack("d$n",$data);

   # output stream index
   printf OUT "<Stream> 1\n";
      
   # output mean
   printf OUT "<Mean> $vsizestream1\n";
   for ($i=0; $i<$vsizestream1; $i++) {
       $mean = shift(@pdf);
       printf OUT "%e ", $mean;
   }
   
   # output variance
   printf OUT "\n<Variance> $vsizestream1\n";
   $gConst = $vsizestream1*log(2*$PI); 
   for ($i=0; $i<$vsizestream1; $i++) {
       $var = shift(@pdf);
       printf OUT "%e ",$var;
       $gConst += log($var);
   }
   printf OUT "\n<GConst> %e\n", $gConst;


   open(IN,"$ANALYSIS/gv/gv-lf0.pdf") || die "cannot open file: $ANALYSIS/gv/gv-lf0.pdf";
   @STAT=stat(IN);
   read(IN,$data,$STAT[7]);
   close(IN);

   $n = $STAT[7]/4;
   @pdf = unpack("d$n",$data);

   # output stream index
   printf OUT "<Stream> 2\n";
      
   # output mean
   printf OUT "<Mean> 1\n";
   for ($i=0; $i<1; $i++) {
       $mean = shift(@pdf);
       printf OUT "%e ", $mean;
   }
   
   # output variance
   printf OUT "\n<Variance> 1\n";
   $gConst = 1*log(2*$PI); 
   for ($i=0; $i<1; $i++) {
       $var = shift(@pdf);
       printf OUT "%e ",$var;
       $gConst += log($var);
   }
   printf OUT "\n<GConst> %e\n", $gConst;

   open(IN,"$ANALYSIS/gv/gv-bndap.pdf") || die "cannot open file: $ANALYSIS/gv/gv-bndap.pdf";
   @STAT=stat(IN);
   read(IN,$data,$STAT[7]);
   close(IN);

   $n = $STAT[7]/4;
   @pdf = unpack("d$n",$data);

   # output stream index
   printf OUT "<Stream> 3\n";
      
   # output mean
   printf OUT "<Mean> $NUMBANDAP\n";
   for ($i=0; $i<$NUMBANDAP; $i++) {
       $mean = shift(@pdf);
       printf OUT "%e ", $mean;
   }
   
   # output variance
   printf OUT "\n<Variance> $NUMBANDAP\n";
   $gConst = $NUMBANDAP*log(2*$PI); 
   for ($i=0; $i<$NUMBANDAP; $i++) {
       $var = shift(@pdf);
       printf OUT "%e ",$var;
       $gConst += log($var);
   }
   printf OUT "\n<GConst> %e\n", $gConst;
 
   # output footer
   print OUT "<TRANSP> 3\n";
   print OUT "0 1 0\n";
   print OUT "0 0 1\n";
   print OUT "0 0 0\n";
   print OUT "<ENDHMM>\n";
   
   close(OUT);
}

sub  mkreregtreehed($){
    my($kind) = @_;
    my($i);  

    if($kind eq 'cmp'){    
        open(EDFILE, ">$REREGTREEHED{'cmp'}") || die "Cannot open $REREGTREEHED{'cmp'}\n";
        print EDFILE "LS \"$REALIGNSTAFILE{'cmp'}\"\n";
        for ($i = 2;$i < 2+$NUMSTATE ;$i++){
            print EDFILE "LT \"$REINFFILE{'mcep'}.${i}\"\n";
            print EDFILE "LT \"$REINFFILE{'logF0'}.${i}\"\n";
            print EDFILE "LT \"$REINFFILE{'bndap'}.${i}\"\n";
        }
        print EDFILE "DR \"dectree_cmp\"\n ";
        close(EDFILE);
    }else{
        open(EDFILE, ">$REREGTREEHED{'dur'}") || die "Cannot open $REREGTREEHED{'dur'}\n";
        print EDFILE "LS \"$REALIGNSTAFILE{'dur'}\"\n";
        print EDFILE "LT \"$REINFFILE{'dur'}\"\n";
        print EDFILE "DR \"dectree_dur\"\n ";
        close(EDFILE);
    }    
}

sub generate_base(){

    my($vsize, $vsizestream1,$i,$index,$numclass); 
    $vsize = ($CEPSTRALORDER + 1 + 1 + $NUMBANDAP)*3;  
    $vsizestream1 = ($CEPSTRALORDER + 1)*3;
    $vsizestream5 = $NUMBANDAP*3;
    $numclass = $NUMSTATE * 2 + $NUMSTATE * 3 * 2;  # MSD stream requires two class: 3 MSD streams + 2 normal streams 
    
    open(OUT,">$OUTBASE") || die "cannot open file: $OUTBASE";
    printf OUT "~b \"regclass.cmpbase\" \n";
    printf OUT "<MMFIDMASK> \* \n"; 
    printf OUT "<PARAMETERS> MIXBASE \n";
    printf OUT "<STREAMINFO> 5 $vsizestream1 1 1 1 $vsizestream5 \n";

    printf OUT "<NUMCLASSES> $numclass \n"; 
    # Spectral stream
    for ($index=1, $i = 2 ; $i <= $NUMSTATE+1 ; $i++,$index++){
        printf OUT "<CLASS> $index  {\*.state[${i}].stream[1].mix[1-$NUMMIXTURE]} \n";
    }

    # MSD voiced stream: static
    for ($i = 2 ; $i <= $NUMSTATE+1 ; $i++,$index++){
        printf OUT "<CLASS> $index  {\*.state[${i}].stream[2].mix[1]} \n";
    }
    # MSD unvoiced stream: static
    for ($i = 2 ; $i <= $NUMSTATE+1 ; $i++,$index++){
        printf OUT "<CLASS> $index {\*.state[${i}].stream[2].mix[2]} \n";
    }

    # MSD voiced stream: delta
    for ($i = 2 ; $i <= $NUMSTATE+1 ; $i++,$index++){
        printf OUT "<CLASS> $index  {\*.state[${i}].stream[3].mix[1]} \n";
    }
    # MSD unvoiced stream: delta
    for ($i = 2 ; $i <= $NUMSTATE+1 ; $i++,$index++){
        printf OUT "<CLASS> $index {\*.state[${i}].stream[3].mix[2]} \n";
    }

    # MSD voiced stream: delta-delta
    for ($i = 2 ; $i <= $NUMSTATE+1 ; $i++,$index++){
        printf OUT "<CLASS> $index  {\*.state[${i}].stream[4].mix[1]} \n";
    }
    # MSD unvoiced stream: delta-delta
    for ($i = 2 ; $i <= $NUMSTATE+1 ; $i++,$index++){
        printf OUT "<CLASS> $index {\*.state[${i}].stream[4].mix[2]} \n";
    }

    #Bndap stream
    for ($i = 2 ; $i <= $NUMSTATE+1 ; $i++,$index++){
        printf OUT "<CLASS> $index {\*.state[${i}].stream[5].mix[1-$NUMMIXTURE]} \n";
    }    
    close(OUT);

    open(OUT,">$DURBASE") || die "cannot open file: $DURBASE";
    printf OUT "~b \"regclass.durbase\" \n";
    printf OUT "<MMFIDMASK> \* \n";
    printf OUT "<PARAMETERS> MIXBASE \n";
    printf OUT "<STREAMINFO>  $NUMSTATE ";
    for ($i = 1 ; $i <= $NUMSTATE ; $i++){
        printf OUT " 1 "
    }
    printf OUT "\n"; 
    printf OUT "<NUMCLASSES> $NUMSTATE  \n";
    for ($i = 1 ; $i <= $NUMSTATE ; $i++){
        printf OUT "<CLASS> $i {\*.state[2].stream[${i}].mix[1-$NUMMIXTURE]} \n";
    }
    
    close(OUT);
}

sub modelinfo(){

    my($day, $vendor, $model, $cpu, $cache);
    my($total, $free, $swaptotal, $swapfree);
    my($lines,$buffer);
    my($sec, $min, $hour, $day, $mon, $year);

    open(INFO,">$MODELINFO") || die "cannot open file: $MODELINFO";
    print INFO "HTS models trained by CSTR/EMIME programs\n"; 
    print INFO "\n";

    # general
    ($sec, $min, $hour, $day, $mon, $year) = localtime(time);
    print INFO "Day                       : $day/$mon/$year\n";
    print INFO "Time                      : $hour:$min\n";
    &get_cpuinfo( $vendor, $model, $cpu, $cache );
    print INFO "CPU Model                 : $model\n";
    print INFO "CPU Clock                 : $cpu\n";
    &get_raminfo( $total, $free, $swaptotal, $swapfree );
    print INFO "Memory total              : $total\n";
    print INFO "Swap total                : $swaptotal\n";

    # input
    print INFO "Inputs\n";
    print INFO "Wavforms                  : $WAV\n";
    print INFO "Context labels            : $LABEL\n";
    print INFO "Question files            : $QFILE\n";
    print INFO "\n";

    # given data
    print INFO "User-specified info\n";
    print INFO "Name of data              : $SP \n";
    print INFO "Name of phoneset          : $Phoneset \n";
    print INFO "\n";

    # data condition
    print INFO "Data details\n";
    $lines = 0;
    open(FILE, "$WAV") or die "Can't open `$WAV': $!";
    while ($buffer = <FILE>) {
        $lines += ($buffer =~ m/\.wav/i);
    }
    close FILE;
    print INFO "Number of waveforms       : $lines\n";
    $numsp = keys(%SPEAKER);
    print INFO "Number of speakers        : $numsp \n";
    $lines = 0;
    open(FILE, "$QFILE") or die "Can't open `$QFILE': $!";
    while ($buffer = <FILE>) {
        $lines += ($buffer =~ /^QS /);
    }
    close FILE;
    print INFO "Number of given questions : $lines\n";
    print INFO "\n";

    # analysis condition
    print INFO "Analysis Condition\n";
    print INFO "F0 extraction             : IFAS \n" if ($F0METHOD == 1);
    print INFO "F0 extraction             : TEMPO\n" if ($F0METHOD == 2);
    print INFO "F0 extraction             : ESPS \n" if ($F0METHOD == 3);
    print INFO "F0 extraction             : Voting of IFAS, TEMPO & ESPS\n" if ($F0METHOD == 4);
    print INFO "Spectral Analysis         : Mel-cepstrum\n" if($ANALYSISMETHOD == 1);
    print INFO "Spectral Analysis         : Mel-gemeralized cepstrum\n" if($ANALYSISMETHOD == 2);
    print INFO "Spectral Analysis         : Mel-LSP\n" if($ANALYSISMETHOD == 3);
    print INFO "Spectral Analysis         : MGC-LSP\n" if($ANALYSISMETHOD == 4);
    print INFO "Analysis Order            : $CEPSTRALORDER (static dimension-1)\n";
    print INFO "Frame-shift               : $FRAMESHIFT (ms)\n";
    print INFO "\n";

    # HMM condition
    print INFO "HMM Condition\n";
    print INFO "Number of states          : $NUMSTATE \n";
    print INFO "Decision Tree             : Single trees\n" if($TREETYPE == 1);
    print INFO "Decision Tree             : Phonetic trees\n" if($TREETYPE == 2);
    print INFO "Criteria of Decision Tree : MDL\n" if($TREETHRESH ==1);
    print INFO "Criteria of Decision Tree : State occupancy + leaf merge\n" if($TREETHRESH ==2);


    # Obtain number of leaf nodes built
    $lines = 0;
    open(FILE, "$OUTHMMs/tree.mcep.inf") or die "Can't open `$OUTHMMs/tree.mcep.inf': $!";
    while ($buffer = <FILE>) {
        if ($buffer =~ / 0 /) {    # A tree starts.
            $lines += 2;
        } elsif ($buffer =~ / -[0-9]* /) {
            $lines++;
        }
    }
    close FILE;
    print INFO "Number of leaf nodes      : $lines (Mcep)\n";
    $lines = 0;
    open(FILE, "$OUTHMMs/tree.logF0.inf") or die "Can't open `$OUTHMMs/tree.logF0.inf': $!";
    while ($buffer = <FILE>) {
        if ($buffer =~ / 0 /) {    # A tree starts.
            $lines += 2;
        } elsif ($buffer =~ / -[0-9]* /) {
            $lines++;
        }
    }
    close FILE;
    print INFO "Number of leaf nodes      : $lines (logF0)\n";
    $lines = 0;
    open(FILE, "$OUTHMMs/tree.bndap.inf") or die "Can't open `$OUTHMMs/tree.bndap.inf': $!";
    while ($buffer = <FILE>) {
        if ($buffer =~ / 0 /) {    # A tree starts.
            $lines += 2;
        } elsif ($buffer =~ / -[0-9]* /) {
            $lines++;
        }
    }
    close FILE;
    print INFO "Number of leaf nodes      : $lines (Bndap)\n";
    $lines = 0;
    open(FILE, "$OUTHMMs/tree.dur.inf") or die "Can't open `$OUTHMMs/tree.dur.inf': $!";
    while ($buffer = <FILE>) {
        if ($buffer =~ / 0 /) {    # A tree starts.
            $lines += 2;
        } elsif ($buffer =~ / -[0-9]* /) {
            $lines++;
        }
    }
    close FILE;
    print INFO "Number of leaf nodes      : $lines (Duration)\n";

    # Obtain number of questions used 
    $lines = 0;
    open(FILE, "$OUTHMMs/tree.mcep.inf") or die "Can't open `$OUTHMMs/tree.mcep.inf': $!";
    while ($buffer = <FILE>) {
        $lines += ($buffer =~ /^QS /);
    }
    close FILE;
    print INFO "Number of used questions  : $lines (Mcep)\n";
    $lines = 0;
    open(FILE, "$OUTHMMs/tree.logF0.inf") or die "Can't open `$OUTHMMs/tree.logF0.inf': $!";
    while ($buffer = <FILE>) {
        $lines += ($buffer =~ /^QS /);
    }
    close FILE;
    print INFO "Number of used questions  : $lines (logF0)\n";
    $lines = 0;
    open(FILE, "$OUTHMMs/tree.bndap.inf") or die "Can't open `$OUTHMMs/tree.bndap.inf': $!";
    while ($buffer = <FILE>) {
        $lines += ($buffer =~ /^QS /);
    }
    close FILE;
    print INFO "Number of used questions  : $lines (Bndap)\n";
    $lines = 0;
    open(FILE, "$OUTHMMs/tree.dur.inf") or die "Can't open `$OUTHMMs/tree.dur.inf': $!";
    while ($buffer = <FILE>) {
        $lines += ($buffer =~ /^QS /);
    }
    close FILE;
    print INFO "Number of used questions  : $lines (Duration)\n";
    print INFO "Mixture                   : 1\n"; # mixutre is not supported yet
    print INFO "\n";

}


sub get_cpuinfo
{
    local( $vendor, $model, $cpu, $cache ) = @_;
    local( $info, $rec, @recs );
    $info = "/proc/cpuinfo";
    if( -e $info ){
        &read_recs_ref( $info, *recs );
        foreach $rec ( @recs ){
            $_[0] = $1 if $rec =~ /vendor_id\s*:\s*(.+)/i;
            $_[1] = $1 if $rec =~ /model\s*name\s*:\s*(.+)/i;
            $_[2] = $1." MHz" if $rec =~ /cpu\s*MHz\s*:\s*(.+)/i;
            $_[3] = $1 if $rec =~ /cache\s*size\s*:\s*(.+)/i;
        }
    }
    else{
        $ERR_MSG = "Unknown ...";
        return 0;
    }
    return 1;
}

sub get_raminfo
{
    local( $total, $free, $swaptotal, $swapfree ) = @_;
    local( $info, $rec, @recs );
    $info = "/proc/meminfo";
    if( -e $info ){
        &read_recs_ref( $info, *recs );
        foreach $rec ( @recs ){
            $_[0] = &s3c($1)." Kbyte" if $rec =~ /MemTotal:\s*(.+)\s*kB/i;
            $_[1] = &s3c($1)." Kbyte" if $rec =~ /MemFree:\s*(.+)\s*kB/i;
            $_[2] = &s3c($1)." Kbyte" if $rec =~ /SwapTotal:\s*(.+)\s*kB/i;
            $_[3] = &s3c($1)." Kbyte" if $rec =~ /SwapFree:\s*(.+)\s*kB/i;
        }
    }
    else{
        $ERR_MSG = "Unknown..";
        return 0;
    }
    return 1;
}

sub s3c
{
    local( $value ) = @_;
    $value =~ s/(\d{1,3})(?=(?:\d\d\d)+(?!\d))/$1,/g;
    return $value;
}

sub read_recs_ref
{
    local( $fname, *dat ) = @_;
    local( $cnt );
    
    unless( -r $fname ){
        $ERR_MSG = "File does not exit";
        return 0;
    }
    eval{
        open( FPR, "<$fname" ) || die "failed to open $fname";
        @dat = <FPR>;
        close( FPR );
    };
    if( $@ ){
        $ERR_MSG = $@;
        return 0;
    }
    
    $cnt = @dat;
    return $cnt;
}

sub mkaddtranshed() {

  my($i,$j);

  open(EDFILE, ">$ADDTRANSHED") || die "Cannot open $ADDTRANSHED\n";
  print EDFILE "\nTR 2\n\n";
  print EDFILE "UT {*.transP}\n";
  open(HMMLIST, "<$MONOLIST");
  while (<HMMLIST>) {
      chomp;
      print EDFILE "TI TrP_$_ {(*-$_+*).transP}";
  }
  close(HMMLIST);

  for ($i = 2;$i < 2+$NUMSTATE ;$i++){
      $j = $i + 1;
      print EDFILE "AT $i $i 0.9 {*.transP}\n";
      print EDFILE "AT $i $j 0.1 {*.transP}\n";
  }
  close(EDFILE);
}

On 13 May 2012, at 11:05, Kwan Lisa wrote:

> Maybe it was the diversity of my corpus resulted in the poor
> performance. My corpus consists of voices of 300 speakers and about
> 200 sentences (about 10 mins) for each speaker. This corpus is not
> labeled manually. I built a average voice model using about 3000
> sentences, then I used sentences of one speaker to perform adaptation.
> At the first place I thought the alignment accuracy was the reason why
> performance was bad. But I think you are right. Embedded training
> procedure doesn't rely on the phoneme boundary. Now I'm not sure what
> kind of method could improve the performance of the TTS system. I'm
> afraid that the number of the adaptation sentence is too small;
> however I only have 200 sentences for each speaker.
> 
> 2012/5/13 huanliangwang <huanliangwang@xxxxxxx>:
>> Hi,
>>    Our experiments show the same conclusion as you. The effect of initial
>> phone boundary to the synthesis results is very limited if you use the
>> embedded training procedure. I think the consistency between mono phone
>> sequence and  full-context phone sequence, as well as in training stage and
>> in synthesis stage,  may be more important for synthesis performance.
>> 
>> Best Regards,
>> 
>> hlwang
>> 
>> 
>> 
>> At 2012-05-13 10:05:26,"那兴宇" <nxy-yzqs@xxxxxxx> wrote:
>> 
>> My opinion:
>> HTS system use phoneme boundaries only in the initialization stage of
>> monophone models, which will affect the result of convergences in the
>> embedded training of full-context models. But in my experiments, phoneme
>> alignment does not affect that much. So I do not know what is your corpus
>> size, maybe using more training data would help.
>> --
>> Xingyu Na (那兴宇)
>> Beijing Institute of Technology
>> naxy(at)bit.edu.cn
>> asr.naxingyu(at)gmail.com
>> naxingyu at {facebook, twitter, linkedin}
>> 
>> 
>> At 2012-05-13 03:29:51,"Kwan Lisa" <lisakwan1102@xxxxxxxxx> wrote:
>>> Hi,
>>> 
>>> I'm using a corpus without manual phoneme alignment. Thus, I performed
>>> forced alignment to get the phoneme boundary information.
>>> However, the performance of the TTS system was not good. TTS system
>>> seems to be very sensitive to the accuracy of the phoneme boundary
>>> information.
>>> Is there any method that could improve the performance of TTS without
>>> manual phoneme alignment?
>>> 
>>> --
>>> Lisa Kwan
>>> lisakwan1102(at)gmail.com
>>> 
>> 
>> 
>> 
>> 
>> 
> 
> 
> 
> -- 
> Lisa Kwan
> lisakwan1102(at)gmail.com
> 
> 

The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.

Follow-Ups
[hts-users:03311] Re: How to improve performance of TTS without manual phoneme alignment, Kwan Lisa
References
[hts-users:03295] How to improve performance of TTS without manual phoneme alignment, Kwan Lisa
[hts-users:03299] Re: How to improve performance of TTS without manual phoneme alignment, 那兴宇
[hts-users:03300] Re: How to improve performance of TTS without manual phoneme alignment, huanliangwang
[hts-users:03301] Re: How to improve performance of TTS without manual phoneme alignment, Kwan Lisa