winamp/Src/external_dependencies/openmpt-trunk/soundlib/Resampler.h
2024-09-24 14:54:57 +02:00

144 lines
3.6 KiB
C++

/*
* Resampler.h
* -----------
* Purpose: Holds the tables for all available resamplers.
* Notes : (currently none)
* Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#pragma once
#include "openmpt/all/BuildSettings.hpp"
#include "WindowedFIR.h"
#include "Mixer.h"
#include "MixerSettings.h"
#include "Paula.h"
OPENMPT_NAMESPACE_BEGIN
#ifdef LIBOPENMPT_BUILD
// All these optimizations are not applicable to the tracker
// because cutoff and firtype are configurable there.
// Cache resampler tables across resampler object creation.
// A C++11-style function-static singleton is holding the cached values.
#define MPT_RESAMPLER_TABLES_CACHED
// Prime the tables cache when the library is loaded.
// Caching gets triggered via a global object that primes the cache during
// construction.
// This is only really useful with MPT_RESAMPLER_TABLES_CACHED.
//#define MPT_RESAMPLER_TABLES_CACHED_ONSTARTUP
#endif // LIBOPENMPT_BUILD
#define SINC_WIDTH 8
#define SINC_PHASES_BITS 12
#define SINC_PHASES (1<<SINC_PHASES_BITS)
#ifdef MPT_INTMIXER
typedef int16 SINC_TYPE;
#define SINC_QUANTSHIFT 15
#else
typedef mixsample_t SINC_TYPE;
#endif // MPT_INTMIXER
#define SINC_MASK (SINC_PHASES-1)
static_assert((SINC_MASK & 0xffff) == SINC_MASK); // exceeding fractional freq
class CResamplerSettings
{
public:
ResamplingMode SrcMode = Resampling::Default();
double gdWFIRCutoff = 0.97;
uint8 gbWFIRType = WFIR_KAISER4T;
Resampling::AmigaFilter emulateAmiga = Resampling::AmigaFilter::Off;
public:
constexpr CResamplerSettings() = default;
bool operator == (const CResamplerSettings &cmp) const
{
#if MPT_COMPILER_CLANG
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"
#endif // MPT_COMPILER_CLANG
return SrcMode == cmp.SrcMode && gdWFIRCutoff == cmp.gdWFIRCutoff && gbWFIRType == cmp.gbWFIRType && emulateAmiga == cmp.emulateAmiga;
#if MPT_COMPILER_CLANG
#pragma clang diagnostic pop
#endif // MPT_COMPILER_CLANG
}
bool operator != (const CResamplerSettings &cmp) const { return !(*this == cmp); }
};
class CResampler
{
public:
CResamplerSettings m_Settings;
CWindowedFIR m_WindowedFIR;
static const int16 FastSincTable[256 * 4];
#ifdef MODPLUG_TRACKER
static bool StaticTablesInitialized;
#define RESAMPLER_TABLE static
#else
// no global data which has to be initialized by hand in the library
#define RESAMPLER_TABLE
#endif // MODPLUG_TRACKER
RESAMPLER_TABLE SINC_TYPE gKaiserSinc[SINC_PHASES * 8]; // Upsampling
RESAMPLER_TABLE SINC_TYPE gDownsample13x[SINC_PHASES * 8]; // Downsample 1.333x
RESAMPLER_TABLE SINC_TYPE gDownsample2x[SINC_PHASES * 8]; // Downsample 2x
RESAMPLER_TABLE Paula::BlepTables blepTables; // Amiga BLEP resampler
#ifndef MPT_INTMIXER
RESAMPLER_TABLE mixsample_t FastSincTablef[256 * 4]; // Cubic spline LUT
RESAMPLER_TABLE mixsample_t LinearTablef[256]; // Linear interpolation LUT
#endif // !defined(MPT_INTMIXER)
#undef RESAMPLER_TABLE
private:
CResamplerSettings m_OldSettings;
public:
CResampler(bool fresh_generate=false)
{
if(fresh_generate)
{
InitializeTablesFromScratch(true);
} else
{
InitializeTables();
}
}
void InitializeTables()
{
#if defined(MPT_RESAMPLER_TABLES_CACHED)
InitializeTablesFromCache();
#else
InitializeTablesFromScratch(true);
#endif
}
void UpdateTables()
{
InitializeTablesFromScratch(false);
}
private:
void InitFloatmixerTables();
void InitializeTablesFromScratch(bool force=false);
#ifdef MPT_RESAMPLER_TABLES_CACHED
void InitializeTablesFromCache();
#endif
};
OPENMPT_NAMESPACE_END