diff options
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/soundlib/WindowedFIR.h')
-rw-r--r-- | Src/external_dependencies/openmpt-trunk/soundlib/WindowedFIR.h | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/soundlib/WindowedFIR.h b/Src/external_dependencies/openmpt-trunk/soundlib/WindowedFIR.h new file mode 100644 index 00000000..ed324a33 --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/soundlib/WindowedFIR.h @@ -0,0 +1,82 @@ +/* + * WindowedFIR.h + * ------------- + * Purpose: FIR resampling code + * Notes : (currently none) + * Authors: OpenMPT Devs + * ModPlug-XMMS Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#pragma once + +#include "openmpt/all/BuildSettings.hpp" + +#include "Mixer.h" + +OPENMPT_NAMESPACE_BEGIN + +/* + ------------------------------------------------------------------------------------------------ + fir interpolation doc, + (derived from "an engineer's guide to fir digital filters", n.j. loy) + + calculate coefficients for ideal lowpass filter (with cutoff = fc in 0..1 (mapped to 0..nyquist)) + c[-N..N] = (i==0) ? fc : sin(fc*pi*i)/(pi*i) + + then apply selected window to coefficients + c[-N..N] *= w(0..N) + with n in 2*N and w(n) being a window function (see loy) + + then calculate gain and scale filter coefs to have unity gain. + ------------------------------------------------------------------------------------------------ +*/ + +#ifdef MPT_INTMIXER +// quantizer scale of window coefs - only required for integer mixing +inline constexpr int WFIR_QUANTBITS = 15; +inline constexpr double WFIR_QUANTSCALE = 1 << WFIR_QUANTBITS; +inline constexpr int WFIR_8SHIFT = (WFIR_QUANTBITS - 8); +inline constexpr int WFIR_16BITSHIFT = (WFIR_QUANTBITS); +using WFIR_TYPE = int16; +#else +using WFIR_TYPE = mixsample_t; +#endif // INTMIXER +// log2(number)-1 of precalculated taps range is [4..12] +inline constexpr int WFIR_FRACBITS = 12; //10 +inline constexpr int WFIR_LUTLEN = ((1 << (WFIR_FRACBITS + 1)) + 1); +// number of samples in window +inline constexpr int WFIR_LOG2WIDTH = 3; +inline constexpr int WFIR_WIDTH = (1 << WFIR_LOG2WIDTH); +// cutoff (1.0 == pi/2) +// wfir type +enum WFIRType +{ + WFIR_HANN = 0, // Hann + WFIR_HAMMING = 1, // Hamming + WFIR_BLACKMANEXACT = 2, // Blackman Exact + WFIR_BLACKMAN3T61 = 3, // Blackman 3-Tap 61 + WFIR_BLACKMAN3T67 = 4, // Blackman 3-Tap 67 + WFIR_BLACKMAN4T92 = 5, // Blackman-Harris + WFIR_BLACKMAN4T74 = 6, // Blackman 4-Tap 74 + WFIR_KAISER4T = 7, // Kaiser a=7.5 +}; + + +// fir interpolation +inline constexpr int WFIR_FRACSHIFT = (16 - (WFIR_FRACBITS + 1 + WFIR_LOG2WIDTH)); +inline constexpr int WFIR_FRACMASK = ((((1 << (17 - WFIR_FRACSHIFT)) - 1) & ~(WFIR_WIDTH - 1))); +inline constexpr int WFIR_FRACHALVE = (1 << (16 - (WFIR_FRACBITS + 2))); + +class CWindowedFIR +{ +private: + double coef(int,double,double,int,int); + +public: + void InitTable(double WFIRCutoff, uint8 WFIRType); + WFIR_TYPE lut[WFIR_LUTLEN * WFIR_WIDTH]; +}; + +OPENMPT_NAMESPACE_END |