// file: extract_feature/extf_algo_3.cc
//

// isip include files
//
#include "extract_feature.h"
#include <Signal.h>

#include "extract_feature_constants.h"
#include <signal_constants.h>

// method: compute_delta_cc
//
// arguments:
//  float_8** vectors_a: (input/output) feature vectors
//  int_4 num_frame: number of frames of feature vectors
//  int_4 vec_start_pos: the position of the start coefficient in a vector
//
// this method computes delta parameters of the signal using the
// regression formula as in the equation 5.15 in the HTK Manual P72
//
logical_1 Extract_feature::compute_delta_cc(float_8** vectors_a,
					    int_4 num_frame_a,
					    int_4 vec_start_pos_a,
					    int_4 vector_first_a,
					    int_4 dw_a) {
  
  int_4 frame;  // frame index
  int_4 c_pos;  // index for original coefficient in the vectors array
  int_4 d_pos;  // index for delta coefficient in the vectors array
  int_4 i;
  int_4 vec_end_pos;
  float_8 denom = 0.0;
  float_8 acc = 0.0;
  
  // compute the denominator of the regression formula 
  //
  for (i = 1; i<= dw_a; i++) {
    denom += i*i;
  }
  denom *= 2.0;
  
  // full regression formula 
  //
  for (frame = 0; frame < num_frame_a; frame++) {
    
    // compute delta coefficient for one frame
    //
    vec_end_pos = vec_start_pos_a + vector_first_a;
    for (c_pos = vec_start_pos_a; c_pos < vec_end_pos; c_pos++) {
      
      acc = 0.0;
      d_pos = c_pos + vector_first_a;
      
      for (i = 1; i <= dw_a; i++){
	
	// take care of the beginning frames of the feature vectors
	//
	if (frame < dw_a) {
	  acc += i*(vectors_a[frame+i][c_pos] - vectors_a[0][c_pos]);
	}
	// take care of the end frames of the feature vectors
	//
	else if (frame >= num_frame_a - dw_a) {
	  acc += i * (vectors_a[num_frame_a - 1][c_pos] -
		      vectors_a[frame - i][c_pos]);
	}
	else {
	  acc += i*(vectors_a[frame + i][c_pos] - vectors_a[frame - i][c_pos]);
	}
      }
      vectors_a[frame][d_pos] = acc / denom;
    } // end of computing delta coefficient for one frame
  }  //  end of full regression
  
  // return without error
  //
  return ISIP_TRUE;
}
