// file: extract_feature.h
//
// definitions file for the extract_feature class (frontend)
//

// make sure definitions are made only once
//
#ifndef __ISIP_EXTRACT_FEATURE
#define __ISIP_EXTRACT_FEATURE

// isip include files
//
#ifndef __ISIP_INTEGRAL
#include <integral.h>
#endif

// forward declaration of classes
//
#ifndef __ISIP_SIGNAL
#include <Signal.h>
#endif

#ifndef __ISIP_SIGNAL_MODEL_CONSTANTS
#include "extract_feature_constants.h"
#endif

// ExtractFeature: the main extract-feature class that wraps the front-end
// 
// the order of the output vector is: c1 c2 .. cn c0 log-energy
//
class Extract_feature {

  //---------------------------------------------------------------------------
  //
  // protected data
  //
  //---------------------------------------------------------------------------
protected:

  // input signal
  //
  Signal data_sig_d;

  // declare local variables
  //
  char_1 window_type_d[ISIP_MAX_STRING_LENGTH];	// type of window to use
  logical_1 use_pre_emph_d;
                                                // flag of pre-emphasis
  float_8 pre_emph_coeff_d;	// pre-emphasis filter coeff
  logical_1 use_liftering_d;

  float_8 lifter_coeff_d;	// liftering coefficient
  float_8 frame_dur_d;	// frame duration in msecs
  float_8 window_dur_d;	// window duration in msecs
  float_8 sample_freq_d;		// sample frequency
  int_4 num_chans_d;		// number of channels in data
  int_4 channel_d;		// default channel	
  logical_1 swap_byte_d;		// whether or not to swap bytes
  char_1* input_file_d;		// name of input data file
  char_1* output_file_d;          // name of output file
  int_4 delta_win_d;		// delta window size
  int_4 num_fbanks_d;	// num filterbank channels
  float_8 mel_width_d;                     // user-defined mel width
  logical_1 cepstral_mean_subtract_d; // normalize vectors
  logical_1 c0_d;               // output c0
  logical_1 delta_d;		// delta features
  logical_1 delta_delta_d;	// delta features
  int_4 output_mode_d;        // output mode
  int_4 num_coeffs_d[EXTF_NUM_ALGORITHMS];        // coeff number for each
                                                // algorithm
  logical_1 vtln_d;               // vtln
  float_8 vtln_factor_d;   // vtl normalization factor
  int_4 vtln_algo_d;       // vtln implement algorithm

  int_4 num_file_d;                    // number of the valid files

  logical_1 zero_mean_d;
  logical_1 energy_norm_d;
  logical_1 include_energy_d;         // include energy as a feature?
  float_8 max_energy_d;               // maximum energy
  
  // determine the number of samples that will make up a window of data
  // and the number of samples that will make up a frame of data
  //
  int_4 window_num_samples_d;
  int_4 frame_num_samples_d;

  // determine the size of the vector
  //
  int_4 vector_size_d;
  int_4 vector_first_d;

protected:
  // Communicator parameters
  //
  char_1* buf_d;     // block buffer address
  int_4 capacity_d;    // block size
  int_4 size_d;        // sample size
  int_4 current_d;     // starting position of valid data
  int_4 num_block_d;   // number of blocks received
  
  //---------------------------------------------------------------------------
  //
  // public methods
  //
  //---------------------------------------------------------------------------
public:
 
  // destructors/constructors
  //
  ~Extract_feature();
  Extract_feature();
  Extract_feature(char_1*& param_file);

  // function to get the command line parameters
  //
  logical_1 get_parameter_cc(int_4 argc, char_1** argv);

  // function to read parameter file
  //
  logical_1 read_parameter_cc(char_1* params);

  // configure the front-end
  //
  logical_1 config_frontend_cc();

  // function to pre-emphasize the data
  //
  logical_1 pre_emphasize_data_cc(float_8* data);
  
  // function to apply a hamming window to the data
  //
  //logical_1 window_hamming_cc(float_8* data, int_4 num_samples);
  
  // algorithms to run on the data
  //
  logical_1 compute_mean_cc(float_8* outvec, float_8* data, int_4 num_samples);
  
  logical_1 compute_fba_cc(float_8* outvec, int_4 num_coeffs, float_8* data);
  logical_1 compute_fft_mfcc_cc(float_8* outvec, int_4 num_coeffs,
				float_8* data);
  
  // wrapper functions for fft, lpc, and plp
  //
  logical_1 func_fft_cc(float_8* output, float_8* input, int_4 num_samples);
  logical_1 func_fbank_cc(float_8* coeffs, float_8* data, int_4 num_samples);
  logical_1 func_mfbank_cc(float_8* coeffs, float_8* data, int_4 num_samples);

  logical_1 func_lifter_cc(float_8* cepstrum, int_4 num_coeffs);
  
  logical_1 func_aud_weight_cc(int_4 npoint,int_4& nfilt,float_8* cb,
			       float_8* eql, int_4* ibegen);
  
  logical_1 func_cosf_cc(int_4 temp,int_4 nfilt,float_8* wcos);
  
  logical_1 func_vtln_cc(float_8* output, int_4 num_samples);
  
  // get the next largest power of 2
  //
  inline int_4 power_of_2(int_4 size) {
    int_4 i;
    for (i = 1; i < size; i <<= 1);
    return i;
  }
  
  // output method
  //
  logical_1 write_cc(float_8** vectors, int_4 num_frames);

  logical_1 write_cc(float_8*& mfc, float_8** vectors, int_4 num_frames);
  
  // normalize method (does mean subtraction)
  //
  logical_1 normalize_cc(float_8** vectors, int_4 num_frames);
  logical_1 normalize_cc(float_8** vectors, int_4 num_frames, int_4 block);  

  // MFCC support functions
  //
  logical_1 compute_mel_cc(int num, float_8* mel);
  logical_1 compute_cenf_cc(int num, float_8* cenf, float_8* mel);
  
  // delta functions
  //
  static logical_1 compute_delta_cc(float_8** model_vectors, int_4 num_frames,
				    int_4 vector_start_pos, int_4 num_coeffs,
				    int_4 dw);

  // delta function for steaming audio data
  //
  static logical_1 compute_delta_cc(float_8* vector_a, int_4 num_coeffs_a,
				    int_4 dw_a, logical_1 delta_delta_a,
				    int_4 flag_a);
  
  logical_1 write_txt(char_1* output_file_a, float_8* vectors_a,
		      int_4 size_a);

  // compute method
  //
  logical_1 compute_cc();

  // compute method for communicator
  //
  float_8* compute_cc(int_2*& in_data, int_4& num_samples, int_4 block);

  // clean up the frontend before receiving a new utterance
  //
  logical_1 clean_cc();
};
  
// end of file
//
#endif
