📄 win_06.cc
字号:
// return: a boolean value indicating status//// this method generates a Gaussian window function://// 2 2// w(n) = { G * exp (-0.5 * k * (tan(theta_0/2)) , n <= |M|// { 0 elsewhere//// theta_0 is the width of the main lobe in radians, and is related// to the frequency response of the window.// a good reference for this window can be found at://// R.A. Roberts and C.T. Mullis, Digital Signal Processing,// Addison Wesley Publishing Company, Reading, Massachusetts, USA,// 1987, pp. 183-188.//// there are two parameters allowed for this window://// params(0): G, the gain of the window// params(1): theta_0, the main lobe width//// for an odd number of points, the window is defined as above.// for an even number of points, an interpolation technique is used.//boolean Window::generateGaussian(VectorFloat& output_a, const VectorFloat& params_a, long num_points_a) const { // compute some constants related to the length of the window // long N = num_points_a; long Nm1 = N - 1; long Nm2 = Nm1 - 1; float scale = (float)Nm2 / (float)Nm1; // compute the half-window length // long M = (N - 1) / 2; // define some useful constants related to the Gaussian function // float theta_0 = params_a(1); float arg1 = (float)(theta_0 / 2.0); float arg2 = Integral::tan(arg1); // create output space // output_a.setLength(num_points_a); // case 1: an odd number of points // if ((N % 2) != 0) { // loop over all elements // for (long n = -M; n <= M; n++) { output_a(n + M) = (float)params_a(0) * Integral::exp(-0.5 * (float)n * (float)n * arg2 * arg2); } } // case 2: an even number of points // use a resampling strategy // else { for (long n = 0; n < N; n++) { float scaled_index = -M + scale * n; output_a(n) = (float)params_a(0) * Integral::exp(-0.5 * (float)scaled_index * (float)scaled_index * arg2 * arg2); } } // exit gracefully // return true;}// method: generateGeneralizedHanning//// arguments: // VectorFloat& output: (output) the window function// const VectorFloat& params: (input) window function parameters// long num_points: (input) number of points in the window//// return: a boolean value indicating status//// this method generates a generalized Hanning window function://// w(n) = { G * (alpha - (1 - alpha) cos (2 * PI * n / (N-1))) 0 <= n < N// { 0 elsewhere//// the constant alpha can be used to implement a variety of windows,// including a Hamming (alpha = 0.54) and Hanning (alpha = 0.50).// a good reference for this window can be found at://// L.R. Rabiner and R.W. Schafer, Digital Processing of Speech Signals,// Prentice-Hall, Englewood Cliffs, New Jersey, USA, 1978, pp. 121.//// there are two parameters allowed for this window://// params(0): G, the gain of the window// params(1): alpha, the main lobe width//// this window works the same way for both odd and even samples.//boolean Window::generateGeneralizedHanning(VectorFloat& output_a, const VectorFloat& params_a, long num_points_a) const { // compute some constants related to the length of the window // long N = num_points_a; long Nm1 = N - 1; // create output space // output_a.setLength(N); // loop over all elements // for (long n = 0; n < N; n++) { float arg1 = 2.0 * Integral::PI * (float)n / (float)(Nm1); output_a(n) = (float)params_a(0) * ((float)params_a(1) - (1 - (float)params_a(1)) * Integral::cos(arg1)); } // exit gracefully // return true;}// method: generateKaiser//// arguments: // VectorFloat& output: (output) the window function// const VectorFloat& params: (input) window function parameters// long num_points: (input) number of points in the window//// return: a boolean value indicating status//// this method generates a Kaiser window function://// 2// w(n) = { I (beta * sqrt(1 - (n/M) ) / I (beta) n <= |M|// 0 0// = { 0 elsewhere//// there are a couple of important auxiliary design equations://// alpha_s = 2.285 * N * dw + 8//// where dw is the transition bandwidth in normalized radian frequency and// N is the window length. from alpha_a, we compute beta using the// following heuristically derived equations://// { 0.1102(alpha_s - 8.7), alpha_s > 50// beta = { 0.5842(alpha_s - 21)**0.4 +// 0.07886(alpha_s - 21) 21 <= alpha_s <= 50// { 0 alpha_s < 21//// a good reference for this window can be found at://// S.K. Mitra, Digital Signal Processing,// McGraw-Hill, Boston, Massachusetts, USA, 2001, pp. 456.//// there are two parameters allowed for this window://// params(0): G, the gain of the window// params(1): dw, the normalized transition bandwidth//// for an odd number of points, the window is defined as above.// for an even number of points, an interpolation technique is used.//boolean Window::generateKaiser(VectorFloat& output_a, const VectorFloat& params_a, long num_points_a) const { // compute some constants related to the length of the window // long N = num_points_a; long Nm1 = N - 1; long Nm2 = Nm1 - 1; float scale = (float)Nm2 / (float)Nm1; // compute the half-window length // long M = (N - 1) / 2; // create output space // output_a.setLength(N); // convert the transition bandwidth (delta_w) and window length (M) to // an attenuation in dB (alpha_s) // float alpha_s = N * 2.285 * params_a(1) + 8.0; // convert the attenuation to beta // float beta; if (alpha_s >= 50.0) { beta = 0.1102 * (alpha_s - 8.7); } else if ((alpha_s > 21) && (alpha_s < 50)) { beta = 0.5842 * Integral::pow(alpha_s - 21.0, 0.4) + 0.07886 * (alpha_s - 21.0); } else { return Error::handle(name(), L"generateKaiser", ERR_PRM, __FILE__, __LINE__); } // precompute the normalization factor // float num, denom; Bessel::compute(denom, beta, 0); // case 1: an odd number of points // if ((N % 2) != 0) { for (long n = -M; n <= M; n++) { // compute the argument and then the Bessel function value // float n_M = (float)n / (float)M; float arg1 = beta * Integral::sqrt(1.0 - n_M * n_M); Bessel::compute(num, arg1, 0); // save the output value // output_a(n + M) = params_a(0) * num / denom; } } // case 2: an even number of points // use a resampling technique // else { for (long n = 0; n < N; n++) { // compute the argument and then the Bessel function value // float scaled_index = -M + scale * n; float n_M = Integral::min(scaled_index / (float)M, 1.0); float arg1 = beta * Integral::sqrt(1.0 - n_M * n_M); Bessel::compute(num, arg1, 0); // save the output value // output_a(n) = params_a(0) * num / denom; } } // exit gracefully // return true;}// method: generateLifter//// arguments: // VectorFloat& output: (output) the window function// const VectorFloat& params: (input) window function parameters// long num_points: (input) number of points in the window//// return: a boolean value indicating status//// this method generates a raised sine, often called a lifter,// window function://// w(n) = { G * (1 + h * sin(n * PI / L)) 1 <= n <= L// { 0 elsewhere//// the constant h is normally set to L/2. note that L != N.// a good reference for this window can be found at://// L. Rabiner and B.H. Juang, Fundamentals of Speech Recognition,// Prentice-Hall, Englewood Cliffs, New Jersey, USA, 1993, pp. 169.//// there are two parameters allowed for this window://// params(0): G, the gain of the window// params(1): L, the raised sine frequency// params(2): h, the raised sine scale factor//boolean Window::generateLifter(VectorFloat& output_a, const VectorFloat& params_a, long num_points_a) const { // compute some constants related to the length of the window // long N = num_points_a; float L = params_a(1); float h = params_a(2); // create output space // output_a.setLength(N); output_a(0) = 0.0; // loop over all elements // for (long n = 1; n < N; n++) { // check the limits // if (n <= L) { float arg1 = (float)n * Integral::PI / L; output_a(n) = (float)params_a(0) * (1 + h * Integral::sin(arg1)); } else { output_a(n) = 0; } } // exit gracefully // return true;}// method: getLeadingPad//// arguments: none //// return: a long value indicating leading pad (in units of frames)//long Window::getLeadingPad() const { // in FRAME_INTERNAL mode, we only deal with the current frame // if (cmode_d == FRAME_INTERNAL) { return 0; } // for a right-aligned window, there is no leading pad // if (alignment_d == RIGHT) { return 0; } // for a left-aligned window, we need to compute the overlap // float overlap = (duration_d - frame_dur_d) / frame_dur_d; if (alignment_d == LEFT) { return (long)Integral::ceil(overlap); } // for a center-aligned window, we need to compute the overlap // else if (alignment_d == CENTER) { return (long)Integral::ceil(overlap / 2); } // else: exit ungracefully // else { return Error::handle(name(), L"getLeadingPad", ERR_PRM, __FILE__, __LINE__); }}// method: getTrailingPad//// arguments: none //// return: a long value indicating the trailing pad (in units of frames)//long Window::getTrailingPad() const { // in FRAME-INTERNAL mode, we only deal with the current frame // if (cmode_d == FRAME_INTERNAL) { return 0; } // for a right-aligned window, there is no leading pad // if (alignment_d == LEFT) { return 0; } // for a right-aligned window, we need to compute the overlap // float overlap = (duration_d - frame_dur_d) / frame_dur_d; if (alignment_d == RIGHT) { return (long)Integral::ceil(overlap); } // for a center-aligned window, we need to compute the overlap // else if (alignment_d == CENTER) { return (long)Integral::ceil(overlap / 2); } // else: exit ungracefully // else { return Error::handle(name(), L"getTrailingPad", ERR_PRM, __FILE__, __LINE__); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -