// file: $isip/class/algo/FourierTransform/FourierTransform.h // version: $Id: FourierTransform.h 8311 2002-07-08 20:41:34Z parihar $ // // make sure definitions are only made once // #ifndef ISIP_FOURIER_TRANSFORM #define ISIP_FOURIER_TRANSFORM // isip include files // #ifndef ISIP_ALGORITHM_BASE #include #endif #ifndef ISIP_VECTORFLOAT #include #endif #ifndef ISIP_LONG #include #endif #ifndef ISIP_MEMORY_MANAGER #include #endif // FourierTransform: a class to compute a fourier transform // class FourierTransform : public AlgorithmBase { //--------------------------------------------------------------------------- // // public constants // //--------------------------------------------------------------------------- public: // define the class name // static const String CLASS_NAME; //---------------------------------------- // // other important constants // //---------------------------------------- // define algorithm choices // enum ALGORITHM { DFT = 0, FFT, DCT, DEF_ALGORITHM = FFT }; // define implementation choices // enum IMPLEMENTATION { CONVENTIONAL = 0, TRIGONOMETRIC, SPLIT_RADIX, RADIX_2, RADIX_4, FAST_HARTLEY, QF, DITF, TYPE_I, TYPE_II, TYPE_III, TYPE_IV, DEF_IMPLEMENTATION = SPLIT_RADIX}; // define algorithm choices // enum DIRECTION { FORWARD = 0, INVERSE, DEF_DIRECTION = FORWARD }; // define algorithm output mode // enum OTYPE { FULL = 0, SYMMETRIC, DEF_OTYPE = FULL }; // define algorithm resolution // enum RESOLUTION { AUTO = 0, FIXED, DEF_RESOLUTION = AUTO }; // define normalization choices // enum NORM { NONE = 0, UNIT_ENERGY, DEF_NORM = NONE }; // define static NameMap objects // static const NameMap ALGO_MAP; static const NameMap IMPL_MAP; static const NameMap DIRE_MAP; static const NameMap OUTM_MAP; static const NameMap RESO_MAP; static const NameMap NORM_MAP; //---------------------------------------- // // i/o related constants // //---------------------------------------- static const String DEF_PARAM; static const String PARAM_ALGORITHM; static const String PARAM_IMPLEMENTATION; static const String PARAM_DIRECTION; static const String PARAM_OTYPE; static const String PARAM_RESOLUTION; static const String PARAM_INPUT_LEN; static const String PARAM_OUTPUT_LEN; static const String PARAM_ORDER; static const String PARAM_NORMALIZATION; //---------------------------------------- // // default values and arguments // //---------------------------------------- // define the default fast fourier transform // static const IMPLEMENTATION DEF_FFT = SPLIT_RADIX; // define the default order of the fourier transform and i/o length // static const int32 DEF_LENGTH = -1; static const int32 DEF_ORDER = 1024; // define default argument(s) // static const AlgorithmData::COEF_TYPE DEF_COEF_TYPE = AlgorithmData::SIGNAL; //---------------------------------------- // // error codes // //---------------------------------------- static const int32 ERR = 70800; static const int32 ERR_INIT = 70801; static const int32 ERR_OUTLEN = 70802; static const int32 ERR_OUTTYP = 70803; //--------------------------------------------------------------------------- // // protected data // //--------------------------------------------------------------------------- protected: // parameters related to the algorithm specification // ALGORITHM algorithm_d; // algorithm type IMPLEMENTATION implementation_d; // implementation type DIRECTION direction_d; // direction type OTYPE otype_d; // FFT and DFT output type RESOLUTION resolution_d; // resolution type NORM normalization_d; // normalization name Long ilen_d; // user specified input length Long olen_d; // user specified output length Long order_d; // FFT transform order // parameters related to fourier transform computation // VectorFloat wd_real_d; VectorFloat wd_imag_d; VectorFloat tempd_d; // parameters storing implementation type and transform order used last time // IMPLEMENTATION prev_implementation_d; Long prev_order_d; // parameters related to the Decimation In Time Frequency (DITF) // transformation // VectorFloat ditf_trans_factor_indices_d; VectorFloat ditf_indices_d; // parameters related to the Quick Fourier (QF) transformation // VectorFloat qf_comp_real_coeff_d; VectorFloat qf_comp_imag_coeff_d; VectorFloat qf_comp_temp_d; // workspace related pointers for Quick Fourier (QF) transformation // VectorFloat qf_ws_d; // workspace int32 qf_sc_d; // secant table addr. int32 qf_nc_d; // current QFT length int32 qf_ic_d; // current secant inc. int32 qf_mc_d; // current output pruning int32 qf_nn_d; // pruned QFT input length int32 qf_mm_d; // pruned QFT output length int32 qf_ii_d; // current QFT recursion level int32 qf_input_d; // dct/dst calling arguments int32 qf_output_d; // dct/dst calling arguments // static memory manager // static MemoryManager mgr_d; //--------------------------------------------------------------------------- // // required public methods // //--------------------------------------------------------------------------- public: // method: name // static const String& name() { return CLASS_NAME; } // other static methods // static bool8 diagnose(Integral::DEBUG debug_level); // method: setDebug // these methods are inherited from the AlgorithmBase class // other debug methods // bool8 debug(const unichar* msg) const; // method: destructor // ~FourierTransform() {} // method: default constructor // FourierTransform(ALGORITHM algorithm = DEF_ALGORITHM); // method: copy constructor // FourierTransform(const FourierTransform& arg) { assign(arg); } // assign methods // bool8 assign(const FourierTransform& arg); // method: operator= // FourierTransform& operator= (const FourierTransform& arg) { assign(arg); return *this; } // i/o methods // int32 sofSize() const; bool8 read(Sof& sof, int32 tag, const String& name = CLASS_NAME); bool8 write(Sof& sof, int32 tag, const String& name = CLASS_NAME) const; bool8 readData(Sof& sof, const String& pname = DEF_PARAM, int32 size = SofParser::FULL_OBJECT, bool8 param = true, bool8 nested = false); bool8 writeData(Sof& sof, const String& pname = DEF_PARAM) const; // equality methods // bool8 eq(const FourierTransform& arg) const; // method: new // static void* operator new(size_t size) { return mgr_d.get(); } // method: new[] // static void* operator new[](size_t size) { return mgr_d.getBlock(size); } // method: delete // static void operator delete(void* ptr) { mgr_d.release(ptr); } // method: delete[] // static void operator delete[](void* ptr) { mgr_d.releaseBlock(ptr); } // method: setGrowSize // static bool8 setGrowSize(int32 grow_size) { return mgr_d.setGrow(grow_size); } // other memory management methods // bool8 clear(Integral::CMODE ctype = Integral::DEF_CMODE); //--------------------------------------------------------------------------- // // class-specific public methods // set methods // //--------------------------------------------------------------------------- // method: setAlgorithm // bool8 setAlgorithm(const ALGORITHM algorithm) { if (algorithm_d != algorithm) { is_valid_d = false; } algorithm_d = algorithm; return true; } // method: setImplementation // bool8 setImplementation(const IMPLEMENTATION implementation) { implementation_d = implementation; return true; } // method: setDirection // bool8 setDirection(const DIRECTION direction) { direction_d = direction; return true; } // method: setOutputType // bool8 setOutputType(const OTYPE otype) { otype_d = otype; return true; } // method: setResolution // bool8 setResolution(const RESOLUTION arg) { resolution_d = arg; return true; } // method: setInputLength // bool8 setInputLength(const int32 ilen = DEF_LENGTH) { ilen_d = ilen; return true; } // method: setOutputLength // bool8 setOutputLength(int32 olen = DEF_LENGTH) { olen_d = olen; return true; } // method: setOrder // bool8 setOrder(int32 order) { order_d = order; resolution_d = FIXED; is_valid_d = false; return true; } // method: setNormalization // bool8 setNormalization(NORM normalization) { normalization_d = normalization; return true; } // method: set // bool8 set(ALGORITHM algorithm = DFT, IMPLEMENTATION implementation = CONVENTIONAL, DIRECTION direction = FORWARD, OTYPE otype = FULL, RESOLUTION resolution = AUTO, int32 order = DEF_ORDER, NORM normalization = DEF_NORM) { setAlgorithm(algorithm); setImplementation(implementation); setDirection(direction); setOutputType(otype); setResolution(resolution); if (resolution == FIXED) setOrder(order); setNormalization(normalization); return true; } //--------------------------------------------------------------------------- // // class-specific public methods // get methods // //--------------------------------------------------------------------------- // method: getAlgorithm // ALGORITHM getAlgorithm() const { return algorithm_d; } // method: getImplementation // IMPLEMENTATION getImplementation() const { return implementation_d; } // method: getDirection // DIRECTION getDirection() const { return direction_d; } // method: getOutputType // OTYPE getOutputType() const { return otype_d; } // method: getResolution // RESOLUTION getResolution() const { return resolution_d; } // method: getInputLength // int32 getInputLength() const { return ilen_d; } // method: getOutputLength // int32 getOutputLength() const { return olen_d; } // method: getOrder // int32 getOrder() const { return order_d; } // method: getNormalization // NORM getNormalization() const { return normalization_d; } // method: get // bool8 get(ALGORITHM& algorithm, IMPLEMENTATION& implementation, DIRECTION& direction, OTYPE& otype, RESOLUTION& resolution, int32& order, NORM& normalization) const { algorithm = algorithm_d; implementation = implementation_d; direction = direction_d; resolution = resolution_d; order = order_d; normalization = normalization_d; return true; } //--------------------------------------------------------------------------- // // class-specific public methods: // computational methods // // the first two methods use a conservative approach for computing the // fourier transform. if the chosen fourier transform algorithm supports // computation on a vector the length of the input vector then that // algorithm is used, otherwise a discrete fourier transform is used. // // the second set of methods are more aggressive in following the user's // desires. if the input vector length is less than the specified // transform order, the input vector is zero-padded up to the length of // the specified "required_order". if the input vector is greater than the // specified order, then only the elements up to the specified // required order are used (i.e. the input is truncated). // // note that these methods do not alter the input vector. i.e. the user is // assured that the input vector after the call to compute() will be no // different than the input vector they passed in. // //--------------------------------------------------------------------------- // single-channel compute methods // bool8 compute(VectorComplexFloat& output, const VectorFloat& input, AlgorithmData::COEF_TYPE input_coef_type = DEF_COEF_TYPE, int32 chan = DEF_CHANNEL_INDEX); bool8 compute(VectorFloat& output, const VectorComplexFloat& input, AlgorithmData::COEF_TYPE input_coef_type = AlgorithmData::SPECTRUM, int32 chan = DEF_CHANNEL_INDEX); bool8 compute(VectorComplexFloat& output, const VectorComplexFloat& input, AlgorithmData::COEF_TYPE input_coef_type = DEF_COEF_TYPE, int32 chan = DEF_CHANNEL_INDEX); bool8 compute(VectorFloat& output, const VectorFloat& input, AlgorithmData::COEF_TYPE input_coef_type = DEF_COEF_TYPE, int32 chan = DEF_CHANNEL_INDEX); //--------------------------------------------------------------------------- // // class-specific public methods: // public methods required by the AlgorithmBase interface contract // //--------------------------------------------------------------------------- // assign method // bool8 assign(const AlgorithmBase& arg); // equality method // bool8 eq(const AlgorithmBase& arg) const; // method: className // const String& className() const { return CLASS_NAME; } // apply method // bool8 apply(Vector& output, const Vector< CircularBuffer >& input); // method to set the parser // bool8 setParser(SofParser* parser); //--------------------------------------------------------------------------- // // private methods // //--------------------------------------------------------------------------- private: // common i/o methods // bool8 readDataCommon(Sof& sof, const String& pname, int32 size, bool8 param, bool8 nested); bool8 writeDataCommon(Sof& sof, const String& pname) const; // miscellaneous math methods // static bool8 isPower(int32& exponent, int32 base, int32 value); // algorithm checking methods: // check the order of the algorithm and assign a default algorithm // if the chosen algorithm does not support the provided order // bool8 validateImplementation(); // algorithm-specific computation methods: FORWARD // bool8 computeForward(VectorComplexFloat& output, const VectorFloat& input); bool8 computeForward(VectorComplexFloat& output, const VectorComplexFloat& input); bool8 computeForward(VectorFloat& output, const VectorFloat& input); // algorithm-specific computation methods: INVERSE // bool8 computeInverse(VectorComplexFloat& output, const VectorComplexFloat& input); bool8 computeInverse(VectorFloat& output, const VectorComplexFloat& input); bool8 computeInverse(VectorFloat& output, const VectorFloat& input); bool8 computeInverse(VectorComplexFloat& output, const VectorFloat& input); // algorithm-specific methods: DFT // the init methods are called to set up the lookup tables for each // algorithm as needed. the real and complex computation methods // generate fourier transform coefficients for real and complex input // respectively. // bool8 dfInit(int32 order); bool8 dfReal(VectorFloat& output, const VectorFloat& input); bool8 dfComplex(VectorFloat& output, const VectorFloat& input); // algorithm-specific methods: TRIGONOMETRIC // bool8 triInit(int32 order); bool8 triReal(VectorFloat& output, const VectorFloat& input); bool8 triComplex(VectorFloat& output, const VectorFloat& input); // algorithm-specific methods: SPLIT_RADIX // bool8 srInit(int32 order); bool8 srReal(VectorFloat& output, const VectorFloat& input); bool8 srComplex(VectorFloat& output, const VectorFloat& input); // algorithm-specific methods: RAD_2 // bool8 rad2Init(int32 order); bool8 rad2Real(VectorFloat& output, const VectorFloat& input); bool8 rad2Complex(VectorFloat& output, const VectorFloat& input); // algorithm-specific methods: RAD_4 // bool8 rad4Init(int32 order); bool8 rad4Real(VectorFloat& output, const VectorFloat& input); bool8 rad4Complex(VectorFloat& output, const VectorFloat& input); // algorithm-specific methods: FAST_HARTLEY // bool8 fhInit(int32 order); bool8 fhReal(VectorFloat& output, const VectorFloat& input, bool8 isReal = true); bool8 fhComplex(VectorFloat& output, const VectorFloat& input); // algorithm-specific methods: QFT // bool8 qfInit(int32 order); bool8 qfReal(VectorFloat& output, const VectorFloat& input); bool8 qfComplex(VectorFloat& output, const VectorFloat& input); // algorithm-specific methods: DITF // bool8 ditfInit(int32 order); bool8 ditfReal(VectorFloat& output, const VectorFloat& input); bool8 ditfComplex(VectorFloat& output, const VectorFloat& input); // algorithm-specific methods: DCT TYPE_I // bool8 dct1Init(int32 order); bool8 dct1Real(VectorFloat& output, const VectorFloat& input); bool8 dct1Complex(VectorFloat& output, const VectorFloat& input); // algorithm-specific methods: DCT TYPE_II // bool8 dct2Init(int32 order); bool8 dct2Real(VectorFloat& output, const VectorFloat& input); bool8 dct2Complex(VectorFloat& output, const VectorFloat& input); // algorithm-specific methods: DCT TYPE_III // bool8 dct3Init(int32 order); bool8 dct3Real(VectorFloat& output, const VectorFloat& input); bool8 dct3Complex(VectorFloat& output, const VectorFloat& input); // algorithm-specific methods: DCT TYPE_IV // bool8 dct4Init(int32 order); bool8 dct4Real(VectorFloat& output, const VectorFloat& input); bool8 dct4Complex(VectorFloat& output, const VectorFloat& input); // miscellaneous DCT/DST methods // bool8 dct_real_cc(VectorFloat& output, const VectorFloat& input); bool8 dst_real_cc(VectorFloat& output, const VectorFloat& input); }; // end of include file // #endif