📄 fb_05.cc
字号:
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 + -