12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- /*
- * 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
|