⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win_05.cc

📁 这是一个从音频信号里提取特征参量的程序
💻 CC
字号:
// file: $isip/class/algo/Window/win_05.cc// version: $Id: win_05.cc,v 1.22 2002/05/31 21:57:33 picone Exp $//// isip include files//#include "Window.h"// method: apply//// arguments://  Vector<AlgorithmData>& output: (output) output data//  const Vector< CircularBuffer<AlgorithmData> >& input: (input) input data//// return: a boolean value indicating status//// this method calls the appropriate computation methods//boolean Window::apply(Vector<AlgorithmData>& output_a,		      const Vector< CircularBuffer<AlgorithmData> >& input_a) {  // determine the number of input channels and force the output to be  // that number  //  long len = input_a.length();  output_a.setLength(len);  boolean res = true;  // start the debugging output  //  displayStart(this);    // loop over the channels and call the compute method  //  for (long c = 0; c < len; c++) {    // display the channel number    //    displayChannel(c);        // call AlgorithmData::makeVectorFloat to force the output vector for    // this channel to be a VectorFloat, use the CircularBuffer<AlgorithmData>    // directly on the input for this channel    //              res &= compute(output_a(c).makeVectorFloat(),		   input_a(c),		   input_a(c)(0).getCoefType(),		   c);        // set the coefficient type for the output    //                output_a(c).setCoefType(input_a(c)(0).getCoefType());  }  // finish the debugging output  //  displayFinish(this);    // exit gracefully  //  return res;}// method: compute//// arguments://  VectorFloat& vector_out: (output) operand//  const VectorFloat& vector_in: (input) operand//  AlgorithmData::COEF_TYPE coef_type: (input) coeff type of input signal//  long channel_index: (input) the channel index of input signal//// return: a boolean value containing status//// this method applies the specified window on the input vector//boolean Window::compute(VectorFloat& vector_out_a,			const VectorFloat& vector_in_a,			AlgorithmData::COEF_TYPE coef_type_a,			long channel_index_a) {  // declare local variables  //  boolean status = false;  // check whether we need to initialize  //  if (!is_valid_d) {    init();  }  // algorithm: *all* standard algorithms  //  if ((algorithm_d == RECTANGULAR) ||      (algorithm_d == BARTLETT) ||      (algorithm_d == BLACKMAN) ||      (algorithm_d == DOLPH_CHEBYSHEV) ||      (algorithm_d == GAUSSIAN) ||      (algorithm_d == HAMMING) ||      (algorithm_d == HANNING) ||      (algorithm_d == KAISER) ||      (algorithm_d == LIFTER) ||      (algorithm_d == CUSTOM)) {    status = computeCommon(vector_out_a, vector_in_a);  }    // error: unknown algorithm  //  else {    status = Error::handle(name(), L"compute", ERR_UNKALG,			   __FILE__, __LINE__);  }  // possibly display the data  //  display(vector_out_a, vector_in_a, name());      // exit gracefully  //  return status;}// method: compute//// arguments://  VectorComplexFloat& vector_out: (output) operand//  const VectorComplexFloat& vector_in: (input) operand//  AlgorithmData::COEF_TYPE coef_type: (input) coeff type of input signal//  long channel_index: (input) the channel index of input signal//// return: a boolean value containing status//// this method applies the specified window on the input vector//boolean Window::compute(VectorComplexFloat& vector_out_a,			const VectorComplexFloat& vector_in_a,			AlgorithmData::COEF_TYPE coef_type_a,			long channel_index_a) {  // declare local variables  //  boolean status = false;  // check whether we need to initialize  //  if (!is_valid_d) {    init();  }  // algorithm: *all* standard algorithms  //  if ((algorithm_d == RECTANGULAR) ||      (algorithm_d == BARTLETT) ||      (algorithm_d == BLACKMAN) ||      (algorithm_d == DOLPH_CHEBYSHEV) ||      (algorithm_d == GAUSSIAN) ||      (algorithm_d == HAMMING) ||      (algorithm_d == HANNING) ||      (algorithm_d == KAISER) ||      (algorithm_d == LIFTER) ||      (algorithm_d == CUSTOM)) {    status = computeCommon(vector_out_a, vector_in_a);  }    // error: unknown algorithm  //  else {    status = Error::handle(name(), L"compute", ERR_UNKALG,			   __FILE__, __LINE__);  }  // possibly display the data  //  display(vector_out_a, vector_in_a, name());      // exit gracefully  //  return status;}// method: compute//// arguments://  VectorFloat& output: (output) output data//  const CircularBuffer<AlgorithmData>& input: (input) input data//  AlgorithmData::COEF_TYPE coef_type: (input) coeff type of input signal//  long channel_index: (input) the channel index of input signal//// return: a boolean value containing status//// this method applies the specified window on the input channel//boolean Window::compute(VectorFloat& output_a,			const CircularBuffer<AlgorithmData>& input_a,			AlgorithmData::COEF_TYPE coef_type_a,			long channel_index_a) {  // for FRAME_INTERNAL mode, we just process what data we have  //  if (cmode_d == FRAME_INTERNAL) {    return compute(output_a, input_a(0).getVectorFloat(), coef_type_a,		   channel_index_a);  }  double win_nsamp = duration_d * sample_freq_d;  double frame_nsamp = frame_dur_d * sample_freq_d;  if (win_nsamp < frame_nsamp) {         VectorFloat buf;        if (alignment_d == LEFT) {            // because window size is smaller than frame size, just moving      // the specified number of elements via the move method      //      buf.move(input_a(0).getVectorFloat(),	       (long)Integral::round(win_nsamp),	       0,	       0);            // apply the window function      //      return compute(output_a, buf, coef_type_a, channel_index_a);    }        else if (alignment_d == RIGHT) {            // because window size is smaller than frame size, just moving      // the specified number of elements via the move method      //      buf.move(input_a(0).getVectorFloat(),	       (long)Integral::round(win_nsamp),	       (long)Integral::round(frame_nsamp - win_nsamp),	       0);            // apply the window function      //      return compute(output_a, buf, coef_type_a, channel_index_a);          }        else if (alignment_d == CENTER) {            // moving equally forward and backward      //      // we will copy the middle (current) frame no matter what, so      // subtract it out from the totals. we will use floor for the      // left calculation which will bias us by at most half a sample      // into the past leaving the total number of samples unchanged.      //      long left_nsamp	= (long)Integral::floor(frame_nsamp / 2.0 - win_nsamp / 2.0 + 0.0001);            buf.move(input_a(0).getVectorFloat(),	       (long)Integral::round(win_nsamp),	       left_nsamp,	       0);            // apply the window function      //      return compute(output_a, buf, coef_type_a, channel_index_a);    }        // error    //    return Error::handle(name(), L"compute", Error::NOT_IMPLEM,			 __FILE__, __LINE__);      }      // make sure there is enough data  //  if ((input_a.getNumForward() < getLeadingPad())      || (input_a.getNumBackward() < getTrailingPad())) {    return Error::handle(name(), L"compute", ERR, __FILE__, __LINE__);  }  // if windown size is almost equal to frame size using FRAME_INTERNAL  // mode  //  if (Integral::almostEqual(win_nsamp, frame_nsamp)) {    return compute(output_a,		   input_a(0).getVectorFloat(),		   coef_type_a,		   channel_index_a);        }    VectorFloat buf;  if (alignment_d == LEFT) {    long frame = 0;    double num_left = win_nsamp;        while (num_left > 0) {      // while there are still full frames to copy, use concat      //      if (num_left > frame_nsamp) {	buf.concat(input_a(frame).getVectorFloat());	num_left -= frame_nsamp;      }      // for the last frame only copy over the specified number of      // elements via the move method      //      else {	buf.move(input_a(frame).getVectorFloat(),		 (long)Integral::round(num_left),		 0,		 buf.length());	num_left = 0;      }      frame++;    }    // apply the window function    //    return compute(output_a, buf, coef_type_a, channel_index_a);  }  else if (alignment_d == RIGHT) {    Double num_frames = win_nsamp / frame_nsamp;    long frame = (long)Integral::ceil(num_frames);    long index = frame - 1;    // this is the number of samples not included from the first frame    //    long first_offset = (long)Integral::round(frame * frame_nsamp - win_nsamp);    long first_nelem = (long)Integral::round(frame_nsamp - first_offset);    double num_left = win_nsamp;    boolean initialization = true;        while (num_left > 0) {      // for the first frame we probably don't copy all samples, just      // a right-aligned pre-specified number of samples.      //      if (initialization) {	buf.move(input_a(-index).getVectorFloat(),		 first_nelem, first_offset, 0);	num_left -= first_nelem;	initialization = false;      }      // for all other frames we copy the entire frame      //      else {	buf.concat(input_a(-index).getVectorFloat());	num_left -= frame_nsamp;      }      index--;    }        // apply the window function    //    return compute(output_a, buf, coef_type_a, channel_index_a);  }  else if (alignment_d == CENTER) {    long num_frames = (long)Integral::ceil(win_nsamp / frame_nsamp);    // case 0: a window is less than or equal to the frame size, only    // copy from one the middle of the current frame    //    if (num_frames == 1) {            long start_offset	= (long)Integral::floor((frame_nsamp / 2.0) - (win_nsamp / 2.0));      buf.move(input_a(0).getVectorFloat(), (long)Integral::ceil(win_nsamp),	       start_offset, 0);    }    // else we must span frames -- moving equally forward and backward    //    else {      // we will copy the middle (current) frame no matter what, so      // subtract it out from the totals. we will use floor for the      // left calculation which will bias us by at most half a sample      // into the past leaving the total number of samples unchanged.      //      long left_nsamp	= (long)Integral::floor(win_nsamp / 2.0 - frame_nsamp / 2.0);      long right_nsamp	= (long)Integral::ceil(win_nsamp / 2.0 - frame_nsamp / 2.0);      long first_frame = (long)Integral::ceil(left_nsamp / frame_nsamp);      long first_offset = first_frame * (long)Integral::round(frame_nsamp)	- left_nsamp;            long first_nelem = (long)Integral::round(frame_nsamp) - first_offset;      for (long index = first_frame; left_nsamp > 0; ) {	if (index == first_frame) {	  buf.move(input_a(-index).getVectorFloat(), first_nelem,		   first_offset, 0);	  left_nsamp -= first_nelem;	}	else {	  buf.concat(input_a(-index).getVectorFloat());	  left_nsamp -= (long)Integral::round(frame_nsamp);	}      }      // copy the middle frame      //      buf.concat(input_a(0).getVectorFloat());      long index = 1;            // now copy the future frames      //      while (right_nsamp > 0) {	// while there are still full frames to copy, use concat	//	if (right_nsamp > frame_nsamp) {	  buf.concat(input_a(index).getVectorFloat());	  right_nsamp -= (long)Integral::round(frame_nsamp);	}	// for the last frame only copy over the specified number of	// elements via the move method	//	else {	  buf.move(input_a(index).getVectorFloat(),		   (long)Integral::ceil(right_nsamp), 0,		   buf.length());	  right_nsamp = 0;	}	index++;      }    }    // apply the window function    //    return compute(output_a, buf, coef_type_a, channel_index_a);  }  // error  //  return Error::handle(name(), L"compute", Error::NOT_IMPLEM,		       __FILE__, __LINE__);}// method: computeCommon//// arguments://  VectorFloat& vector_out: (output) operand//  const VectorFloat& vector_in: (input) operand//// return: a boolean value containing status//// this method applies the window on the input vector and is called by the// public compute method//boolean Window::computeCommon(VectorFloat& vector_out_a,			      const VectorFloat& vector_in_a) {  // set the size of the window  //  long len = vector_in_a.length();  setSize(len);  vector_out_a.setLength(len);  // if window is not set then initialize the window  //  if (!is_valid_d) {    init();  }  // now apply  //  for (long i = 0; i < len; i++) {    vector_out_a(i) = data_d(i) * vector_in_a(i);  }    // exit gracefully  //  return true;}// method: computeCommon//// arguments://  VectorComplexFloat& vector_out: (output) operand//  const VectorComplexFloat& vector_in: (input) operand//// return: a boolean value containing status//// this method applies the window on the input vector and is called by the// public compute method//boolean Window::computeCommon(VectorComplexFloat& vector_out_a,			      const VectorComplexFloat& vector_in_a) {  // set the size of the window  //  long len = vector_in_a.length();  setSize(len);  vector_out_a.setLength(len);  // if window is not set then initialize the window  //  if (!is_valid_d) {    init();  }  // now apply  //  for (long i = 0; i < len; i++) {    vector_out_a(i) = complexfloat((float)data_d(i) *				   (float)vector_in_a(i).real(),				   (float)data_d(i) *				   (float)vector_in_a(i).imag());  }    // exit gracefully  //  return true;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -