Cog/Frameworks/OpenMPT/OpenMPT/soundlib/WindowedFIR.h
Christopher Snowhill 731e52c440 Build libOpenMPT from source once again
Bundle libOpenMPT as a dynamic framework, which should be safe once
again, now that there is only one version to bundle. Also, now it is
using the versions of libvorbisfile and libmpg123 that are bundled with
the player, instead of compiling minimp3 and stbvorbis.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-06-30 22:57:30 -07:00

82 lines
2.5 KiB
C++

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