#! @PERL@
#
# sample usage: split_mmf.pl input_mmf.text output_states.text 
#                      output_trans.text output_model.text
#
# this script splits the htk ascii mmf to three separate files for state 
# definitions, transition matrices and model definitions
#

# define constants
#
$NUM_ARGS = 3;
$NUMMIXES = "NUMMIXES";
$MODEL_FLAG = "\~h";
$TRANS_FLAG = "\~t";
$STATES_FLAG = "\~s";
$STATES_STR = "\<STATE\>";
$TRANS_STR = "\<TRANSP\>";

# define local variables
#
$trans_ind = 0;
$states_ind = 0;

# check for correct number of arguments
#
($#ARGV == ($NUM_ARGS)) || 
    die "Usage: split_mmf.pl <input mmf> <output states> <output transitions> <output models>\n";

$mmf = $ARGV[0];
$states = $ARGV[1];
$trans = $ARGV[2];
$models = $ARGV[3];

# open files
# 
open (mmf_file, "$mmf") || die "Cannot open file $mmf: $!\n";
open (states_file, ">$states") || die "Cannot open file $states: $!\n";
open (trans_file, ">$trans") || die "Cannot open file $trans: $!\n";
open (models_file, ">$models") || die "Cannot open file $models: $!\n";


while (!eof(mmf_file)) {

    # read line
    #
    $line = <mmf_file>;

    # get the hmms
    #
    if ($line =~ $MODEL_FLAG) {
	
	# write to the states file
	#
	print models_file "$line";
	
	$line = <mmf_file>;
	print models_file "$line";
	$line = <mmf_file>;
	print models_file "$line";
	@num_state = split (/\s+/, $line);

	
	# loop over all states (remember that is 2 less than the number on
	# the line)
	#
	for ($i = 0; $i < ($num_state[1] - 2); $i++) {
	    
	    $prev_line = <mmf_file>;
	    $line = <mmf_file>;
	    
	    # if the state definition exists explicitly (not a macro)
	    #
	    if ($prev_line =~ $STATES_STR && $line !~ $STATES_FLAG) {
		
		# print the dummy name for this transition matrix
		#
		print states_file "$STATES_FLAG \"isip_states_$states_ind\"\n";
		print models_file "$prev_line";
		print models_file "$STATES_FLAG \"isip_states_$states_ind\"\n";
		print states_file "$line";
		$states_ind++;
		
		# if mixture exists
		#
		if ($line =~ /$NUMMIXES/) {

		    @num_mix = split (/\s+/, $line);
		    
		    # read in each mixture
		    #
		    for ($j = 0; $j < $num_mix[1]; $j++) {
			$line = <mmf_file>;
			print states_file "$line";
			$line = <mmf_file>;
			print states_file "$line";
			$line = <mmf_file>;
			print states_file "$line";
			$line = <mmf_file>;
			print states_file "$line";
			$line = <mmf_file>;
			print states_file "$line";
			$line = <mmf_file>;
			print states_file "$line";
		    }
		}

		# if single mixture model
		#
		else {
		    $line = <mmf_file>;
		    print states_file "$line";
		    $line = <mmf_file>;
		    print states_file "$line";
		    $line = <mmf_file>;
		    print states_file "$line";
		    $line = <mmf_file>;
		    print states_file "$line";
		} 
	    }
	    
            # if the state is a macro
	    #
	    elsif ($prev_line =~ $STATES_STR && $line == $STATES_FLAG) {
		
		@temp = split(/\s+/, $line);
		$state_name = $macro{$temp[1]};
		print models_file "$prev_line";		
		print models_file "$STATES_FLAG $state_name\n";
	    }
	}

	# print the transition matrix or its index
	#
	$line = <mmf_file>;
	
	# if the transition matrix is explicitly specified here (like in silst)
	# read the matrix
	#
	if ($line =~ $TRANS_STR) {	 
	    
	    # print the dummy name for this transition matrix
	    #
	    print trans_file "$TRANS_FLAG \"isip_trans_$trans_ind\"\n";
	    print models_file "$TRANS_FLAG \"isip_trans_$trans_ind\"\n";
	    print trans_file "$line";	    
	    $trans_ind++;
	    
	    @num_trans = split (/\s+/, $line);
	
	    for ($i = 0; $i < $num_trans[1]; $i++) {
		$line = <mmf_file>;
		print trans_file "$line";
	    }
	}
    
	
	# else read the transition index
	#
	else {
	    print models_file "$line";
	}
	
	# print the end of hmm definition
	#
	$line = <mmf_file>;
	print models_file "$line";
    }

    
	
    # if explicit transition matrix 
    #
    elsif ($line =~ $TRANS_FLAG) {
	

	# write to the transitions file
	#
	print trans_file "$line";
	
	$line = <mmf_file>;
    	@num_trans = split (/\s+/, $line);
	print trans_file "$line";

	for ($i = 0; $i < $num_trans[1]; $i++) {
	    $line = <mmf_file>;
	    print trans_file "$line";
	}
    }
    
    elsif  ($line =~ $STATES_FLAG) {
		
	# write to the states file
	#
	$new_state_name = "\"isip_states_$states_ind\"";
	print states_file "$STATES_FLAG $new_state_name\n";
	
	# create a mapping to the state index to the macro name for future use
	#
	@temp = split(/\s+/, $line);
	$state_name = $temp[1];
	$macro{$state_name} = $new_state_name;
	
	# increment state index
	#
	$states_ind++;
		
	$line = <mmf_file>;
    	@num_mix = split (/\s+/, $line);
	print states_file "$line";
	
	# if mixture exists
	#
	if ($line =~ /$NUMMIXES/) {
	    
	    @num_mix = split (/\s+/, $line);
	    
	    # read in each mixture
	    #
	    for ($j = 0; $j < $num_mix[1]; $j++) {
		$line = <mmf_file>;
		print states_file "$line";
		$line = <mmf_file>;
		print states_file "$line";
		$line = <mmf_file>;
		print states_file "$line";
		$line = <mmf_file>;
		print states_file "$line";
		$line = <mmf_file>;
		print states_file "$line";
		$line = <mmf_file>;
		print states_file "$line";
	    }
	}
	
	# if single mixture model
	#
	else {
	    $line = <mmf_file>;
	    print states_file "$line";
	    $line = <mmf_file>;
	    print states_file "$line";
	    $line = <mmf_file>;
	    print states_file "$line";
	    $line = <mmf_file>;
	    print states_file "$line";
	} 
    }
}
# 
# end of script
