size_t FirFilterDesigner::wdfirCx ( T& filtCoeff, FIRFilter::filter_type type, Real ripple, Real twNorm, Real flNorm, Real fhNorm, size_t minTaps, size_t maxTaps) { if ((type==FIRFilter::lowpass)||(type==FIRFilter::highpass)) { //design a real filter and mux the imaginary zeros in there to make it complex RealArray r; size_t ret = wdfir(r, type, ripple, twNorm, flNorm, 0, minTaps,maxTaps); muxImaginaryZeros(r, filtCoeff); return ret; } else { //create a lowpass or highpass filter and tune the filter with a complex tune to make the bandpass filter FIRFilter::filter_type inputType=FIRFilter::lowpass; if (type==FIRFilter::bandstop) inputType=FIRFilter::highpass; RealArray r; size_t ret = wdfir(r, inputType, ripple, twNorm, fabs(fhNorm-flNorm)/2.0, 0, minTaps,maxTaps); filtCoeff.resize(ret); //tune the filter outputs to the specified center frequency //the tune phase is 2*pi*fc_norm = 2*pi*((fhNorm+flNorm)/2) = pi*(fhNorm+flNorm) Real tunePhaseUpdate=M_PI*(fhNorm+flNorm); Complex phasor(cos(tunePhaseUpdate),sin(tunePhaseUpdate)); Complex tuner(phasor); for (size_t i=0; i!=ret; i++) { filtCoeff[i]=r[i]*tuner; tuner*=phasor; } return ret; } }
std::vector<std::complex<T> > getTwiddleFactors(size_t N, bool fwd, size_t Lm1Qm1 = std::numeric_limits<size_t>::max) { std::vector<std::complex<T> > factors(std::min(N, Lm1Qm1)); if(factors.size() > 0) { factors[0] = 1; if(factors.size() > 1) { // Use high-precision multiplication of phasors. typedef std::complex<long double> HighPrecComplex; long double phase = 2*3.14159265358979323846/N; HighPrecComplex phasor(cos(phase), fwd ? -sin(phase) : sin(phase)); HighPrecComplex tmp(phasor); factors[1] = tmp; for(size_t i = 2; i < factors.size(); ++i) factors[i] = tmp = tmp * phasor; } } return factors; }