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

📄 filt_05.cc

📁 这是一个从音频信号里提取特征参量的程序
💻 CC
字号:
// file: $isip/class/algo/Filter/filt_05.cc// version: $Id: filt_05.cc,v 1.21 2002/07/14 16:48:43 gao Exp $//// isip include files//#include "Filter.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 Filter::apply(Vector<AlgorithmData>& output_a,		      const Vector< CircularBuffer<AlgorithmData> >& input_a) {    // for ACCUMULATE mode, error  //  if (cmode_d == ACCUMULATE) {    return Error::handle(name(), L"apply",			 ERR_UNSUPM, __FILE__, __LINE__);  }  // adding one to indicator means we process one frame  //  frame_index_d++;    // for SAMPLE_BASED mode, error  //  if (dmode_d == SAMPLE_BASED) {    return Error::handle(name(), L"apply",			 ERR_UNSUPM, __FILE__, __LINE__);  }     // set the length to the number of channels input  //  long len = input_a.length();  output_a.setLength(len);  // set the number of channels  //  if (len != num_channels_d) {    setNumChannels(len);  }  // accumulate a result status -- if compute method returns false  // this apply method should return false  //    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 &= computeBuffer(output_a(c).makeVectorFloat(),			 input_a(c),			 input_a(c)(0).getCoefType(),			 c);        // set the coef type for AlgorithmData output    //    output_a(c).setCoefType(input_a(c)(0).getCoefType());  }  // finish the debugging output  //  displayFinish(this);  // exit gracefully  //  return res;}// method: compute// // arguments://  VectorFloat& output: (output) filtered signal//  const VectorFloat& input: (input) signal to be filtered//  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 indicating status//// this method selects the appropriate private computational method//boolean Filter::compute(VectorFloat& output_a, const VectorFloat& input_a,			AlgorithmData::COEF_TYPE coef_type_a,			long channel_index_a) {  // declare local variable  //  boolean status = false;  // check whether we need to initialize  //  if (!is_valid_d) {    init();  }  // algorithm: LTI  //  if (algorithm_d == LTI) {    // implementation: CCDE (Constant Coefficient Difference Equation)    //    if (implementation_d == CCDE) {      if (cmode_d == FRAME_INTERNAL) {	status = computeLtiCcdeFrameInternal(output_a, input_a,					     channel_index_a);      }      else {	status = computeLtiCcdeCrossFrame(output_a, input_a, channel_index_a);      }    }        // error: unknown implementation    //    else {      return Error::handle(name(), L"compute", ERR_UNKIMP,			   __FILE__, __LINE__);    }  }    // error: unknown algorithm  //  else {    status = Error::handle(name(), L"compute", ERR_UNKALG,			   __FILE__, __LINE__);  }  // possibly display the data  //  display(output_a, input_a, name());      // exit gracefully  //  return status;}// method: compute// // arguments://  VectorComplexFloat& output: (output) filtered signal//  const VectorComplexFloat& input: (input) signal to be filtered//  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 indicating status//// this method selects the appropriate computational method//boolean Filter::compute(VectorComplexFloat& output_a,			const VectorComplexFloat& input_a,			AlgorithmData::COEF_TYPE coef_type_a,			long channel_index_a) {  return Error::handle(name(), L"compute", Error::NOT_IMPLEM,		       __FILE__, __LINE__);}// method: computeLtiCcdeFrameInternal// // arguments://  VectorFloat& output: (output) filtered signal//  const VectorFloat& input: (input) signal to be filtered//  long channel_index: (input) the channel index of input signal//// return: a boolean value indicating status//// this method has filter implemented in Direct Form 1. The past and// future samples outside the input buffer are considered zero.//boolean Filter::computeLtiCcdeFrameInternal(VectorFloat& output_a,					    const VectorFloat& input_a,					    long channel_index_a) {    // check whether the channel index is valid or not  //  if (channel_index_a >= num_channels_d) {    return Error::handle(name(), L"computeLtiCcdeFrameInternal", Error::ARG,			 __FILE__, __LINE__);  }    // check whether the filter is valid or not  //  if (!is_valid_d) {    init();  }    // allocate memory for output signal  //  long input_len = input_a.length();  long ma_max = ma_lag_d.max();  long len = input_len - ma_max;  // at least one element exist in current frame beside future samples  // to process  //  if (len < 1) {    return Error::handle(name(), L"computeLtiCcdeFrameInternal", ERR_DATA,			 __FILE__, __LINE__);  }    output_a.setLength(len);  // loop through the input signal  //  for (long index = 0; index < len; index++) {    // fetch the future samples if any and if the filter is anti-causal    //    for (long i = ma_lag_d.length() - (long)1; i >= 0; i--) {      if ((ma_lag_d(i) > (long)0) && ((index + ma_lag_d(i)) < input_len)) {	ma_mem_d(channel_index_a).	  advanceAndAssign(input_a(index + ma_lag_d(i)),			   (ma_lag_d(i) + (long)1));		// reverse the pointer position from future to present	//	ma_mem_d(channel_index_a).advance(-ma_lag_d(i) - (long)1);      }    }        // advance the read pointer and append the input sample    //    ma_mem_d(channel_index_a).advanceAndAssign(input_a(index));	      // declare local variables    //    Float sum = 0.0;        // loop through the moving average coefficients    //    for (long i = ma_lag_d.length() - (long)1; i >= 0; i--) {      // limit the input sample to future samples, prevent the      // circular buffer from fetching the past sample when the      // pointer makes a complete circle through the buffer      //      if (((index + ma_lag_d(i)) < input_len) &&	  (ma_lag_d(i) + index >= 0)) {	sum += (float)ma_coef_d(i) *	  (float)ma_mem_d(channel_index_a)((long)ma_lag_d(i));      }    }    // loop through the auto regressive coefficients only if the    // filter is regressive (IIR)    //    for (long i = ar_lag_d.length() - (long)1; i >= 0; i--) {      if (ar_lag_d(i) + index >= 0)	sum -= (float)ar_coef_d(i) *	  (float)ar_mem_d(channel_index_a)((long)ar_lag_d(i));    }        // advance the ar memory and save the output    //    ar_mem_d(channel_index_a).assignAndAdvance(sum);    output_a(index) = sum;  }  // exit gracefully  //  return true;}// method: computeBuffer//// arguments://  VectorFloat& output: (output) output buffer of frames//  const CircularBuffer<AlgorithmData>& input: (input) circular buffer//  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 indicating status//// this method transfers the input circular buffer data into one data vector// with necessary leading or trailing pad.//boolean Filter::computeBuffer(VectorFloat& output_a,			      const CircularBuffer<AlgorithmData>& input_a,			      AlgorithmData::COEF_TYPE coef_type_a,			      long channel_index_a) {      // make sure there is enough data  //  if (input_a.getNumForward() < getLeadingPad()) {    return Error::handle(name(), L"computeBuffer",ERR_INSUFD, __FILE__,			 __LINE__);  }    // compute the number of samples per frame using the current frame  // in the circular buffer since it always contains one frame of data  //  long frame_nsamp = input_a(0).getVectorFloat().length();  // get the number of future samples and the number of frames  //  long future_nsamp = getLeadingNumSamp();  long future_nframe = getLeadingPad();    if (future_nsamp > ma_mem_d(0).length()) {    return Error::handle(name(), L"computeBuffer", ERR_INSUFD, __FILE__,			 __LINE__);  }    // declare local variables  //  long future_offset_num = future_nsamp % (long)frame_nsamp;  long pad_pos = frame_nsamp;  // form a vector for that has required future samples for all the  // samples in the current frame  //  VectorFloat buf;  buf.assign(input_a(0).getVectorFloat());  if (cmode_d == CROSS_FRAME) {      // if future partial frames are present, copy the future frames,    // the future partial frame    //    if ((future_offset_num > (long)0)) {            // copy the future frames      //      for (long i = 1 ; i < future_nframe; i++) {          	buf.concat(input_a(i).getVectorFloat());		// increase the padding position	//	pad_pos += (long)frame_nsamp;      }            // copy the partial future frame      //      buf.move(input_a(future_nframe).getVectorFloat(),	       future_offset_num, (long)0, pad_pos);    }        // if no future partial frame is present, copy the full future frames    //    if (future_offset_num == (long)0) {            // copy the past frames, current frame and future frames      //      for (long i = 1 ; i <= future_nframe; i++) {          	buf.concat(input_a(i).getVectorFloat());      	// increase the padding position	//	pad_pos += (long)frame_nsamp;      }    }  }    boolean status;    status = compute(output_a, buf, coef_type_a, channel_index_a);    // exit gracefully  //  return status;}// method: computeLtiCcdeCrossFrame// // arguments://  VectorFloat& output: (output) filtered signal//  const VectorFloat& input: (input) signal to be filtered//  long channel_index: (input) the channel index of input signal//// return: a boolean value indicating status//// this method has filter implemented in Direct Form 1. The past and// future samples outside the current frame input buffer are used.//boolean Filter::computeLtiCcdeCrossFrame(VectorFloat& output_a,					 const VectorFloat& input_a,					 long channel_index_a) {    // check whether the channel index is valid or not  //  if (channel_index_a >= num_channels_d) {    return Error::handle(name(), L"computeLtiCcdeCrossFrame", Error::ARG,			 __FILE__, __LINE__);  }    // check whether the filter is valid or not  //  if (!is_valid_d) {    init();  }    // allocate memory for output signal  //  long input_len = input_a.length();  long ma_max = ma_lag_d.max();  long len = input_len - ma_max;  // at least one element exist in current frame beside future samples  // to process  //  if (len < 1) {    return Error::handle(name(), L"computeLtiCcdeCrossFrame", ERR_DATA,			 __FILE__, __LINE__);  }    output_a.setLength(len);  // loop through the input signal  //  for (long index = 0; index < len; index++) {    // fetch the future samples if any and if the filter is anti-causal    //    for (long i = ma_lag_d.length() - (long)1; i >= 0; i--) {      if ((ma_lag_d(i) > (long)0) && ((index + ma_lag_d(i)) < input_len)) {	ma_mem_d(channel_index_a).	  advanceAndAssign(input_a(index + ma_lag_d(i)),			   (ma_lag_d(i) + (long)1));		// reverse the pointer position from future to present	//	ma_mem_d(channel_index_a).advance(-ma_lag_d(i) - (long)1);      }    }        // advance the read pointer and append the input sample    //    ma_mem_d(channel_index_a).advanceAndAssign(input_a(index));	      // declare local variables    //    Float sum = 0.0;        // loop through the moving average coefficients    //    for (long i = ma_lag_d.length() - (long)1; i >= 0; i--) {      sum += (float)ma_coef_d(i) *	(float)ma_mem_d(channel_index_a)((long)ma_lag_d(i));    }    // loop through the auto regressive coefficients only if the    // filter is regressive (IIR)    //    for (long i = ar_lag_d.length() - (long)1; i >= 0; i--) {      sum -= (float)ar_coef_d(i) *	(float)ar_mem_d(channel_index_a)((long)ar_lag_d(i));    }        // advance the ar memory and save the output    //    ar_mem_d(channel_index_a).assignAndAdvance(sum);    output_a(index) = sum;  }  // exit gracefully  //  return true;}

⌨️ 快捷键说明

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