// file: bw_input_0.cc
//
// function to read acoustic feature data from input file
//
#define BW_SLEEP_TIME "sleep 5s"
#define BW_LOOP_TIME 3

// isip include files
//
#include "bw_train.h"
#include "bw_train_constants.h"

// method: read_input_cc
//
// arguments:
//  float_8**& data : (output) the feature vectors
//  int_4& num_vect : (outputJ) the number of vectors
//  int_4 num_feat : (input) size of the feature vector
//  int_4 input_mode : (input) ascii/binary
//  char_1* mfcc_file : (input) the mfcc file
//  int_4 input_feature_format : (input) isip_proto/htk
//  int_4 delta_win : (input) delta window size
//  logical_1 delta : (input) flag indicating delta computation
//  logical_1 acc : (input) flag indicating acceleration computation
//
// return: a logical flag to indicate success
//

// this method reads a mfcc file and gets the number of feature vectors
// 
logical_1 read_input_cc(float_8**& data_a, int_4& num_vect_a, int_4 num_feat_a,
			int_4 input_mode_a, char_1* mfcc_file_a,
			int_4 input_feature_format_a, int_4 delta_win_a,
			logical_1 delta_a, logical_1 acc_a) {
  
  // local variables
  //
  char_1* str = new char_1[ISIP_MAX_STRING_LENGTH];
  int_4 total_bytes = (int_4)0;
  int_4 header_bytes = (int_4)0;
  int_4 num = BW_LOOP_TIME;
  int_4 flag = ISIP_TRUE;
  FILE* f_mfc;
  int_4 n_samples;
  int_4 samp_period;
  int_2 samp_size;
  int_2 samp_kind;
  int_4 temp_num_feat = (int_4)0;
  float_4* temp_data = (float_4*)NULL;
  
  // open mfcc file
  //
  strcpy((char*)str, BW_SLEEP_TIME);
  if (input_mode_a == BW_ASCII_MODE) {
    f_mfc = fopen((char*)mfcc_file_a, "r");
    while((f_mfc == (FILE*)NULL) && (num > (int_4)0)) {
      system((char*)str);
      num--;
      f_mfc = fopen((char*)mfcc_file_a, "r");
    }
  }
  else {
    f_mfc = fopen((char*)mfcc_file_a, "rb");
    while((f_mfc == (FILE*)NULL) && (num > (int_4)0)) {
      system((char*)str);
      num--;
      f_mfc = fopen((char*)mfcc_file_a, "rb");
    }  
  }
  if (f_mfc == (FILE*)NULL) {  
    fprintf(stdout, "Warning: cannot open file %s\n", mfcc_file_a);
    flag = ISIP_FALSE;
  }
  else {
    
    // read mfccs
    //
    num_vect_a = 0;
    if (input_mode_a == BW_ASCII_MODE) {

      if (input_feature_format_a == BW_HTK_FORMAT) {
	fprintf(stdout, "Warning: ASCII HTK input feature file not supported %s\n", mfcc_file_a);
	flag = ISIP_FALSE;
      }
      
      while(fgets((char*)str, ISIP_MAX_STRING_LENGTH, f_mfc) != (char*)NULL) {
	num_vect_a++;
      }
          
      // allocate memory
      //
      data_a = new float_8*[num_vect_a];
      rewind(f_mfc);
      for (int_4 i = 0; i < num_vect_a; i++) {
	num = 0;
	data_a[i] = new float_8[num_feat_a];
	
	// read vector
	//
	while (fscanf(f_mfc, "%lf", &data_a[i][num++]) != EOF) {
	  if (num == num_feat_a) {
	    break;
	  }
	}
	if (num != num_feat_a) {
	  flag = ISIP_FALSE;
	  break;
	}
      }
    } // end if ASCII mode
    
    else {

      // read the htk header and calculate the mfcc file size
      //      
if (input_feature_format_a == BW_HTK_FORMAT) {
      
  fseek (f_mfc, 0L, SEEK_SET);
  
  if (!fread (&n_samples, sizeof(int_4), 1, f_mfc)) {
    fprintf(stdout, "Warning: No. of Samples not specified in HTK Header file %s\n", mfcc_file_a);
    flag = ISIP_FALSE;
  }
  
  if (!fread (&samp_period, sizeof(int_4), 1, f_mfc)) {
    fprintf(stdout, "Warning: Sampling Period not specified in HTK Header file %s\n", mfcc_file_a);
    flag = ISIP_FALSE;
  }
  
  if (!fread (&samp_size, sizeof(int_2), 1, f_mfc)) {
    fprintf(stdout, "Warning: Sampling size notspecified in HTK Header file %s\n", mfcc_file_a);
    flag = ISIP_FALSE;
  }
  
  if (!fread (&samp_kind, sizeof(int_2), 1, f_mfc)) {
    fprintf(stdout, "Warning: Sampling kind not specified in HTK Header file %s\n", mfcc_file_a);
    flag = ISIP_FALSE;
  }
  
  header_bytes = ftell(f_mfc);
  fseek(f_mfc, 0, SEEK_END);
  total_bytes = ftell(f_mfc) - header_bytes;
}
 
 else {
   fseek(f_mfc, 0, SEEK_END);
   total_bytes = ftell(f_mfc);
 }

 if (acc_a == ISIP_TRUE) {
   temp_num_feat = num_feat_a / (int_4)3;
 }
 
 else if (delta_a == ISIP_TRUE) {
   temp_num_feat = num_feat_a / (int_4)2;
 }
 
 else
   temp_num_feat = num_feat_a;

 // compute number of vectors in the input mfcc file
 //
 if (input_feature_format_a == BW_HTK_FORMAT) {
   num_vect_a = total_bytes / (temp_num_feat * sizeof(float_4));
 }
 
 else num_vect_a = total_bytes / (temp_num_feat * sizeof(float_8));
 
 // allocate memory
 //
 data_a = new float_8*[num_vect_a];
 rewind(f_mfc);

 if (input_feature_format_a == BW_HTK_FORMAT) {
   
   fseek (f_mfc, 0L, SEEK_SET);
   
   if (!fread (&n_samples, sizeof(int_4), 1, f_mfc)) {
     fprintf(stdout, "Warning: No. of Samples not specified in HTK Header file %s\n", mfcc_file_a);
     flag = ISIP_FALSE;
   }
   
   if (!fread (&samp_period, sizeof(int_4), 1, f_mfc)) {
     fprintf(stdout, "Warning: Sampling Period not specified in HTK Header file %s\n", mfcc_file_a);
     flag = ISIP_FALSE;
   }
   
   if (!fread (&samp_size, sizeof(int_2), 1, f_mfc)) {
     fprintf(stdout, "Warning: Sampling size notspecified in HTK Header file %s\n", mfcc_file_a);
     flag = ISIP_FALSE;
   }
   
   if (!fread (&samp_kind, sizeof(int_2), 1, f_mfc)) {
     fprintf(stdout, "Warning: Sampling kind not specified in HTK Header file %s\n", mfcc_file_a);
     flag = ISIP_FALSE;
   }

   // read the features as float and cast to double
   //
  temp_data = new float_4[num_feat_a];
   for (int_4 i = 0; i < num_vect_a; i++) {
     data_a[i] = new float_8[num_feat_a];
     if ((int_4)fread(temp_data, sizeof(float_4), temp_num_feat, f_mfc)
	 != temp_num_feat) {
       flag = ISIP_FALSE;
       break;
     }
     for ( int_4 j = 0; j < num_feat_a; j++) {
     data_a[i][j] = (float_8)temp_data[j];
     }
   }   
 }

 // read the features as doubles
 //
 else {
   for (int_4 i = 0; i < num_vect_a; i++) {
     data_a[i] = new float_8[num_feat_a];
     if ((int_4)fread(data_a[i], sizeof(float_8), temp_num_feat, f_mfc)
	 != temp_num_feat) {
       flag = ISIP_FALSE;
       break;
     }
   }
 } 
 
 // compute the deltas and accelerations
 //
 if (delta_a == ISIP_TRUE) {
   Extract_feature::compute_delta_cc(data_a, num_vect_a, 0, temp_num_feat,
				     delta_win_a);
 }
 
 if (acc_a == ISIP_TRUE) {
   Extract_feature::compute_delta_cc(data_a, num_vect_a, temp_num_feat,
				     temp_num_feat, delta_win_a);
 }
 
    } // end if BINARY mode
  } // if it is a valid mfcc file
  
  // clean up
  //
  fclose(f_mfc);
  delete [] str;

  if (temp_data != (float_4*)NULL) {
    delete [] temp_data;
  }
  if (flag == ISIP_FALSE) {
    if (data_a != (float_8**)NULL) {
      for (int_4 i = 0; i < num_vect_a; i++) {
	if (data_a[i] != (float_8*)NULL) {
	  delete [] data_a[i];
	}
      }
      delete [] data_a;
      num_vect_a = 0;
    }
  }
    
  // return gracefully
  //
  return flag;
}
