123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783 |
- //$ nobt
- //$ nocpp
-
- /**
- * @file CDSPSincFilterGen.h
- *
- * @brief Sinc function-based FIR filter generator class.
- *
- * This file includes the CDSPSincFilterGen class implementation that
- * generates FIR filters.
- *
- * r8brain-free-src Copyright (c) 2013-2014 Aleksey Vaneev
- * See the "License.txt" file for license.
- */
-
- #ifndef R8B_CDSPSINCFILTERGEN_INCLUDED
- #define R8B_CDSPSINCFILTERGEN_INCLUDED
-
- #include "r8bbase.h"
-
- namespace r8b
- {
-
- /**
- * @brief Sinc function-based FIR filter generator class.
- *
- * Structure that holds state used to perform generation of sinc functions of
- * various types, windowed by the Blackman window by default (but the window
- * function can be changed if necessary).
- */
-
- class CDSPSincFilterGen
- {
- public:
- double Len2 = 0; ///< Required half filter kernel's length in samples (can be
- ///< a fractional value). Final physical kernel length will be
- ///< provided in the KernelLen variable. Len2 should be >= 2.
- ///<
- int KernelLen = 0; ///< Resulting length of the filter kernel, this variable
- ///< is set after the call to one of the "init" functions.
- ///<
- int fl2 = 0; ///< Internal "half kernel length" value. This value can be used
- ///< as filter's latency in samples (taps), this variable is set after
- ///< the call to one of the "init" functions.
- ///<
-
- union
- {
- struct
- {
- double Freq1; ///< Required corner circular frequency 1 [0; pi].
- ///< Used only in the generateBand() function.
- ///<
- double Freq2; ///< Required corner circular frequency 2 [0; pi].
- ///< Used only in the generateBand() function. The range
- ///< [Freq1; Freq2] defines a pass band for the generateBand()
- ///< function.
- ///<
- };
-
- struct
- {
- double FracDelay; ///< Fractional delay in the range [0; 1], used
- ///< only in the generateFrac() function. Note that the
- ///< FracDelay parameter is actually inversed. At 0.0 value it
- ///< produces 1 sample delay (with the latency equal to fl2),
- ///< at 1.0 value it produces 0 sample delay (with the latency
- ///< equal to fl2 - 1).
- ///<
- };
- };
-
- /**
- * Window function type.
- */
-
- enum EWindowFunctionType
- {
- wftCosine, ///< Generalized cosine window function. No parameters
- ///< required. The "Power" parameter is optional.
- ///<
- wftKaiser, ///< Kaiser window function. Requires the "Beta" parameter.
- ///< The "Power" parameter is optional.
- ///<
- wftGaussian, ///< Gaussian window function. Requires the "Sigma"
- ///< parameter. The "Power" parameter is optional.
- ///<
- wftVaneev ///< Vaneev window function, mainly used for short
- ///< fractional delay filters, requires 4 cosine width parameters,
- ///< plus the "Power" parameter which is mandatory.
- ///<
- };
-
- typedef double ( CDSPSincFilterGen::*CWindowFunc )(); ///< Window
- ///< calculation function pointer type.
- ///<
-
- /**
- * Function initializes *this structure for generation of a window
- * function, odd-sized.
- *
- * @param WinType Window function type.
- * @param Params Window function's parameters. If NULL, the table values
- * may be used.
- * @param UsePower "True" if the power factor should be used to raise the
- * window function. If "true", the power factor should be specified as the
- * last value in the Params array. If Params is NULL, the table or default
- * value of -1.0 (off) will be used.
- */
-
- void initWindow(const EWindowFunctionType WinType = wftCosine,
- const double* const Params = nullptr, const bool UsePower = false)
- {
- R8BASSERT(Len2 >= 2.0);
-
- fl2 = (int)floor(Len2);
- KernelLen = fl2 + fl2 + 1;
-
- setWindow(WinType, Params, UsePower, true);
- }
-
- /**
- * Function initializes *this structure for generation of band-limited
- * sinc filter kernel. The generateBand() or generateBandPow() functions
- * should be used to calculate the filter.
- *
- * @param WinType Window function type.
- * @param Params Window function's parameters. If NULL, the table values
- * may be used.
- * @param UsePower "True" if the power factor should be used to raise the
- * window function. If "true", the power factor should be specified as the
- * last value in the Params array. If Params is NULL, the table or default
- * value of -1.0 (off) will be used.
- */
-
- void initBand(const EWindowFunctionType WinType = wftCosine,
- const double* const Params = nullptr, const bool UsePower = false)
- {
- R8BASSERT(Len2 >= 2.0);
-
- fl2 = (int)floor(Len2);
- KernelLen = fl2 + fl2 + 1;
- f1.init(Freq1, 0.0);
- f2.init(Freq2, 0.0);
-
- setWindow(WinType, Params, UsePower, true);
- }
-
- /**
- * Function initializes *this structure for Hilbert transformation filter
- * calculation. Freq1 and Freq2 variables are not used.
- * The generateHilbert() function should be used to calculate the filter.
- *
- * @param WinType Window function type.
- * @param Params Window function's parameters. If NULL, the table values
- * may be used.
- * @param UsePower "True" if the power factor should be used to raise the
- * window function. If "true", the power factor should be specified as the
- * last value in the Params array. If Params is NULL, the table or default
- * value of -1.0 (off) will be used.
- */
-
- void initHilbert(const EWindowFunctionType WinType = wftCosine,
- const double* const Params = nullptr, const bool UsePower = false)
- {
- R8BASSERT(Len2 >= 2.0);
-
- fl2 = (int)floor(Len2);
- KernelLen = fl2 + fl2 + 1;
-
- setWindow(WinType, Params, UsePower, true);
- }
-
- /**
- * Function initializes *this structure for generation of full-bandwidth
- * fractional delay sinc filter kernel. Freq1 and Freq2 variables are not
- * used. The generateFrac() function should be used to calculate the
- * filter.
- *
- * @param WinType Window function type.
- * @param Params Window function's parameters. If NULL, the table values
- * may be used.
- * @param UsePower "True" if the power factor should be used to raise the
- * window function. If "true", the power factor should be specified as the
- * last value in the Params array. If Params is NULL, the table or default
- * value of -1.0 (off) will be used.
- */
-
- void initFrac(const EWindowFunctionType WinType = wftCosine,
- const double* const Params = nullptr, const bool UsePower = false)
- {
- R8BASSERT(Len2 >= 2.0);
-
- fl2 = (int)ceil(Len2);
- KernelLen = fl2 + fl2;
-
- setWindow(WinType, Params, UsePower, false, FracDelay);
- }
-
- /**
- * @return The next "Hann" window function coefficient.
- */
-
- double calcWindowHann() { return (0.5 + 0.5 * w1.generate()); }
-
- /**
- * @return The next "Hamming" window function coefficient.
- */
-
- double calcWindowHamming() { return (0.54 + 0.46 * w1.generate()); }
-
- /**
- * @return The next "Blackman" window function coefficient.
- */
-
- double calcWindowBlackman() { return (0.42 + 0.5 * w1.generate() + 0.08 * w2.generate()); }
-
- /**
- * @return The next "Nuttall" window function coefficient.
- */
-
- double calcWindowNuttall()
- {
- return (0.355768 + 0.487396 * w1.generate() +
- 0.144232 * w2.generate() + 0.012604 * w3.generate());
- }
-
- /**
- * @return The next "Blackman-Nuttall" window function coefficient.
- */
-
- double calcWindowBlackmanNuttall()
- {
- return (0.3635819 + 0.4891775 * w1.generate() +
- 0.1365995 * w2.generate() + 0.0106411 * w3.generate());
- }
-
- /**
- * @return The next "Kaiser" window function coefficient.
- */
-
- double calcWindowKaiser()
- {
- const double n = 1.0 - sqr(wn / Len2 + KaiserLen2Frac);
- wn++;
-
- if (n < 0.0) { return (0.0); }
-
- return (besselI0(KaiserBeta * sqrt(n)) / KaiserDiv);
- }
-
- /**
- * @return The next "Gaussian" window function coefficient.
- */
-
- double calcWindowGaussian()
- {
- const double f = exp(-0.5 * sqr(wn / GaussianSigma +
- GaussianSigmaFrac));
-
- wn++;
-
- return (f);
- }
-
- /**
- * @return The next "Vaneev" windowing function coefficient, for use with
- * the fractional delay filters.
- */
-
- double calcWindowVaneev()
- {
- const double v1 = 0.5 + 0.5 * w1.generate();
- const double v2 = 0.5 + 0.5 * w2.generate();
- const double v3 = 0.5 + 0.5 * w3.generate();
- const double v4 = 0.5 + 0.5 * w4.generate();
-
- return (v1 * sqr(v2) * sqr(sqr(v3)) * sqr(sqr(sqr(v4))));
- }
-
- /**
- * Function calculates window function only.
- *
- * @param[out] op Output buffer, length = KernelLen.
- * @param wfunc Window calculation function to use.
- */
-
- template <class T>
- void generateWindow(T* op,
- CWindowFunc wfunc = &CDSPSincFilterGen::calcWindowBlackman)
- {
- op += fl2;
- T* op2 = op;
-
- int l = fl2;
-
- if (Power < 0.0)
- {
- *op = (*this.*wfunc)();
-
- while (l > 0)
- {
- const double v = (*this.*wfunc)();
-
- ++op;
- --op2;
- *op = v;
- *op2 = v;
- l--;
- }
- }
- else
- {
- *op = pows((*this.*wfunc)(), Power);
-
- while (l > 0)
- {
- const double v = pows((*this.*wfunc)(), Power);
-
- ++op;
- --op2;
- *op = v;
- *op2 = v;
- l--;
- }
- }
- }
-
- /**
- * Function calculates band-limited windowed sinc function-based filter
- * kernel.
- *
- * @param[out] op Output buffer, length = KernelLen.
- * @param wfunc Window calculation function to use.
- */
-
- template <class T>
- void generateBand(T* op,
- CWindowFunc wfunc = &CDSPSincFilterGen::calcWindowBlackman)
- {
- op += fl2;
- T* op2 = op;
- f1.generate();
- f2.generate();
- int t = 1;
-
- if (Power < 0.0)
- {
- *op = (Freq2 - Freq1) * (*this.*wfunc)() / M_PI;
-
- while (t <= fl2)
- {
- const double v = (f2.generate() - f1.generate()) *
- (*this.*wfunc)() / t / M_PI;
-
- ++op;
- --op2;
- *op = v;
- *op2 = v;
- t++;
- }
- }
- else
- {
- *op = (Freq2 - Freq1) * pows((*this.*wfunc)(), Power) / M_PI;
-
- while (t <= fl2)
- {
- const double v = (f2.generate() - f1.generate()) *
- pows((*this.*wfunc)(), Power) / t / M_PI;
-
- ++op;
- --op2;
- *op = v;
- *op2 = v;
- t++;
- }
- }
- }
-
- /**
- * Function calculates windowed Hilbert transformer filter kernel.
- *
- * @param[out] op Output buffer, length = KernelLen.
- * @param wfunc Window calculation function to use.
- */
-
- template <class T>
- void generateHilbert(T* op,
- CWindowFunc wfunc = &CDSPSincFilterGen::calcWindowBlackman)
- {
- static const double fvalues[ 2 ] = { 0.0, 2.0 };
- op += fl2;
- T* op2 = op;
-
- (*this.*wfunc)();
- *op = 0.0;
-
- int t = 1;
-
- if (Power < 0.0)
- {
- while (t <= fl2)
- {
- const double v = fvalues[t & 1] *
- (*this.*wfunc)() / t / M_PI;
-
- ++op;
- --op2;
- *op = v;
- *op2 = -v;
- t++;
- }
- }
- else
- {
- while (t <= fl2)
- {
- const double v = fvalues[t & 1] *
- pows((*this.*wfunc)(), Power) / t / M_PI;
-
- ++op;
- --op2;
- *op = v;
- *op2 = -v;
- t++;
- }
- }
- }
-
- /**
- * Function calculates windowed fractional delay filter kernel.
- *
- * @param[out] op Output buffer, length = KernelLen.
- * @param wfunc Window calculation function to use.
- * @param opinc Output buffer increment, in "op" elements.
- */
-
- template <class T>
- void generateFrac(T* op,
- CWindowFunc wfunc = &CDSPSincFilterGen::calcWindowBlackman,
- const int opinc = 1)
- {
- R8BASSERT(opinc != 0);
-
- double f[ 2 ];
- f[0] = sin(FracDelay * M_PI);
- f[1] = -f[0];
-
- int t = -fl2;
-
- if (t + FracDelay < -Len2)
- {
- (*this.*wfunc)();
- *op = 0.0;
- op += opinc;
- t++;
- }
-
- int mt = (FracDelay >= 1.0 - 1e-13 && FracDelay <= 1.0 + 1e-13 ? -1 : 0);
-
- if (Power < 0.0)
- {
- while (t < mt)
- {
- *op = f[t & 1] * (*this.*wfunc)() / (t + FracDelay) /
- M_PI;
-
- op += opinc;
- t++;
- }
-
- double ut = t + FracDelay;
- *op = (fabs(ut) <= 1e-13 ? (*this.*wfunc)() : f[t & 1] * (*this.*wfunc)() / ut / M_PI);
-
- mt = fl2 - 2;
-
- while (t < mt)
- {
- op += opinc;
- t++;
- *op = f[t & 1] * (*this.*wfunc)() / (t + FracDelay) /
- M_PI;
- }
-
- op += opinc;
- t++;
- ut = t + FracDelay;
- *op = (ut > Len2 ? 0.0 : f[t & 1] * (*this.*wfunc)() / ut / M_PI);
- }
- else
- {
- while (t < mt)
- {
- *op = f[t & 1] * pows((*this.*wfunc)(), Power) /
- (t + FracDelay) / M_PI;
-
- op += opinc;
- t++;
- }
-
- double ut = t + FracDelay;
- *op = (fabs(ut) <= 1e-13 ? pows((*this.*wfunc)(), Power) : f[t & 1] * pows((*this.*wfunc)(), Power) / ut / M_PI);
-
- mt = fl2 - 2;
-
- while (t < mt)
- {
- op += opinc;
- t++;
- *op = f[t & 1] * pows((*this.*wfunc)(), Power) /
- (t + FracDelay) / M_PI;
- }
-
- op += opinc;
- t++;
- ut = t + FracDelay;
- *op = (ut > Len2 ? 0.0 : f[t & 1] * pows((*this.*wfunc)(), Power) / ut / M_PI);
- }
- }
-
- private:
- double Power = 0; ///< The power factor used to raise the window function.
- ///< Equals a negative value if the power factor should not be used.
- ///<
- CSineGen f1; ///< Sine function 1. Used in the generateBand() function.
- ///<
- CSineGen f2; ///< Sine function 2. Used in the generateBand() function.
- ///<
- int wn = 0; ///< Window function integer position. 0 - center of the window
- ///< function. This variable may not be used by some window functions.
- ///<
- CSineGen w1; ///< Cosine wave 1 for window function.
- ///<
- CSineGen w2; ///< Cosine wave 2 for window function.
- ///<
- CSineGen w3; ///< Cosine wave 3 for window function.
- ///<
- CSineGen w4; ///< Cosine wave 4 for window function.
- ///<
-
- union
- {
- struct
- {
- double KaiserBeta; // Kaiser window function's "Beta" coefficient.
- double KaiserDiv; // Kaiser window function's divisor.
- double KaiserLen2Frac; // Equals FracDelay / Len2.
- };
-
- struct
- {
- double GaussianSigma; // Gaussian window function's "Sigma" coefficient.
- double GaussianSigmaFrac; // Equals FracDelay / GaussianSigma.
- };
- };
-
- /**
- * @param FilterLen2 Half filter length in samples (taps).
- * @return The Kaiser power-raised window function parameters for the
- * specified filter length.
- */
-
- static const double* getKaiserParams(const int FilterLen2)
- {
- R8BASSERT(FilterLen2 >= 3 && FilterLen2 <= 15);
-
- static const double Coeffs[][ 2 ] = {
- { 3.41547411, 1.41275111 }, // 6 @ 51.38
- { 3.72300147, 1.75212634 }, // 8 @ 67.60
- { 4.34839223, 1.85801372 }, // 10 @ 79.86
- { 4.90860405, 1.97194591 }, // 12 @ 93.29
- { 5.17430411, 2.20609617 }, // 14 @ 106.74
- { 21.08445389, 0.59684098 }, // 16 @ 119.71
- { 9.14552738, 1.57619894 }, // 18 @ 134.53
- { 22.02344341, 0.71669064 }, // 20 @ 148.44
- { 16.41763757, 1.05884118 }, // 22 @ 164.61
- { 12.55262798, 1.51553897 }, // 24 @ 180.15
- { 9.84861210, 2.09912671 }, // 26 @ 194.15
- { 9.73150659, 2.29079494 }, // 28 @ 206.91
- { 10.42657217, 2.29183875 }, // 30 @ 218.20
- };
-
- return (Coeffs[FilterLen2 - 3]);
- }
-
- /**
- * Function initializes Kaiser window function calculation. The FracDelay
- * variable should be initialized when using this window function.
- *
- * @param Params Function parameters. If NULL, the table values will be
- * used. If not NULL, the first parameter should specify the "Beta" value.
- * @param UsePower "True" if the power factor should be used to raise the
- * window function.
- * @param IsCentered "True" if centered window should be used. This
- * parameter usually equals to "false" for fractional delay filters only.
- */
-
- void setWindowKaiser(const double* Params, const bool UsePower,
- const bool IsCentered)
- {
- wn = (IsCentered ? 0 : -fl2);
-
- if (Params == nullptr)
- {
- Params = getKaiserParams(fl2);
- KaiserBeta = Params[0];
- Power = (UsePower ? Params[1] : -1.0);
- }
- else
- {
- KaiserBeta = clampr(Params[0], 1.0, 350.0);
- Power = (UsePower ? fabs(Params[1]) : -1.0);
- }
-
- KaiserDiv = besselI0(KaiserBeta);
- KaiserLen2Frac = FracDelay / Len2;
- }
-
- /**
- * Function initializes Gaussian window function calculation. The FracDelay
- * variable should be initialized when using this window function.
- *
- * @param Params Function parameters. If NULL, the table values will be
- * used. If not NULL, the first parameter should specify the "Sigma"
- * value.
- * @param UsePower "True" if the power factor should be used to raise the
- * window function.
- * @param IsCentered "True" if centered window should be used. This
- * parameter usually equals to "false" for fractional delay filters only.
- */
-
- void setWindowGaussian(const double* Params, const bool UsePower,
- const bool IsCentered)
- {
- wn = (IsCentered ? 0 : -fl2);
-
- if (Params == nullptr)
- {
- GaussianSigma = 1.0;
- Power = -1.0;
- }
- else
- {
- GaussianSigma = clampr(fabs(Params[0]), 1e-1, 100.0);
- Power = (UsePower ? fabs(Params[1]) : -1.0);
- }
-
- GaussianSigma *= Len2;
- GaussianSigmaFrac = FracDelay / GaussianSigma;
- }
-
- /**
- * Function initializes "Vaneev" window function calculation.
- *
- * @param Params Function parameters. If NULL, the table values will be
- * used. If not NULL, the first 4 parameters should specify the cosine
- * multipliers while the fifth parameter should specify the "Power" value.
- * @param IsCentered "True" if centered window should be used. This
- * parameter usually equals to "false" for fractional delay filters only.
- */
-
- void setWindowVaneev(const double* Params, const bool IsCentered)
- {
- R8BASSERT(fl2 >= 3 && fl2 <= 15);
-
- // This set of parameters was obtained via probabilistic optimization.
- // The number after @ shows the approximate (+/- 1 dB) signal-to-noise
- // ratio for the given filter. SNR can be also decreased by using a
- // filter bank with suboptimal number of sampled fractional delay
- // filters: thus the FilterFracs should be selected with care.
-
- static const double Coeffs[][ 5 ] = {
- { 0.35926104, 0.66154037, 0.79264845, 0.31897879, 0.18844972 }, // 6 @ 51.91
- { 0.81690764, 0.39409966, 0.01546567, 0.02067949, 1.15143000 }, // 8 @ 67.87
- { 0.26545140, 0.84346586, 0.12114879, 0.23640230, 0.72659219 }, // 10 @ 81.82
- { 0.56254211, 0.32615646, 0.88375690, 0.46944169, 0.32862728 }, // 12 @ 95.36
- { 0.51926261, 0.41265523, 0.89552919, 0.47699008, 0.37308306 }, // 14 @ 109.60
- { 0.55650321, 0.92583533, 0.58934379, 0.16399064, 0.67129777 }, // 16 @ 122.89
- { 0.27930548, 0.94898807, 0.70335882, 0.32080180, 0.59102482 }, // 18 @ 136.45
- { 0.12620836, 0.94993219, 0.70209891, 0.34747431, 0.64429174 }, // 20 @ 150.52
- { 0.83595860, 0.95040751, 0.64127591, 0.30856013, 0.69692727 }, // 22 @ 163.41
- { 0.41252871, 0.96236749, 0.74895429, 0.41669175, 0.65996102 }, // 24 @ 174.32
- { 0.98567539, 0.88907131, 0.65652775, 0.34585902, 0.77265757 }, // 26 @ 191.26
- { 0.64526843, 0.67729329, 0.91813705, 0.43972488, 0.68332682 }, // 28 @ 195.77
- { 0.65310281, 0.66723395, 0.91751074, 0.43956737, 0.73651421 }, // 30 @ 207.04
- };
-
- double p[ 4 ];
-
- if (Params == nullptr)
- {
- Params = Coeffs[fl2 - 3];
- Power = Params[4];
- }
- else
- {
- p[0] = clampr(Params[0], -4.0, 4.0);
- p[1] = clampr(Params[1], -4.0, 4.0);
- p[2] = clampr(Params[2], -4.0, 4.0);
- p[3] = clampr(Params[3], -4.0, 4.0);
- Power = fabs(Params[4]);
- Params = p;
- }
-
- if (IsCentered)
- {
- w1.init(Params[0] * M_PI / Len2, M_PI * 0.5);
- w2.init(Params[1] * M_PI / Len2, M_PI * 0.5);
- w3.init(Params[2] * M_PI / Len2, M_PI * 0.5);
- w4.init(Params[3] * M_PI / Len2, M_PI * 0.5);
- }
- else
- {
- const double step1 = Params[0] * M_PI / Len2;
- w1.init(step1, M_PI * 0.5 - step1 * fl2 + step1 * FracDelay);
-
- const double step2 = Params[1] * M_PI / Len2;
- w2.init(step2, M_PI * 0.5 - step2 * fl2 + step2 * FracDelay);
-
- const double step3 = Params[2] * M_PI / Len2;
- w3.init(step3, M_PI * 0.5 - step3 * fl2 + step3 * FracDelay);
-
- const double step4 = Params[3] * M_PI / Len2;
- w4.init(step4, M_PI * 0.5 - step4 * fl2 + step4 * FracDelay);
- }
- }
-
- /**
- * Function initializes calculation of window function of the specified
- * type.
- *
- * @param WinType Window function type.
- * @param Params Window function's parameters. If NULL, the table values
- * may be used.
- * @param UsePower "True" if the power factor should be used to raise the
- * window function. If "true", the power factor should be specified as the
- * last value in the Params array. If Params is NULL, the table or default
- * value of -1.0 (off) will be used.
- * @param IsCentered "True" if centered window should be used. This
- * parameter usually equals to "false" for fractional delay filters only.
- * @param UseFracDelay Fractional delay to use.
- */
-
- void setWindow(const EWindowFunctionType WinType,
- const double* const Params, const bool UsePower,
- const bool IsCentered, const double UseFracDelay = 0.0)
- {
- FracDelay = UseFracDelay;
-
- if (WinType == wftCosine)
- {
- if (IsCentered)
- {
- w1.init(M_PI / Len2, M_PI * 0.5);
- w2.init(M_2PI / Len2, M_PI * 0.5);
- w3.init(M_3PI / Len2, M_PI * 0.5);
- }
- else
- {
- const double step1 = M_PI / Len2;
- w1.init(step1, M_PI * 0.5 - step1 * fl2 +
- step1 * FracDelay);
-
- const double step2 = M_2PI / Len2;
- w2.init(step2, M_PI * 0.5 - step2 * fl2 +
- step2 * FracDelay);
-
- const double step3 = M_3PI / Len2;
- w3.init(step3, M_PI * 0.5 - step3 * fl2 +
- step3 * FracDelay);
- }
-
- Power = (UsePower && Params != nullptr ? Params[0] : -1.0);
- }
- else if (WinType == wftKaiser) { setWindowKaiser(Params, UsePower, IsCentered); }
- else if (WinType == wftGaussian) { setWindowGaussian(Params, UsePower, IsCentered); }
- else { setWindowVaneev(Params, IsCentered); }
- }
- };
- } // namespace r8b
-
- #endif // R8B_CDSPSINCFILTERGEN_INCLUDED
|