📄 win_05.cc
字号:
// file: $isip/class/algo/Window/win_05.cc// version: $Id: win_05.cc,v 1.22 2002/05/31 21:57:33 picone Exp $//// isip include files//#include "Window.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 Window::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); // 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 &= compute(output_a(c).makeVectorFloat(), input_a(c), input_a(c)(0).getCoefType(), c); // set the coefficient type for the output // output_a(c).setCoefType(input_a(c)(0).getCoefType()); } // finish the debugging output // displayFinish(this); // exit gracefully // return res;}// method: compute//// arguments:// VectorFloat& vector_out: (output) operand// const VectorFloat& vector_in: (input) operand// 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 containing status//// this method applies the specified window on the input vector//boolean Window::compute(VectorFloat& vector_out_a, const VectorFloat& vector_in_a, AlgorithmData::COEF_TYPE coef_type_a, long channel_index_a) { // declare local variables // boolean status = false; // check whether we need to initialize // if (!is_valid_d) { init(); } // algorithm: *all* standard algorithms // if ((algorithm_d == RECTANGULAR) || (algorithm_d == BARTLETT) || (algorithm_d == BLACKMAN) || (algorithm_d == DOLPH_CHEBYSHEV) || (algorithm_d == GAUSSIAN) || (algorithm_d == HAMMING) || (algorithm_d == HANNING) || (algorithm_d == KAISER) || (algorithm_d == LIFTER) || (algorithm_d == CUSTOM)) { status = computeCommon(vector_out_a, vector_in_a); } // error: unknown algorithm // else { status = Error::handle(name(), L"compute", ERR_UNKALG, __FILE__, __LINE__); } // possibly display the data // display(vector_out_a, vector_in_a, name()); // exit gracefully // return status;}// method: compute//// arguments:// VectorComplexFloat& vector_out: (output) operand// const VectorComplexFloat& vector_in: (input) operand// 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 containing status//// this method applies the specified window on the input vector//boolean Window::compute(VectorComplexFloat& vector_out_a, const VectorComplexFloat& vector_in_a, AlgorithmData::COEF_TYPE coef_type_a, long channel_index_a) { // declare local variables // boolean status = false; // check whether we need to initialize // if (!is_valid_d) { init(); } // algorithm: *all* standard algorithms // if ((algorithm_d == RECTANGULAR) || (algorithm_d == BARTLETT) || (algorithm_d == BLACKMAN) || (algorithm_d == DOLPH_CHEBYSHEV) || (algorithm_d == GAUSSIAN) || (algorithm_d == HAMMING) || (algorithm_d == HANNING) || (algorithm_d == KAISER) || (algorithm_d == LIFTER) || (algorithm_d == CUSTOM)) { status = computeCommon(vector_out_a, vector_in_a); } // error: unknown algorithm // else { status = Error::handle(name(), L"compute", ERR_UNKALG, __FILE__, __LINE__); } // possibly display the data // display(vector_out_a, vector_in_a, name()); // exit gracefully // return status;}// method: compute//// arguments:// VectorFloat& output: (output) output data// const CircularBuffer<AlgorithmData>& input: (input) input data// 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 containing status//// this method applies the specified window on the input channel//boolean Window::compute(VectorFloat& output_a, const CircularBuffer<AlgorithmData>& input_a, AlgorithmData::COEF_TYPE coef_type_a, long channel_index_a) { // for FRAME_INTERNAL mode, we just process what data we have // if (cmode_d == FRAME_INTERNAL) { return compute(output_a, input_a(0).getVectorFloat(), coef_type_a, channel_index_a); } double win_nsamp = duration_d * sample_freq_d; double frame_nsamp = frame_dur_d * sample_freq_d; if (win_nsamp < frame_nsamp) { VectorFloat buf; if (alignment_d == LEFT) { // because window size is smaller than frame size, just moving // the specified number of elements via the move method // buf.move(input_a(0).getVectorFloat(), (long)Integral::round(win_nsamp), 0, 0); // apply the window function // return compute(output_a, buf, coef_type_a, channel_index_a); } else if (alignment_d == RIGHT) { // because window size is smaller than frame size, just moving // the specified number of elements via the move method // buf.move(input_a(0).getVectorFloat(), (long)Integral::round(win_nsamp), (long)Integral::round(frame_nsamp - win_nsamp), 0); // apply the window function // return compute(output_a, buf, coef_type_a, channel_index_a); } else if (alignment_d == CENTER) { // moving equally forward and backward // // we will copy the middle (current) frame no matter what, so // subtract it out from the totals. we will use floor for the // left calculation which will bias us by at most half a sample // into the past leaving the total number of samples unchanged. // long left_nsamp = (long)Integral::floor(frame_nsamp / 2.0 - win_nsamp / 2.0 + 0.0001); buf.move(input_a(0).getVectorFloat(), (long)Integral::round(win_nsamp), left_nsamp, 0); // apply the window function // return compute(output_a, buf, coef_type_a, channel_index_a); } // error // return Error::handle(name(), L"compute", Error::NOT_IMPLEM, __FILE__, __LINE__); } // make sure there is enough data // if ((input_a.getNumForward() < getLeadingPad()) || (input_a.getNumBackward() < getTrailingPad())) { return Error::handle(name(), L"compute", ERR, __FILE__, __LINE__); } // if windown size is almost equal to frame size using FRAME_INTERNAL // mode // if (Integral::almostEqual(win_nsamp, frame_nsamp)) { return compute(output_a, input_a(0).getVectorFloat(), coef_type_a, channel_index_a); } VectorFloat buf; if (alignment_d == LEFT) { long frame = 0; double num_left = win_nsamp; while (num_left > 0) { // while there are still full frames to copy, use concat // if (num_left > frame_nsamp) { buf.concat(input_a(frame).getVectorFloat()); num_left -= frame_nsamp; } // for the last frame only copy over the specified number of // elements via the move method // else { buf.move(input_a(frame).getVectorFloat(), (long)Integral::round(num_left), 0, buf.length()); num_left = 0; } frame++; } // apply the window function // return compute(output_a, buf, coef_type_a, channel_index_a); } else if (alignment_d == RIGHT) { Double num_frames = win_nsamp / frame_nsamp; long frame = (long)Integral::ceil(num_frames); long index = frame - 1; // this is the number of samples not included from the first frame // long first_offset = (long)Integral::round(frame * frame_nsamp - win_nsamp); long first_nelem = (long)Integral::round(frame_nsamp - first_offset); double num_left = win_nsamp; boolean initialization = true; while (num_left > 0) { // for the first frame we probably don't copy all samples, just // a right-aligned pre-specified number of samples. // if (initialization) { buf.move(input_a(-index).getVectorFloat(), first_nelem, first_offset, 0); num_left -= first_nelem; initialization = false; } // for all other frames we copy the entire frame // else { buf.concat(input_a(-index).getVectorFloat()); num_left -= frame_nsamp; } index--; } // apply the window function // return compute(output_a, buf, coef_type_a, channel_index_a); } else if (alignment_d == CENTER) { long num_frames = (long)Integral::ceil(win_nsamp / frame_nsamp); // case 0: a window is less than or equal to the frame size, only // copy from one the middle of the current frame // if (num_frames == 1) { long start_offset = (long)Integral::floor((frame_nsamp / 2.0) - (win_nsamp / 2.0)); buf.move(input_a(0).getVectorFloat(), (long)Integral::ceil(win_nsamp), start_offset, 0); } // else we must span frames -- moving equally forward and backward // else { // we will copy the middle (current) frame no matter what, so // subtract it out from the totals. we will use floor for the // left calculation which will bias us by at most half a sample // into the past leaving the total number of samples unchanged. // long left_nsamp = (long)Integral::floor(win_nsamp / 2.0 - frame_nsamp / 2.0); long right_nsamp = (long)Integral::ceil(win_nsamp / 2.0 - frame_nsamp / 2.0); long first_frame = (long)Integral::ceil(left_nsamp / frame_nsamp); long first_offset = first_frame * (long)Integral::round(frame_nsamp) - left_nsamp; long first_nelem = (long)Integral::round(frame_nsamp) - first_offset; for (long index = first_frame; left_nsamp > 0; ) { if (index == first_frame) { buf.move(input_a(-index).getVectorFloat(), first_nelem, first_offset, 0); left_nsamp -= first_nelem; } else { buf.concat(input_a(-index).getVectorFloat()); left_nsamp -= (long)Integral::round(frame_nsamp); } } // copy the middle frame // buf.concat(input_a(0).getVectorFloat()); long index = 1; // now copy the future frames // while (right_nsamp > 0) { // while there are still full frames to copy, use concat // if (right_nsamp > frame_nsamp) { buf.concat(input_a(index).getVectorFloat()); right_nsamp -= (long)Integral::round(frame_nsamp); } // for the last frame only copy over the specified number of // elements via the move method // else { buf.move(input_a(index).getVectorFloat(), (long)Integral::ceil(right_nsamp), 0, buf.length()); right_nsamp = 0; } index++; } } // apply the window function // return compute(output_a, buf, coef_type_a, channel_index_a); } // error // return Error::handle(name(), L"compute", Error::NOT_IMPLEM, __FILE__, __LINE__);}// method: computeCommon//// arguments:// VectorFloat& vector_out: (output) operand// const VectorFloat& vector_in: (input) operand//// return: a boolean value containing status//// this method applies the window on the input vector and is called by the// public compute method//boolean Window::computeCommon(VectorFloat& vector_out_a, const VectorFloat& vector_in_a) { // set the size of the window // long len = vector_in_a.length(); setSize(len); vector_out_a.setLength(len); // if window is not set then initialize the window // if (!is_valid_d) { init(); } // now apply // for (long i = 0; i < len; i++) { vector_out_a(i) = data_d(i) * vector_in_a(i); } // exit gracefully // return true;}// method: computeCommon//// arguments:// VectorComplexFloat& vector_out: (output) operand// const VectorComplexFloat& vector_in: (input) operand//// return: a boolean value containing status//// this method applies the window on the input vector and is called by the// public compute method//boolean Window::computeCommon(VectorComplexFloat& vector_out_a, const VectorComplexFloat& vector_in_a) { // set the size of the window // long len = vector_in_a.length(); setSize(len); vector_out_a.setLength(len); // if window is not set then initialize the window // if (!is_valid_d) { init(); } // now apply // for (long i = 0; i < len; i++) { vector_out_a(i) = complexfloat((float)data_d(i) * (float)vector_in_a(i).real(), (float)data_d(i) * (float)vector_in_a(i).imag()); } // exit gracefully // return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -