// file: $isip/class/algo/Window/win_00.cc // version: $Id: win_00.cc 8197 2002-06-12 16:30:49Z gao $ // // isip include files // #include "Window.h" #include "Bessel.h" #include "Chebyshev.h" //------------------------------------------------------------------------ // // required public methods // //----------------------------------------------------------------------- // method: assign // // arguments: // const Window& arg: (input) object to be assigned // // return: a bool8 value indicating status // // this method assigns the input object to the current object // bool8 Window::assign(const Window& arg_a) { // assign protected data from argument // algorithm_d = arg_a.algorithm_d; alignment_d = arg_a.alignment_d; normalization_d = arg_a.normalization_d; duration_d = arg_a.duration_d; cmode_d = arg_a.cmode_d; constants_d.assign(arg_a.constants_d); data_d.assign(arg_a.data_d); // set initialization flag // is_valid_d = arg_a.is_valid_d; // exit gracefully // return AlgorithmBase::assign(arg_a); } // method: eq // // arguments: // const Window& arg: (input) object to be compared // // return: a bool8 value indicating status // // this method checks whether the current object is identical to the // input object // bool8 Window::eq(const Window& arg_a) const { // compare parameters related to algorithm choices // if ((algorithm_d != arg_a.algorithm_d) || (alignment_d != arg_a.alignment_d) || (normalization_d != arg_a.normalization_d) || (duration_d != arg_a.duration_d) || (cmode_d != arg_a.cmode_d)) { return false; } // for non-CUSTOM, compare the parameters of the function // else if ((algorithm_d != CUSTOM) && (!constants_d.almostEqual(arg_a.constants_d))) { return false; } // for CUSTOM, compare the functions directly // else if ((algorithm_d == CUSTOM) && (!data_d.almostEqual(arg_a.data_d))) { return false; } // exit gracefully by checking the base class // return AlgorithmBase::eq(arg_a); } // method: clear // // arguments: // Integral::CMODE ctype: (input) clear mode // // return: a bool8 value indicating status // // this method resets the data members to the default values // bool8 Window::clear(Integral::CMODE ctype_a) { // reset the data members unless the mode is RETAIN // if (ctype_a != Integral::RETAIN) { // clear the window design parameters // algorithm_d = DEF_ALGORITHM; alignment_d = DEF_ALIGNMENT; normalization_d = DEF_NORMALIZATION; duration_d = DEF_DURATION; cmode_d = DEF_CMODE; // clear the vector data // constants_d.clear(ctype_a); data_d.clear(ctype_a); } // in RETAIN mode, clear the data only if the algorithm is not CUSTOM // else if (algorithm_d != CUSTOM) { data_d.clear(ctype_a); } // set the initialization flag // is_valid_d = false; // call the base clear method // return AlgorithmBase::clear(ctype_a); } //--------------------------------------------------------------------------- // // class-specific public methods: // public methods required by the AlgorithmBase interface contract // //--------------------------------------------------------------------------- // method: assign // // arguments: // const AlgorithmBase& arg: (input) object to be assigned // // return: a bool8 value indicating status // // this method assigns the input algorithm object to the current // Window object // bool8 Window::assign(const AlgorithmBase& arg_a) { // case: input is an Window object // if (typeid(arg_a) == typeid(Window)) { return assign((Window&)arg_a); } // case: other // if the input algorithm object is not an Window object, error // else { return Error::handle(name(), L"assign", Error::ARG, __FILE__, __LINE__); } } // method: eq // // arguments: // const AlgorithmBase& arg: (input) object to be compared // // return: a bool8 value indicating status // // this method checks whether the current Window object is identical // to the input algorithm object // bool8 Window::eq(const AlgorithmBase& arg_a) const { // case: input is an Window object // if (typeid(arg_a) == typeid(Window)) { return eq((Window&)arg_a); } // case: other // if the input algorithm object is not an Window object, return // an error // else { return Error::handle(name(), L"eq", Error::ARG, __FILE__, __LINE__); } } // method: init // // arguments: none // // return: a bool8 value indicating status // // to initialize this object, either the // or the duration and sample frequency must be set, // or the length. // // see the header file for references for the algorithms. // bool8 Window::init() { // check for a valid mode // int32 N; if (cmode_d == FRAME_INTERNAL) { N = data_d.length(); } else if (cmode_d == CROSS_FRAME) { N = (int32)Integral::round(duration_d * sample_freq_d); } else { return Error::handle(name(), L"init", ERR_UNKIMP, __FILE__, __LINE__); } if (N <= 0) { return false; } // for all algorithms, we need to size data_d, because this is where // the window function will be stored // data_d.setLength(N); // algorithm: RECTANGULAR // if (algorithm_d == RECTANGULAR) { // assign the constants if necessary // if (constants_d.length() == 0) { constants_d.assign(DEF_RECT_CONSTANTS); } else if (constants_d.length() != 1) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } // generate the window // if (!generateRectangular(data_d, constants_d, N)) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } } // algorithm: BARTLETT // else if (algorithm_d == BARTLETT) { // assign the constants if necessary // if (constants_d.length() == 0) { constants_d.assign(DEF_BART_CONSTANTS); } else if (constants_d.length() != 1) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } // generate the window // if (!generateBartlett(data_d, constants_d, N)) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } } // Algorithm: BLACKMAN // else if (algorithm_d == BLACKMAN) { // assign the constants if necessary // if (constants_d.length() == 0) { constants_d.assign(DEF_BLCK_CONSTANTS); } else if (constants_d.length() != 3) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } // generate the window // if (!generateBlackman(data_d, constants_d, N)) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } } // algorithm: DOLPH_CHEBYSHEV // else if (algorithm_d == DOLPH_CHEBYSHEV) { // assign the constants if necessary // if (constants_d.length() == 0) { constants_d.assign(DEF_DCHB_CONSTANTS); } else if (constants_d.length() != 2) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } // generate the window // if (!generateDolphChebyshev(data_d, constants_d, N)) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } } else if (algorithm_d == GAUSSIAN) { // assign the constants if necessary // if (constants_d.length() == 0) { constants_d.assign(DEF_GAUS_CONSTANTS); } else if (constants_d.length() != 2) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } // generate the window // if (!generateGaussian(data_d, constants_d, N)) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } } // algorithm: HAMMING // else if (algorithm_d == HAMMING) { // assign the constants if necessary // if (constants_d.length() == 0) { constants_d.assign(DEF_HAMM_CONSTANTS); } else if (constants_d.length() != 2) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } // generate the window // if (!generateGeneralizedHanning(data_d, constants_d, N)) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } } else if (algorithm_d == HANNING) { // assign the constants if necessary // if (constants_d.length() == 0) { constants_d.assign(DEF_HANN_CONSTANTS); } else if (constants_d.length() != 2) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } // generate the window // if (!generateGeneralizedHanning(data_d, constants_d, N)) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } } // algorithm: KAISER // else if (algorithm_d == KAISER) { // assign the constants if necessary // if (constants_d.length() == 0) { constants_d.assign(DEF_KAIS_CONSTANTS); } else if (constants_d.length() != 2) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } // generate the window // if (!generateKaiser(data_d, constants_d, N)) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } } // algorithm: LIFTER // else if (algorithm_d == LIFTER) { // assign the constants if necessary // if (constants_d.length() == 0) { constants_d.assign(DEF_LIFT_CONSTANTS); } else if (constants_d.length() != 3) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } // generate the window // if (!generateLifter(data_d, constants_d, N)) { return Error::handle(name(), L"init", ERR_PRM, __FILE__, __LINE__); } } // algorithm: CUSTOM // needs no initialization at this point // else if (algorithm_d != CUSTOM) { return Error::handle(name(), L"init", ERR_UNKALG, __FILE__, __LINE__); } // normalize if necessary // if (normalization_d == UNIT_ENERGY) { float32 rms = data_d.rms(); if (rms <= 0.0) { return Error::handle(name(), L"init", Error::ENUM, __FILE__, __LINE__); } else { data_d.div(data_d.rms()); } } // set flag // is_valid_d = true; // exit gracefully // return true; } //----------------------------------------------------------------------------- // // we define non-integral constants in the default constructor // //----------------------------------------------------------------------------- // constants: class name // const String Window::CLASS_NAME(L"Window"); // constants: i/o related constants // const String Window::DEF_PARAM(L""); const String Window::PARAM_ALGORITHM(L"algorithm"); const String Window::PARAM_IMPLEMENTATION(L"implementation"); const String Window::PARAM_ALIGNMENT(L"alignment"); const String Window::PARAM_NORMALIZATION(L"normalization"); const String Window::PARAM_DURATION(L"duration"); const String Window::PARAM_CONSTANTS(L"constants"); const String Window::PARAM_DATA(L"data"); const String Window::PARAM_CMODE(L"compute_mode"); // constants: default constants for each window algorithm // const VectorFloat Window::DEF_RECT_CONSTANTS(L"1.0"); const VectorFloat Window::DEF_BART_CONSTANTS(L"1.0"); const VectorFloat Window::DEF_BLCK_CONSTANTS(L"1.0, 0.42, 0.50"); const VectorFloat Window::DEF_DCHB_CONSTANTS(L"1.0, 0.50"); const VectorFloat Window::DEF_GAUS_CONSTANTS(L"1.0, 0.2618"); const VectorFloat Window::DEF_HAMM_CONSTANTS(L"1.0, 0.54"); const VectorFloat Window::DEF_HANN_CONSTANTS(L"1.0, 0.50"); const VectorFloat Window::DEF_KAIS_CONSTANTS(L"1.0, 0.50"); const VectorFloat Window::DEF_LIFT_CONSTANTS(L"1.0, 22.0, 11.0"); // constants: NameMap(s) for the enumerated values // const NameMap Window::ALGO_MAP(L"RECTANGULAR, BLACKMAN, BARTLETT, DOLPH_CHEBYSHEV, GAUSSIAN, HAMMING, HANNING, KAISER, LIFTER, CUSTOM"); const NameMap Window::IMPL_MAP(L"MULTIPLICATION"); const NameMap Window::ALGN_MAP(L"CENTER, LEFT, RIGHT"); const NameMap Window::NORM_MAP(L"NONE, UNIT_ENERGY"); // static instantiations: memory manager // MemoryManager Window::mgr_d(sizeof(Window), Window::name());