Resampler.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * Resampler.h
  3. * -----------
  4. * Purpose: Holds the tables for all available resamplers.
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #pragma once
  10. #include "openmpt/all/BuildSettings.hpp"
  11. #include "WindowedFIR.h"
  12. #include "Mixer.h"
  13. #include "MixerSettings.h"
  14. #include "Paula.h"
  15. OPENMPT_NAMESPACE_BEGIN
  16. #ifdef LIBOPENMPT_BUILD
  17. // All these optimizations are not applicable to the tracker
  18. // because cutoff and firtype are configurable there.
  19. // Cache resampler tables across resampler object creation.
  20. // A C++11-style function-static singleton is holding the cached values.
  21. #define MPT_RESAMPLER_TABLES_CACHED
  22. // Prime the tables cache when the library is loaded.
  23. // Caching gets triggered via a global object that primes the cache during
  24. // construction.
  25. // This is only really useful with MPT_RESAMPLER_TABLES_CACHED.
  26. //#define MPT_RESAMPLER_TABLES_CACHED_ONSTARTUP
  27. #endif // LIBOPENMPT_BUILD
  28. #define SINC_WIDTH 8
  29. #define SINC_PHASES_BITS 12
  30. #define SINC_PHASES (1<<SINC_PHASES_BITS)
  31. #ifdef MPT_INTMIXER
  32. typedef int16 SINC_TYPE;
  33. #define SINC_QUANTSHIFT 15
  34. #else
  35. typedef mixsample_t SINC_TYPE;
  36. #endif // MPT_INTMIXER
  37. #define SINC_MASK (SINC_PHASES-1)
  38. static_assert((SINC_MASK & 0xffff) == SINC_MASK); // exceeding fractional freq
  39. class CResamplerSettings
  40. {
  41. public:
  42. ResamplingMode SrcMode = Resampling::Default();
  43. double gdWFIRCutoff = 0.97;
  44. uint8 gbWFIRType = WFIR_KAISER4T;
  45. Resampling::AmigaFilter emulateAmiga = Resampling::AmigaFilter::Off;
  46. public:
  47. constexpr CResamplerSettings() = default;
  48. bool operator == (const CResamplerSettings &cmp) const
  49. {
  50. #if MPT_COMPILER_CLANG
  51. #pragma clang diagnostic push
  52. #pragma clang diagnostic ignored "-Wfloat-equal"
  53. #endif // MPT_COMPILER_CLANG
  54. return SrcMode == cmp.SrcMode && gdWFIRCutoff == cmp.gdWFIRCutoff && gbWFIRType == cmp.gbWFIRType && emulateAmiga == cmp.emulateAmiga;
  55. #if MPT_COMPILER_CLANG
  56. #pragma clang diagnostic pop
  57. #endif // MPT_COMPILER_CLANG
  58. }
  59. bool operator != (const CResamplerSettings &cmp) const { return !(*this == cmp); }
  60. };
  61. class CResampler
  62. {
  63. public:
  64. CResamplerSettings m_Settings;
  65. CWindowedFIR m_WindowedFIR;
  66. static const int16 FastSincTable[256 * 4];
  67. #ifdef MODPLUG_TRACKER
  68. static bool StaticTablesInitialized;
  69. #define RESAMPLER_TABLE static
  70. #else
  71. // no global data which has to be initialized by hand in the library
  72. #define RESAMPLER_TABLE
  73. #endif // MODPLUG_TRACKER
  74. RESAMPLER_TABLE SINC_TYPE gKaiserSinc[SINC_PHASES * 8]; // Upsampling
  75. RESAMPLER_TABLE SINC_TYPE gDownsample13x[SINC_PHASES * 8]; // Downsample 1.333x
  76. RESAMPLER_TABLE SINC_TYPE gDownsample2x[SINC_PHASES * 8]; // Downsample 2x
  77. RESAMPLER_TABLE Paula::BlepTables blepTables; // Amiga BLEP resampler
  78. #ifndef MPT_INTMIXER
  79. RESAMPLER_TABLE mixsample_t FastSincTablef[256 * 4]; // Cubic spline LUT
  80. RESAMPLER_TABLE mixsample_t LinearTablef[256]; // Linear interpolation LUT
  81. #endif // !defined(MPT_INTMIXER)
  82. #undef RESAMPLER_TABLE
  83. private:
  84. CResamplerSettings m_OldSettings;
  85. public:
  86. CResampler(bool fresh_generate=false)
  87. {
  88. if(fresh_generate)
  89. {
  90. InitializeTablesFromScratch(true);
  91. } else
  92. {
  93. InitializeTables();
  94. }
  95. }
  96. void InitializeTables()
  97. {
  98. #if defined(MPT_RESAMPLER_TABLES_CACHED)
  99. InitializeTablesFromCache();
  100. #else
  101. InitializeTablesFromScratch(true);
  102. #endif
  103. }
  104. void UpdateTables()
  105. {
  106. InitializeTablesFromScratch(false);
  107. }
  108. private:
  109. void InitFloatmixerTables();
  110. void InitializeTablesFromScratch(bool force=false);
  111. #ifdef MPT_RESAMPLER_TABLES_CACHED
  112. void InitializeTablesFromCache();
  113. #endif
  114. };
  115. OPENMPT_NAMESPACE_END