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

📄 fb_05.cc

📁 这是一个从音频信号里提取特征参量的程序
💻 CC
📖 第 1 页 / 共 2 页
字号:
  for (long i = 0; i < filters_d.length(); i++) {    // call the compute method of the Filter Class    //              status &= filters_d(i).compute(tmp_output, input_a);    // add each filter output to form a vector of multichannels    //    output_a(index).assign(tmp_output);    index++;  }  // exit gracefully  //  return status;}// method: computeFrequencyCommon//// arguments://  VectorFloat& output: (output) output data vector//  const VectorFloat& input: (input) input data vector//// return: a boolean value indicating status//// this method does all the preprocessing like computing scale// (LINEAR, MEL, BARK) and central frequencies common to all the// implementations (UNIFORM, TRIANGULAR, RAISED_COSINE) in FREQUENCY// algorithm//boolean FilterBank::computeFrequencyCommon(VectorFloat& output_a,					   const VectorFloat& input_a) {  // FREQUENCY only operates in FRAME_INTERNAL mode  //  if (cmode_d == ACCUMULATE) {    return Error::handle(name(), L"computeFrequencyCommon",                         ERR_UNSUPM, __FILE__, __LINE__);  }  // local variables  //  long len = (long)0;    // FBA expects a full spectrum as input, but only uses the first  // half of it. use the complete input if the input mode is half  // (SYMMETRIC)  //  if (input_mode_d == SYMMETRIC) {    len = input_a.length();  }    else  {    len = input_a.length() / 2;  }    long last_length = warp_freq_d.length();    // do error checking  //  if (len <= 0) {    return Error::handle(name(), L"computeFrequencyCommon",			 ERR, __FILE__, __LINE__);  }    // generate the new data if necessary  //  if (!is_valid_d || (last_length != len + 1)) {        // declare the frequency vector to hold the spectrum of the input    // signal described by the frequency values from 0 to    // sample_freq/2 that is given by (N/2+1) points of the FFT    //    lin_freq_d.setLength(len + 1, false);    for (long i = 0; i < len + 1; i++) {      lin_freq_d(i) = ((float)i * sample_freq_d / (float)(2.0 * len));    }        // case: MEL    //    if (scale_d == MEL) {      Mel mel;      mel.compute(warp_freq_d, lin_freq_d);    }        // case: BARK    //    else if (scale_d == BARK) {      Bark bark;      bark.compute(warp_freq_d, lin_freq_d);    }        // case: LINEAR    //    else {      warp_freq_d.assign(lin_freq_d);    }    // compute the number of filter banks if filter spacing is given    //    if (fsmp_d == BANDWIDTH) {            float num = (warp_freq_d(warp_freq_d.length() - 1)) / bandwidth_d;      // tolerate upper cut-off of the last filter to be 0.1% greater      // than fs/2      //      order_d = (long)Integral::floor(num + 0.001) - 1;    }        // do error checking    //    if (order_d <= (long)0) {      return Error::handle(name(), L"computeFrequencyCommon", ERR,			   __FILE__, __LINE__);    }      // compute the central frequency for the filters, order_d + 2    // central frequency values altogether. To compute n filterbanks,    // we need (n+1) central frequencies. The one extra central    // frequency is to the right of sample_freq/2 that will be used in    // the computation of the filterbanks but will not influence the    // filterbank values since no mel or bark or linear frequency will    // fall to the right of sample_freq/2    //    cen_freq_d.setLength((long)order_d + 2, false);    cen_freq_d(0) = 0.0;    if (fsmp_d == BANDWIDTH) {      for (int i = 1; i <= (long)order_d + 1; i++) {	cen_freq_d(i) = (float)i * bandwidth_d;      }    }    else if (fsmp_d == ORDER) {      float s = warp_freq_d(warp_freq_d.length() - 1);      for (int i = 1; i <= (long)order_d + 1; i++) {	cen_freq_d(i) = (float)i / (float)((long)order_d + 1) * s;      }    }    else {      return Error::handle(name(), L"computeFrequencyCommon", ERR_UNKALG,			   __FILE__, __LINE__);    }    // reset the flag    //    is_valid_d = true;  }  // setup and clear the output vector  //  output_a.setLength(order_d, false);  output_a.assign(0.0);    // exit gracefully  //  return true;}// method: computeFrequencyTriangular//// arguments://  VectorFloat& output: (output) output data vector//  const VectorFloat& input: (input) input data vector//// return: a boolean value indicating status//// this method gives the filter bank amplitude for given input vector// for FREQUENCY algorithm and TRIANGULAR implementation//boolean FilterBank::computeFrequencyTriangular(VectorFloat& output_a,					       const VectorFloat& input_a) {    // call common compute method for FREQUENCY algorithm  //  if (!computeFrequencyCommon(output_a, input_a)) {    return Error::handle(name(), L"computeFrequencyTriangular", ERR,			 __FILE__, __LINE__);  }  // local variables  //  long len;    // FBA expects a full spectrum as input, but only uses the first  // half of it. use the complete input if the input mode is half  // (SYMMETRIC)  //  if (input_mode_d == SYMMETRIC) {    len = input_a.length();  }    else {    len = input_a.length() / 2;  }    // employ an index for guessing the correct bin. If the warping  // preserves monotonicity, then this will be much more efficient  // than looping over all possibilities every time  //  long guess_ind = 0;    // loop over each frequency value, we don't consider the first and  // the last sample frequencies since typically the first sample  // frequency is a dc bias and the last frequency sample at fs/2 is  // zero  //  for (long l = 1; l < len; l++) {    // check the last bin    //    if (warp_freq_d(l) >= cen_freq_d(order_d)) {      output_a((long)order_d - 1) += input_a(l) *	  (1 - ((warp_freq_d(l) - cen_freq_d(order_d)) / 		(cen_freq_d((long)order_d + 1) - cen_freq_d(order_d))));    }        else {            // try to guess the right place to start      //      long start_ind = 0;      if (warp_freq_d(l) >= cen_freq_d(guess_ind)) {	start_ind = guess_ind;      }      for (long i = start_ind; i < order_d; i++) {		// check this bin: if the frequency falls in this bin then update	// this bin's output (the upward slope of this bin's triangle) and	// update the next bin (the downward slope of the previous bin's	// triangle	//	if (warp_freq_d(l) < cen_freq_d(i + 1)) {	  	  // update the current bin (upward slope)	  //	  output_a(i) += input_a(l) * (warp_freq_d(l) - cen_freq_d(i)) / 	    (cen_freq_d(i + 1) - cen_freq_d(i));	  	  // update the previous bin (downward slope) if necessary	  //	  if (i != 0) {	    output_a(i - 1) += input_a(l) *	      (1 - ((warp_freq_d(l) - cen_freq_d(i)) / 		    (cen_freq_d(i + 1) - cen_freq_d(i))));	  }	  	  // no need to keep checking, we've found the right bin, so break	  // out of the inner for loop	  //	  guess_ind = i;	  break;	}      }    }  }    // exit gracefully  //  return true;}// method: computeFrequencyUniform//// arguments://  VectorFloat& output: (output) output data vector//  const VectorFloat& input: (input) input data vector//// return: a boolean value indicating status//// this method gives the filter bank amplitude for given input vector// for FREQUENCY algorithm and UNIFORM implementation//boolean FilterBank::computeFrequencyUniform(VectorFloat& output_a,					    const VectorFloat& input_a) {    // call common compute method for FREQUENCY algorithm  //  if (!computeFrequencyCommon(output_a, input_a)) {    return Error::handle(name(), L"computeFrequencyUniform", ERR,			 __FILE__, __LINE__);  }    // local variables  //  long len;    // FBA expects a full spectrum as input, but only uses the first  // half of it. use the complete input if the input mode is half  // (SYMMETRIC)  //  if (input_mode_d == SYMMETRIC) {    len = input_a.length();  }    else {    len = input_a.length() / 2;  }    // employ an index for guessing the correct bin. If the warping  // preserves monotonicity, then this will be much more efficient  // than looping over all possibilities every time  //  long guess_ind = 0;    // loop over each frequency value, we don't consider the first and  // the last sample frequencies since typically the first sample  // frequency is a dc bais and the last frequency sample at fs/2 is  // zero  //  for (long l = 1; l < len; l++) {    // check the last bin    //    if (warp_freq_d(l) >= cen_freq_d(order_d)) {      output_a((long)order_d - 1) += input_a(l);    }        else {            // try to guess the right place to start      //      long start_ind = 0;      if (warp_freq_d(l) >= cen_freq_d(guess_ind)) {	start_ind = guess_ind;      }      for (long i = start_ind; i < order_d; i++) {		// check this bin: if the frequency falls in this bin then	// update this bin's output and update the next bin	//	if (warp_freq_d(l) < cen_freq_d(i + 1)) {	  	  // update the current bin (upward slope)	  //	  output_a(i) += input_a(l);	  	  // update the previous bin (downward slope) if necessary	  //	  if (i != 0) {	    output_a(i - 1) += input_a(l);	  }	  	  // no need to keep checking, we've found the right bin, so break	  // out of the inner for loop	  //	  guess_ind = i;	  break;	}      }    }  }      // exit gracefully  //  return true;}// method: computeFrequencyRaisedcosine//// arguments://  VectorFloat& output: (output) output data vector//  const VectorFloat& input: (input) input data vector//// return: a boolean value indicating status//// this method gives the filter bank amplitude for given input vector// for FREQUENCY algorithm and RAISED_COSINE implementation//boolean FilterBank::computeFrequencyRaisedcosine(VectorFloat& output_a,						 const VectorFloat& input_a) {    // call common compute method for FREQUENCY algorithm  //  if (!computeFrequencyCommon(output_a, input_a)) {    return Error::handle(name(), L"computeFrequencyRaisedcosine", ERR,			 __FILE__, __LINE__);  }    // local variables  //  long len;    // FBA expects a full spectrum as input, but only uses the first  // half of it. use the complete input if the input mode is half  // (SYMMETRIC)  //  if (input_mode_d == SYMMETRIC) {    len = input_a.length();  }    else {    len = input_a.length() / 2;  }    // employ an index for guessing the correct bin. If the warping  // preserves monotonicity, then this will be much more efficient  // than looping over all possibilities every time  //  long guess_ind = 0;    // loop over each frequency value, we don't consider the first and  // the last sample frequencies since typically the first sample  // frequency is a dc bais and the last frequency sample at fs/2 is  // zero  //  for (long l = 1; l < len; l++) {    // check the last bin    //    if (warp_freq_d(l) >= cen_freq_d(order_d)) {      output_a((long)order_d - 1) += input_a(l) *	(float)Integral::cos(((warp_freq_d(l) - cen_freq_d(order_d)) / (cen_freq_d((long)order_d + 1) - cen_freq_d(order_d))) * (((float)Integral::PI) / (float)4));    }        else {            // try to guess the right place to start      //      long start_ind = 0;      if (warp_freq_d(l) >= cen_freq_d(guess_ind)) {	start_ind = guess_ind;      }      for (long i = start_ind; i < order_d; i++) {		// check this bin: if the frequency falls in this bin then update	// this bin's output (the upward slope of this bin's cosine) and	// update the next bin (the downward slope of the previous bin's	// cosine fuction	//	if (warp_freq_d(l) < cen_freq_d(i + 1)) {	  	  // update the current bin (upward slope)	  //	  output_a(i) += input_a(l) *	    (float)Integral::cos(((1- (warp_freq_d(l) - cen_freq_d(i))) / (cen_freq_d(i + 1) - cen_freq_d(i))) * (((float)Integral::PI)/(float)4));	  	  // update the previous bin (downward slope) if necessary	  //	  if (i != 0) {	    output_a(i - 1) += input_a(l) *	      (float)Integral::cos(((warp_freq_d(l) - cen_freq_d(i)) / (cen_freq_d(i + 1) - cen_freq_d(i))) * (((float)Integral::PI)/(float)4));	  }	  	  // no need to keep checking, we've found the right bin, so break	  // out of the inner for loop	  //	  guess_ind = i;	  break;	}      }    }  }    // exit gracefully  //  return true;}

⌨️ 快捷键说明

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