// file: extract_feature/extf_algo_1.cc
//

// isip include files
//
#include "extract_feature.h"
#include <string.h>
#include <math.h>
#include "extract_feature_constants.h"

// method: compute_fba_cc
//
// arguments:
//  float_8* vector: (output) feature
//  float_8* window_buffer_a: (input) window of data
//
// This method is to implement the digital filter bank, the output is
// a vector of power values for each frame of data
//

logical_1 Extract_feature::compute_fba_cc(float_8* vector_a,
					  int_4 num_coeffs_a,
					  float_8* window_buffer_a) {

  int_4 size = power_of_2(window_num_samples_d);
  float_8 *spectrum = new float_8[size];
  memset(spectrum, 0, size * sizeof(float_8));
  
  // compute the spectrum via the FFT
  //
  func_fft_cc(spectrum, window_buffer_a, size);

  int_4 len = size/2;

  // vocal tract length normalization (VTLN)
  //
  if (vtln_d)
    func_vtln_cc(spectrum, len);
    
  // use a mel scaled triangular filter bank to extract features
  //
  float_8 *dfbank = new float_8[num_coeffs_a];
  memset(dfbank, 0, (num_coeffs_a) * sizeof(float_8));
  

  float_8* mel = new float_8[len + 1];
  compute_mel_cc(len, mel);

  float_8* cenf = new float_8[num_coeffs_a + 2];
  compute_cenf_cc(len, cenf, mel);

  float_8 *norm = new float_8[num_coeffs_a];
  memset(norm, 0, (num_coeffs_a) * sizeof(float_8));
  float_8 power;

  for (int_4 i = 0; i<num_coeffs_a; i++) {
    for (int_4 l = 0; l<len+1; l++) {
      if ((mel[l] >= cenf[i]) && (mel[l] < cenf[i+1])) {
      	power = spectrum[l]*((mel[l]-cenf[i])/
					  (cenf[i+1]-cenf[i]));
	dfbank[i] += power * power;
	norm[i]++;
      }
      else if ((mel[l] >= cenf[i+1]) && (mel[l] < cenf[i+2])) {
	power =  spectrum[l]*((mel[l]-cenf[i+1])/
					  (cenf[i+2]-cenf[i+1]));
	dfbank[i] += power * power;
	norm[i]++;
      }
    }
    if (dfbank[i] > 0) {
      dfbank[i] = log(dfbank[i]/norm[i]);
    }
    else {
      dfbank[i] = ISIP_MINIMUM_FLOAT_4;
    }
  }
  
  // copy over the specified number of mfcc's onto the vector
  //
  memcpy(vector_a, &dfbank[0], num_coeffs_a * sizeof(float_8));

  // free memory
  //
  delete [] spectrum;
  delete [] dfbank;
  delete [] norm;
  delete [] mel;
  delete [] cenf;
  
  // return without error
  //
  return ISIP_TRUE;
}
