WindowedFIR.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. * WindowedFIR.h
  3. * -------------
  4. * Purpose: FIR resampling code
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * ModPlug-XMMS Devs
  8. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  9. */
  10. #pragma once
  11. #include "openmpt/all/BuildSettings.hpp"
  12. #include "Mixer.h"
  13. OPENMPT_NAMESPACE_BEGIN
  14. /*
  15. ------------------------------------------------------------------------------------------------
  16. fir interpolation doc,
  17. (derived from "an engineer's guide to fir digital filters", n.j. loy)
  18. calculate coefficients for ideal lowpass filter (with cutoff = fc in 0..1 (mapped to 0..nyquist))
  19. c[-N..N] = (i==0) ? fc : sin(fc*pi*i)/(pi*i)
  20. then apply selected window to coefficients
  21. c[-N..N] *= w(0..N)
  22. with n in 2*N and w(n) being a window function (see loy)
  23. then calculate gain and scale filter coefs to have unity gain.
  24. ------------------------------------------------------------------------------------------------
  25. */
  26. #ifdef MPT_INTMIXER
  27. // quantizer scale of window coefs - only required for integer mixing
  28. inline constexpr int WFIR_QUANTBITS = 15;
  29. inline constexpr double WFIR_QUANTSCALE = 1 << WFIR_QUANTBITS;
  30. inline constexpr int WFIR_8SHIFT = (WFIR_QUANTBITS - 8);
  31. inline constexpr int WFIR_16BITSHIFT = (WFIR_QUANTBITS);
  32. using WFIR_TYPE = int16;
  33. #else
  34. using WFIR_TYPE = mixsample_t;
  35. #endif // INTMIXER
  36. // log2(number)-1 of precalculated taps range is [4..12]
  37. inline constexpr int WFIR_FRACBITS = 12; //10
  38. inline constexpr int WFIR_LUTLEN = ((1 << (WFIR_FRACBITS + 1)) + 1);
  39. // number of samples in window
  40. inline constexpr int WFIR_LOG2WIDTH = 3;
  41. inline constexpr int WFIR_WIDTH = (1 << WFIR_LOG2WIDTH);
  42. // cutoff (1.0 == pi/2)
  43. // wfir type
  44. enum WFIRType
  45. {
  46. WFIR_HANN = 0, // Hann
  47. WFIR_HAMMING = 1, // Hamming
  48. WFIR_BLACKMANEXACT = 2, // Blackman Exact
  49. WFIR_BLACKMAN3T61 = 3, // Blackman 3-Tap 61
  50. WFIR_BLACKMAN3T67 = 4, // Blackman 3-Tap 67
  51. WFIR_BLACKMAN4T92 = 5, // Blackman-Harris
  52. WFIR_BLACKMAN4T74 = 6, // Blackman 4-Tap 74
  53. WFIR_KAISER4T = 7, // Kaiser a=7.5
  54. };
  55. // fir interpolation
  56. inline constexpr int WFIR_FRACSHIFT = (16 - (WFIR_FRACBITS + 1 + WFIR_LOG2WIDTH));
  57. inline constexpr int WFIR_FRACMASK = ((((1 << (17 - WFIR_FRACSHIFT)) - 1) & ~(WFIR_WIDTH - 1)));
  58. inline constexpr int WFIR_FRACHALVE = (1 << (16 - (WFIR_FRACBITS + 2)));
  59. class CWindowedFIR
  60. {
  61. private:
  62. double coef(int,double,double,int,int);
  63. public:
  64. void InitTable(double WFIRCutoff, uint8 WFIRType);
  65. WFIR_TYPE lut[WFIR_LUTLEN * WFIR_WIDTH];
  66. };
  67. OPENMPT_NAMESPACE_END