📄 refl_05.cc
字号:
// file: $isip/class/algo/Reflection/refl_05.cc// version: $Id: refl_05.cc,v 1.21 2002/02/28 03:21:55 zheng Exp $//// isip include files//#include "Reflection.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 Reflection::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); // branch on input coefficient type - covariance takes matrix as input // if (input_a(c)(0).getCoefType() == AlgorithmData::COVARIANCE) { // call AlgorithmData::makeVectorFloat to force the output vector for // this channel to be a VectorFloat. // call AlgorithmData::getMatrixFloat on the input for this channel // to check that the input is already a MatrixFloat and return // that matrix. // res &= compute(output_a(c).makeVectorFloat(), input_a(c)(0).getMatrixFloat(), input_a(c)(0).getCoefType(), c); } // branch on input coefficient type - others take vector as input // else { // call AlgorithmData::makeVectorFloat to force the output vector for // this channel to be a VectorFloat, call AlgorithmData::getVectorFloat // on the input for this channel to check that the input is // already a VectorFloat and return that vector. // res &= compute(output_a(c).makeVectorFloat(), input_a(c)(0).getVectorFloat(), input_a(c)(0).getCoefType(), c); } // set the coefficient type for the output // output_a(c).setCoefType(AlgorithmData::REFLECTION); } // finish the debugging output // displayFinish(this); // exit gracefully // return res;}// method: compute//// arguments:// VectorFloat& coeff: (output) output reflection coefficients// const VectorFloat& input: (input) input data// AlgorithmData::COEF_TYPE input_coef_type: (input) type of input// long index: (input) channel number//// return: a boolean value indicating status//// this method computes the reflection coefficents for given input data//boolean Reflection::compute(VectorFloat& coeff_a, const VectorFloat& input_a, AlgorithmData::COEF_TYPE input_coef_type_a, long index_a) { // declare local variable // Float temp_energy; // invoke the appropriate compute method and exit gracefully // return compute(coeff_a, temp_energy, input_a, input_coef_type_a, index_a);}// method: compute//// arguments:// VectorFloat& coeff: (output) predictor or reflection coefficents// const MatrixFloat& input: (input) input data (covariance matrix)// AlgorithmData::COEF_TYPE input_coef_type: (input) type of input// long index: (input) channel number//// return: a boolean value indicating status//// this method computes the reflection coefficents from input covariance matrix//boolean Reflection::compute(VectorFloat& coeff_a, const MatrixFloat& input_a, AlgorithmData::COEF_TYPE input_coef_type_a, long index_a) { // declare local variable // Float temp_energy; // invoke the appropriate compute method and exit gracefully // return compute(coeff_a, temp_energy, input_a, input_coef_type_a);}// method: compute//// arguments:// VectorFloat& coeff: (output) output reflection coefficients// Float& err_energy: (output) error energy // const VectorFloat& input: (input) input data// AlgorithmData::COEF_TYPE input_coef_type: (input) type of input// long index: (input) channel number//// return: a boolean value indicating status//// this method computes the reflection coefficents as well as the error energy//boolean Reflection::compute(VectorFloat& coeff_a, Float& err_energy_a, const VectorFloat& input_a, AlgorithmData::COEF_TYPE input_coef_type_a, long index_a) { // declare local variable // boolean status = false; // algorithm: AUTOCORRELATION // if (algorithm_d == AUTOCORRELATION) { // implementation: DURBIN // if (implementation_d == DURBIN) { status = computeAutoDurbin(coeff_a, err_energy_a, input_a); } // implementation: LEROUX_GUEGUEN // else if (implementation_d == LEROUX_GUEGUEN) { status = computeAutoLeroux(coeff_a, err_energy_a, input_a); } // error: unknown implementation // else { return Error::handle(name(), L"compute", ERR_UNKIMP, __FILE__, __LINE__); } } // algorithm: LATTICE // else if (algorithm_d == LATTICE) { // implementation: BURG // if (implementation_d == BURG) { status = computeLatticeBurg(coeff_a, err_energy_a, input_a); } // error: unknown implementation // else { return Error::handle(name(), L"compute", ERR_UNKIMP, __FILE__, __LINE__); } } // algorithm: PREDICTION // else if (algorithm_d == PREDICTION) { // implementation: STEP_UP // if (implementation_d == STEP_UP) { status = computePredictionStepUp(coeff_a, input_a); } // error: unknown implementation // else { return Error::handle(name(), L"compute", ERR_UNKIMP, __FILE__, __LINE__); } } // algorithm: LOG_AREA_RATIO // else if (algorithm_d == LOG_AREA_RATIO) { // implementation: KELLY_LOCHBAUM // if (implementation_d == KELLY_LOCHBAUM) { status = computeLogAreaKellyLochbaum(coeff_a, input_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(coeff_a, input_a, name()); // exit gracefully // return status;}// method: compute//// arguments:// VectorFloat& coeff: (output) predictor or reflection coefficents// Float& err_energy: (output) error energy // const MatrixFloat& input: (input) input data (covariance matrix)// AlgorithmData::COEF_TYPE input_coef_type: (input) type of input// long index: (input) channel number//// return: a boolean value indicating status//// this method computes the reflection coefficents from input covariance matrix// as well as the error energy//boolean Reflection::compute(VectorFloat& coeff_a, Float& err_energy_a, const MatrixFloat& input_a, AlgorithmData::COEF_TYPE input_coef_type_a, long index_a) { // declare local variable // boolean status = false; // algorithm: COVARIANCE // if (algorithm_d == COVARIANCE) { // implementation: CHOLESKY // if (implementation_d == CHOLESKY) { status = computeCovarCholesky(coeff_a, err_energy_a, input_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(coeff_a, input_a, name()); // exit gracefully // return status;}// method: computeAutoDurbin//// arguments:// VectorFloat& output: (output) reflection coefficients// Float& err_energy: (output) error energy // const VectorFloat& input: (input) autocorrelation coefficients//// return: a boolean value indicating status//// this method computes the reflection coefficients from the// autocorrelation coefficents. it also outputs the error energy.//// Reference:// J.D. Markel and A.H. Gray, "Linear Prediction of Speech,"// Springer-Verlag Berlin Heidelberg, New York, USA, pp. 217-219,// 1980.//boolean Reflection::computeAutoDurbin(VectorFloat& output_a, Float& err_energy_a, const VectorFloat& input_a) { // declare local variables // VectorFloat pred_coef; // apply dynamic range threshold // float old_auto_0 = input_a(0); if (dyn_range_d < (float)0) { double scale_factor = pow(10.0, (float)dyn_range_d / Integral::DB_POW_SCALE_FACTOR); const_cast<VectorFloat&>(input_a)(0) *= (1 + scale_factor); } else { return Error::handle(name(), L"computeAutoDurbin", ERR_DYNRANGE, __FILE__, __LINE__); } // declare local variables // long i, j; // loop counters long lp_order = input_a.length() - 1; // analysis order long j_bckwd; // a backwards index long middle_index; // inner loop limit double sum; // accumulator double rc_reg; // register // create space // if (!pred_coef.setLength(lp_order + 1)) { return Error::handle(name(), L"computeAutoDurbin", ERR, __FILE__, __LINE__, Error::WARNING); } if (!output_a.setLength(lp_order)) { return Error::handle(name(), L"computeAutoDurbin", ERR, __FILE__, __LINE__, Error::WARNING); } // initialization // pred_coef(0) = 1.0; err_energy_a = input_a(0); // if the energy of the signal is zero we set all the predictor // coefficients to zero and exit // if (err_energy_a == (float)0) { for (int i = 0; i < output_a.length(); i++) { output_a(i) = 0; } return true; } // do the first step manually // sum = -(double)input_a(1) / err_energy_a; output_a(0) = sum; pred_coef(1) = sum; err_energy_a *= (1 - sum * sum); // recursion // for (i = 2; i <= lp_order; i++) { // compute the next reflection coefficient // sum = 0; for (j = 1; j < i; j++) { sum += pred_coef(j) * input_a(i - j); } // check for divide by zero error // if (err_energy_a == (float)0) { return Error::handle(name(), L"computeAutoDurbin", Error::ARG, __FILE__, __LINE__); } rc_reg = - ((float)input_a(i) + sum) / err_energy_a; // compute the new prediction coefficients // note: the algorithm used here minimizes the storage. // // Reference: // J.D. Markel and A.H. Gray, "Linear Prediction of Speech," // Springer-Verlag Berlin Heidelberg, New York, USA, pp. 219, // 1980. // output_a(i - 1) = rc_reg; pred_coef(i) = rc_reg; j_bckwd = i - 1; middle_index = i / 2; for (j = 1; j <= middle_index; j++) { sum = pred_coef(j_bckwd) + (float)rc_reg* pred_coef(j); pred_coef(j) = pred_coef(j) + (float)rc_reg * pred_coef(i - j); pred_coef(j_bckwd) = sum; j_bckwd--; } // compute new error // err_energy_a *= 1.0 - rc_reg * rc_reg; } // resume the input_a(0) // const_cast<VectorFloat&>(input_a)(0) = old_auto_0; // exit gracefully // return true;}// method: computeAutoLeroux//// arguments:// VectorFloat& output: (output) reflection coefficients// Float& err_energy: (output) error energy // const VectorFloat& input: (input) input data//// return: a boolean value indicating status//// this method computes the reflection coefficients from the// autocorrelation coefficents. it also outputs the error energy.//// Reference:// J.D. Markel and A.H. Gray, "Linear Prediction of Speech,"// Springer-Verlag Berlin Heidelberg, New York, USA, pp. 217-219,// 1980.//boolean Reflection::computeAutoLeroux(VectorFloat& output_a, Float& err_energy_a, const VectorFloat& input_a) { return Error::handle(name(), L"computeAutoLeroux", ERR_UNKIMP, __FILE__, __LINE__);}// method: computeCovarCholesky//// arguments:// VectorFloat& output: (output) reflection coefficients// Float& err_energy: (output) error energy // const MatrixFloat& cor: (input) covariance coefficients//// return: a boolean value indicating status//// this method computes the reflection coefficients using the// covariance analysis method. it also outputs the error energy.//// Reference:// J.D. Markel and A.H. Gray, "Linear Prediction of Speech,"// Springer-Verlag Berlin Heidelberg, New York, USA, pp. 51-55, 1980.//boolean Reflection::computeCovarCholesky(VectorFloat& output_a, Float& err_energy_a, const MatrixFloat& cor_a) { // declare local variable // VectorFloat pred_coef;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -