// file: extf_parmas_1.cc
//
// function to read data from parameter file
//

// isip include files
//
#include "extract_feature.h"
#include "extract_feature_constants.h"

// method: read_params_cc
//
// arguments:
//  FILE* fp : (input) file pointer to params file
//
// return: a logical flag to indicate success
//
// this function parses parameter file.
//
logical_1 Extract_feature::read_parameter_cc(char_1* params_a) {

  // local variable
  //
  logical_1 if_set_fbanks = ISIP_FALSE;

  // open the file
  //
  FILE* fp = fopen((char*)params_a, "r"); 
  if (fp == NULL) {
    fprintf(stderr, "Can't open the parameter file: %s\n", params_a);
  }
  
  // string to hold temporary data
  //
  char_1* tmp = new char_1[ISIP_MAX_STRING_LENGTH];
  char_1* tag_str = new char_1[ISIP_MAX_STRING_LENGTH];
  char_1* tmp1 = new char_1[ISIP_MAX_STRING_LENGTH];
  char_1* tmp2 = new char_1[ISIP_MAX_STRING_LENGTH];
  char_1* tmp3 = new char_1[ISIP_MAX_STRING_LENGTH];

  // read data from file
  //
  while (fgets((char*)tmp, ISIP_MAX_STRING_LENGTH - 1, fp) != (char*)NULL) {
    
    // ignore comment lines 
    //
    if (tmp[0] == (char_1)'#') {
      
      // do nothing
      //
      continue;
    }

    // if the line is not empty, get the first string which should be the 
    // tag string
    //
    if (strlen((char*)tmp) != 1) {
      sscanf((char*)tmp, "%s", tag_str);
      
      // read window type (hamming, rectangle, hanning)
      //
      if (strcmp((char*)tag_str, "window_type") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  strcpy((char*)window_type_d, (char*)tmp3);
	}
      }

      // read window type (hamming, rectangle, hanning)
      //
      else if (strcmp((char*)tag_str, "pre_emph_coeff") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  use_pre_emph_d = ISIP_TRUE;
	  pre_emph_coeff_d = (float_8)atof((char*)tmp3);	  
	}
      }

      // read number of liftering coefficients
      //
      else if (strcmp((char*)tag_str, "lifter_coeff") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  use_liftering_d = ISIP_TRUE;
	  lifter_coeff_d = (float_8)atof((char*)tmp3);
	}
      }     

      // read duration of the analysis frame
      //
      else if (strcmp((char*)tag_str, "frame_dur") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  frame_dur_d = (float_8)atof((char*)tmp3);
	}
      }     
      
      // read duration of the analysis window
      //
      else if (strcmp((char*)tag_str, "window_dur") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  window_dur_d = (float_8)atof((char*)tmp3);
	}
      }

      // read sample frequency
      //
      else if (strcmp((char*)tag_str, "sample_frequency") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  sample_freq_d = (float_8)atof((char*)tmp3);
	}
      }

      // read the number of channels
      //
      else if (strcmp((char*)tag_str, "num_chans") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  num_chans_d = (int_4)atoi((char*)tmp3);
	}
      }

      // read the channel number
      //
      else if (strcmp((char*)tag_str, "channel") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  channel_d = (int_4)atoi((char*)tmp3);
	}
      }
            
      // read the flag of swap byte
      //
      else if (strcmp((char*)tag_str, "swap_bytes") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  if (strcmp((char*)tmp3, "yes") == 0) {
	    swap_byte_d = ISIP_TRUE;
	  }
	}
      }

      // read the flag of cepstral mean subtract
      //
      else if (strcmp((char*)tag_str, "cms") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  if (strcmp((char*)tmp3, "yes") == 0) {
	    cepstral_mean_subtract_d = ISIP_TRUE;
	  }
	}
      }

      // read the output mode: ascii, binary
      //
      else if (strcmp((char*)tag_str, "output_mode") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  if (strcmp((char*)"ascii", (char*)tmp3) == (int)0) {
	    output_mode_d = (int_4)EXTF_OUT_MODE_ASCII;
	  }
	  else if (strcmp((char*)"binary", (char*)tmp3) == (int)0) {
	    output_mode_d = (int_4)EXTF_OUT_MODE_BINA;
	  }
	}
      }

      // read the length of the regression window used to calculate
      // the derivatives
      //
      else if (strcmp((char*)tag_str, "delta_win") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  delta_win_d = (int_4)atoi((char*)tmp3);
	}
      }

      
      // read number of filterbanks to apply
      //
      else if (strcmp((char*)tag_str, "num_fbanks") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  num_fbanks_d = (int_4)atoi((char*)tmp3);
	  if_set_fbanks = ISIP_TRUE;
	}
      }

      // read user-defined mel width of filterbank
      //
      else if (strcmp((char*)tag_str, "mel_width") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  mel_width_d = (float_8)atof((char*)tmp3);
	}
      }   

      // read the list of input (raw audio) files
      //
      else if (strcmp((char*)tag_str, "input") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  strcpy((char*)input_file_d, (char*)tmp3);
	}
      }

      // read the list of output (feature) files
      //
      else if (strcmp((char*)tag_str, "output") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  strcpy((char*)output_file_d, (char*)tmp3);
	}
      }         

      // read the flag of energy
      //
      else if (strcmp((char*)tag_str, "energy") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  num_coeffs_d[EXTF_ALGO_MEAN]++;
	}
      }   

      // read filter bank 
      //
      else if (strcmp((char*)tag_str, "fba") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  num_coeffs_d[EXTF_ALGO_FBA] = (int_4)atoi((char*)tmp3);
	}
      }

      // read number of mel-spaced cepstral coefficients
      //
      else if (strcmp((char*)tag_str, "mfcc") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  num_coeffs_d[EXTF_ALGO_FFT_MFCC] = (int_4)atoi((char*)tmp3);
	}
      }

      // read the first derivative coefficient flag
      //
      else if (strcmp((char*)tag_str, "delta") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  if (strcmp((char*)tmp3, "yes") == 0) {
	    delta_d = ISIP_TRUE;
	  }
	}
      }

      // read the second derivative coefficient flag
      //
      else if (strcmp((char*)tag_str, "acc") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  if (strcmp((char*)tmp3, "yes") == 0) {
	    delta_delta_d = ISIP_TRUE;
	    delta_d = ISIP_TRUE;
	  }
	}
      }

      // read the flag of zero mean
      //
      else if (strcmp((char*)tag_str, "zero_mean") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  if (strcmp((char*)tmp3, "yes") == 0) {
	    zero_mean_d = ISIP_TRUE;
	  }
	}
      }
   
      // read the flag of energy normalization
      //
      else if (strcmp((char*)tag_str, "energy_norm") == 0) {
	if (sscanf((char*)tmp, "%s%s%s", tmp1, tmp2, tmp3) == 3) {
	  if (strcmp((char*)tmp3, "yes") == 0) {
	    energy_norm_d = ISIP_TRUE;
	  }
	}
      }

      else {
	// return with failure
	//
	return ISIP_FALSE;
      }
    }
  }

  // check num_fbanks and mel_width sets
  //  if user set num_fbanks, we should ignore mel_width
  //
  if (if_set_fbanks) {
    mel_width_d = (float_8)0;
  }
  
  // if user specifies mel_width, we need to compute the number of filterbanks
  //
  if (mel_width_d != (float_8)0) {
    float_8 max_mel = 2595 * log10(1 + sample_freq_d/(2*700.0));
    max_mel = max_mel / mel_width_d;
    num_fbanks_d = (int_4) floor(max_mel);
    if ((max_mel - (float_8)num_fbanks_d) < 0.00001) {
      num_fbanks_d--;
    }
  }
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
