aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/soundlib/WindowedFIR.h
diff options
context:
space:
mode:
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/soundlib/WindowedFIR.h')
-rw-r--r--Src/external_dependencies/openmpt-trunk/soundlib/WindowedFIR.h82
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