Index: common/versionNumber.h
===================================================================
--- common/versionNumber.h	(revision 9968)
+++ common/versionNumber.h	(working copy)
@@ -19,7 +19,7 @@
 #define VER_MAJORMAJOR          1
 #define VER_MAJOR               28
 #define VER_MINOR               00
-#define VER_MINORMINOR          15
+#define VER_MINORMINOR          16
 
 //Version string. For example "1.17.02.28"
 #define MPT_VERSION_STR         VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR)
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 9968)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -316,13 +316,13 @@
 }
 
 static ResamplingMode filterlength_to_resamplingmode(std::int32_t length) {
-	ResamplingMode result = SRCMODE_POLYPHASE;
+	ResamplingMode result = SRCMODE_SINC8LP;
 	if ( length == 0 ) {
-		result = SRCMODE_POLYPHASE;
+		result = SRCMODE_SINC8LP;
 	} else if ( length >= 8 ) {
-		result = SRCMODE_POLYPHASE;
+		result = SRCMODE_SINC8LP;
 	} else if ( length >= 3 ) {
-		result = SRCMODE_SPLINE;
+		result = SRCMODE_CUBIC;
 	} else if ( length >= 2 ) {
 		result = SRCMODE_LINEAR;
 	} else if ( length >= 1 ) {
@@ -340,11 +340,11 @@
 	case SRCMODE_LINEAR:
 		return 2;
 		break;
-	case SRCMODE_SPLINE:
+	case SRCMODE_CUBIC:
 		return 4;
 		break;
-	case SRCMODE_POLYPHASE:
-	case SRCMODE_FIRFILTER:
+	case SRCMODE_SINC8:
+	case SRCMODE_SINC8LP:
 	case SRCMODE_DEFAULT:
 		return 8;
 	default:
Index: mptrack/Ctrl_gen.cpp
===================================================================
--- mptrack/Ctrl_gen.cpp	(revision 9968)
+++ mptrack/Ctrl_gen.cpp	(working copy)
@@ -202,21 +202,21 @@
 	FlagSet<HintType> hintType = hint.GetType();
 	const bool updateAll = hintType[HINT_MODTYPE];
 
-	const ResamplingMode resamplingModes[] = { SRCMODE_NEAREST, SRCMODE_LINEAR, SRCMODE_SPLINE, SRCMODE_POLYPHASE, SRCMODE_FIRFILTER };
+	const auto resamplingModes = Resampling::AllModes();
 
 	if (hintType == HINT_MPTOPTIONS || updateAll)
 	{
-		const TCHAR *defaultResampler;
+		CString defaultResampler;
 		if(m_sndFile.m_SongFlags[SONG_ISAMIGA] && TrackerSettings::Instance().ResamplerEmulateAmiga)
 			defaultResampler = _T("Amiga Resampler");
 		else
-			defaultResampler = CTrackApp::GetResamplingModeName(TrackerSettings::Instance().ResamplerMode, false);
+			defaultResampler = CTrackApp::GetResamplingModeName(TrackerSettings::Instance().ResamplerMode, 1, false);
 
 		m_CbnResampling.ResetContent();
-		m_CbnResampling.SetItemData(m_CbnResampling.AddString(_T("Default (") + CString(defaultResampler) + _T(")")), SRCMODE_DEFAULT);
+		m_CbnResampling.SetItemData(m_CbnResampling.AddString(_T("Default (") + defaultResampler + _T(")")), SRCMODE_DEFAULT);
 		for(auto mode : resamplingModes)
 		{
-			m_CbnResampling.SetItemData(m_CbnResampling.AddString(CTrackApp::GetResamplingModeName(mode, false)), mode);
+			m_CbnResampling.SetItemData(m_CbnResampling.AddString(CTrackApp::GetResamplingModeName(mode, 2, true)), mode);
 		}
 		m_CbnResampling.Invalidate(FALSE);
 	}
@@ -312,12 +312,13 @@
 
 	if(updateAll || hintType == HINT_MPTOPTIONS || (hint.GetCategory() == HINTCAT_GENERAL && hintType[HINT_MODGENERAL]))
 	{
+
 		int srcMode = 0;
-		for(int i = 0; i < CountOf(resamplingModes); i++)
+		for(int i = 0; i < m_CbnResampling.GetCount(); ++i)
 		{
-			if(m_sndFile.m_nResampling == resamplingModes[i]) srcMode = i + 1;
+			if(m_sndFile.m_nResampling == static_cast<int>(m_CbnResampling.GetItemData(i)))
+				m_CbnResampling.SetCurSel(i);
 		}
-		m_CbnResampling.SetCurSel(srcMode);
 	}
 
 	CheckDlgButton(IDC_CHECK_LOOPSONG, (TrackerSettings::Instance().gbLoopSong) ? TRUE : FALSE);
Index: mptrack/Ctrl_ins.cpp
===================================================================
--- mptrack/Ctrl_ins.cpp	(revision 9968)
+++ mptrack/Ctrl_ins.cpp	(working copy)
@@ -995,12 +995,12 @@
 	m_EditPWD.SubclassDlgItem(IDC_PITCHWHEELDEPTH, this);
 	m_EditPWD.AllowFractions(false);
 
+	const auto resamplingModes = Resampling::AllModes();
 	m_CbnResampling.SetItemData(m_CbnResampling.AddString(_T("Default")), SRCMODE_DEFAULT);
-	m_CbnResampling.SetItemData(m_CbnResampling.AddString(_T("None")), SRCMODE_NEAREST);
-	m_CbnResampling.SetItemData(m_CbnResampling.AddString(_T("Linear")), SRCMODE_LINEAR);
-	m_CbnResampling.SetItemData(m_CbnResampling.AddString(_T("Spline")), SRCMODE_SPLINE);
-	m_CbnResampling.SetItemData(m_CbnResampling.AddString(_T("Polyphase")), SRCMODE_POLYPHASE);
-	m_CbnResampling.SetItemData(m_CbnResampling.AddString(_T("XMMS")), SRCMODE_FIRFILTER);
+	for(auto mode : resamplingModes)
+	{
+		m_CbnResampling.SetItemData(m_CbnResampling.AddString(CTrackApp::GetResamplingModeName(mode, 1, false)), mode);
+	}
 
 	m_CbnFilterMode.SetItemData(m_CbnFilterMode.AddString(_T("Channel default")), FLTMODE_UNCHANGED);
 	m_CbnFilterMode.SetItemData(m_CbnFilterMode.AddString(_T("Force lowpass")), FLTMODE_LOWPASS);
Index: mptrack/Mpdlgs.cpp
===================================================================
--- mptrack/Mpdlgs.cpp	(revision 9968)
+++ mptrack/Mpdlgs.cpp	(working copy)
@@ -928,9 +928,7 @@
 	ON_WM_HSCROLL()
 	ON_WM_VSCROLL()
 	ON_CBN_SELCHANGE(IDC_COMBO_FILTER,			OnResamplerChanged)
-	ON_CBN_SELCHANGE(IDC_COMBO_FILTERWINDOW,	OnSettingsChanged)
 	ON_CBN_SELCHANGE(IDC_COMBO_POLYPHONY,		OnSettingsChanged)
-	ON_EN_UPDATE(IDC_WFIRCUTOFF,				OnSettingsChanged)
 	ON_EN_UPDATE(IDC_RAMPING_IN,				OnRampingChanged)
 	ON_EN_UPDATE(IDC_RAMPING_OUT,				OnRampingChanged)
 	ON_COMMAND(IDC_CHECK_SOFTPAN,				OnSettingsChanged)
@@ -943,8 +941,6 @@
 	CPropertyPage::DoDataExchange(pDX);
 	//{{AFX_DATA_MAP(COptionsSoundcard)
 	DDX_Control(pDX, IDC_COMBO_FILTER, m_CbnResampling);
-	DDX_Control(pDX, IDC_WFIRCUTOFF, m_CEditWFIRCutoff);
-	DDX_Control(pDX, IDC_COMBO_FILTERWINDOW, m_CbnWFIRType);
 	DDX_Control(pDX, IDC_RAMPING_IN, m_CEditRampUp);
 	DDX_Control(pDX, IDC_RAMPING_OUT, m_CEditRampDown);
 	DDX_Control(pDX, IDC_EDIT_VOLRAMP_SAMPLES_UP, m_CInfoRampUp);
@@ -963,26 +959,18 @@
 
 	// Resampling type
 	{
-		for(auto mode : { SRCMODE_NEAREST, SRCMODE_LINEAR, SRCMODE_SPLINE, SRCMODE_POLYPHASE, SRCMODE_FIRFILTER })
+		const auto resamplingModes = Resampling::AllModes();
+		for(auto mode : resamplingModes)
 		{
-			int index = m_CbnResampling.AddString(CTrackApp::GetResamplingModeName(mode, true));
+			int index = m_CbnResampling.AddString(CTrackApp::GetResamplingModeName(mode, 2, true));
 			m_CbnResampling.SetItemData(index, mode);
 			if(TrackerSettings::Instance().ResamplerMode == mode)
+			{
 				m_CbnResampling.SetCurSel(index);
+			}
 		}
 	}
 
-	// Resampler bandwidth
-	{
-		m_CEditWFIRCutoff.SetWindowText(mpt::ToCString(mpt::ufmt::val(TrackerSettings::Instance().ResamplerCutoffPercent)));
-		static_cast<CSpinButtonCtrl *>(GetDlgItem(IDC_SPIN1))->SetRange32(1, 99);
-	}
-
-	// Resampler filter window
-	{
-		// done in OnResamplerChanged()
-	}
-
 	// Amiga Resampler
 	CheckDlgButton(IDC_CHECK1, TrackerSettings::Instance().ResamplerEmulateAmiga ? BST_CHECKED : BST_UNCHECKED);
 
@@ -1037,7 +1025,6 @@
 		m_SliderPreAmp.SetPos(n);
 	}
 
-	OnResamplerChanged();
 	m_initialized = true;
 
 	return TRUE;
@@ -1053,61 +1040,6 @@
 
 void COptionsMixer::OnResamplerChanged()
 {
-	ResamplingMode srcMode = static_cast<ResamplingMode>(m_CbnResampling.GetItemData(m_CbnResampling.GetCurSel()));
-	m_CbnWFIRType.ResetContent();
-	switch(srcMode)
-	{
-		case SRCMODE_FIRFILTER:
-			m_CbnWFIRType.AddString(_T("Hann"));
-			m_CbnWFIRType.AddString(_T("Hamming"));
-			m_CbnWFIRType.AddString(_T("Blackman Exact"));
-			m_CbnWFIRType.AddString(_T("Blackman 3 Tap 61"));
-			m_CbnWFIRType.AddString(_T("Blackman 3 Tap 67"));
-			m_CbnWFIRType.AddString(_T("Blackman Harris"));
-			m_CbnWFIRType.AddString(_T("Blackman 4 Tap 74"));
-			m_CbnWFIRType.AddString(_T("Kaiser a=7.5"));
-			break;
-		case SRCMODE_POLYPHASE:
-			m_CbnWFIRType.AddString(_T("Auto"));
-			m_CbnWFIRType.AddString(_T("Auto"));
-			m_CbnWFIRType.AddString(_T("Auto"));
-			m_CbnWFIRType.AddString(_T("Auto"));
-			m_CbnWFIRType.AddString(_T("Auto"));
-			m_CbnWFIRType.AddString(_T("Auto"));
-			m_CbnWFIRType.AddString(_T("Auto"));
-			m_CbnWFIRType.AddString(_T("Auto"));
-			break;
-		default:
-			m_CbnWFIRType.AddString(_T("none"));
-			m_CbnWFIRType.AddString(_T("none"));
-			m_CbnWFIRType.AddString(_T("none"));
-			m_CbnWFIRType.AddString(_T("none"));
-			m_CbnWFIRType.AddString(_T("none"));
-			m_CbnWFIRType.AddString(_T("none"));
-			m_CbnWFIRType.AddString(_T("none"));
-			m_CbnWFIRType.AddString(_T("none"));
-			break;
-	}
-	m_CbnWFIRType.SetCurSel(TrackerSettings::Instance().ResamplerSubMode);
-	CSpinButtonCtrl *spinWFIRCutoff = static_cast<CSpinButtonCtrl *>(GetDlgItem(IDC_SPIN1));
-	switch(srcMode)
-	{
-		case SRCMODE_POLYPHASE:
-			m_CEditWFIRCutoff.EnableWindow(FALSE);
-			spinWFIRCutoff->EnableWindow(FALSE);
-			m_CbnWFIRType.EnableWindow(FALSE);
-			break;
-		case SRCMODE_FIRFILTER:
-			m_CEditWFIRCutoff.EnableWindow(TRUE);
-			spinWFIRCutoff->EnableWindow(TRUE);
-			m_CbnWFIRType.EnableWindow(TRUE);
-			break;
-		default:
-			m_CEditWFIRCutoff.EnableWindow(FALSE);
-			spinWFIRCutoff->EnableWindow(FALSE);
-			m_CbnWFIRType.EnableWindow(FALSE);
-			break;
-	}
 	OnSettingsChanged();
 }
 
@@ -1162,27 +1094,6 @@
 		TrackerSettings::Instance().ResamplerMode = static_cast<ResamplingMode>(m_CbnResampling.GetItemData(m_CbnResampling.GetCurSel()));
 	}
 
-	// resampler bandwidth
-	{
-		CString s;
-		m_CEditWFIRCutoff.GetWindowText(s);
-		if(s != "")
-		{
-			int newCutoff = ConvertStrTo<int>(s);
-			Limit(newCutoff, 0, 100);
-			TrackerSettings::Instance().ResamplerCutoffPercent = newCutoff;
-		}
-		{
-			s.Format(_T("%d"), TrackerSettings::Instance().ResamplerCutoffPercent.Get());
-			m_CEditWFIRCutoff.SetWindowText(s);
-		}
-	}
-
-	// resampler filter window
-	{
-		TrackerSettings::Instance().ResamplerSubMode = (uint8)m_CbnWFIRType.GetCurSel();
-	}
-
 	// Amiga Resampler
 	TrackerSettings::Instance().ResamplerEmulateAmiga = IsDlgButtonChecked(IDC_CHECK1) != BST_UNCHECKED;
 
Index: mptrack/Mpdlgs.h
===================================================================
--- mptrack/Mpdlgs.h	(revision 9968)
+++ mptrack/Mpdlgs.h	(working copy)
@@ -88,8 +88,6 @@
 protected:
 
 	CComboBox m_CbnResampling;
-	CEdit m_CEditWFIRCutoff;
-	CComboBox m_CbnWFIRType;
 
 	CEdit m_CEditRampUp;
 	CEdit m_CEditRampDown;
Index: mptrack/Mptrack.cpp
===================================================================
--- mptrack/Mptrack.cpp	(revision 9968)
+++ mptrack/Mptrack.cpp	(working copy)
@@ -1995,24 +1995,39 @@
 }
 
 
-const TCHAR *CTrackApp::GetResamplingModeName(ResamplingMode mode, bool addTaps)
+CString CTrackApp::GetResamplingModeName(ResamplingMode mode, int length, bool addTaps)
 {
+	CString result;
 	switch(mode)
 	{
 	case SRCMODE_NEAREST:
-		return addTaps ? _T("No Interpolation (1 tap)") : _T("No Interpolation");
+		result = (length > 1) ? _T("No Interpolation") : _T("None") ;
+		break;
 	case SRCMODE_LINEAR:
-		return addTaps ? _T("Linear (2 tap)") : _T("Linear");
-	case SRCMODE_SPLINE:
-		return addTaps ? _T("Cubic Spline (4 tap)") :  _T("Cubic Spline");
-	case SRCMODE_POLYPHASE:
-		return addTaps ? _T("Polyphase (8 tap)") : _T("Polyphase");
-	case SRCMODE_FIRFILTER:
-		return addTaps ? _T("XMMS-ModPlug (8 tap)") : _T("XMMS-ModPlug");
+		result = _T("Linear");
+		break;
+	case SRCMODE_CUBIC:
+		result = (length > 1) ? _T("Cubic Spline") : _T("Cubic");
+		break;
+	case SRCMODE_SINC8:
+		result = _T("Sinc");
+		break;
+	case SRCMODE_SINC8LP:
+		result = _T("Sinc");
+		break;
 	default:
 		MPT_ASSERT_NOTREACHED();
+		break;
 	}
-	return _T("");
+	if(Resampling::HasAA(mode))
+	{
+		result += (length > 1) ? _T(" + Low-Pass") : _T(" + LP");
+	}
+	if(addTaps)
+	{
+		result += mpt::cformat(_T(" (%1 tap%2)"))(Resampling::Length(mode), (Resampling::Length(mode) != 1) ? CString(_T("s")) : CString(_T("")));
+	}
+	return result;
 }
 
 
Index: mptrack/Mptrack.h
===================================================================
--- mptrack/Mptrack.h	(revision 9968)
+++ mptrack/Mptrack.h	(working copy)
@@ -268,7 +268,7 @@
 
 public:
 	// Get name of resampling mode. addTaps = true also adds the number of taps the filter uses.
-	static const TCHAR *GetResamplingModeName(ResamplingMode mode, bool addTaps);
+	static CString GetResamplingModeName(ResamplingMode mode, int length, bool addTaps);
 
 // Overrides
 public:
Index: mptrack/mptrack.rc
===================================================================
--- mptrack/mptrack.rc	(revision 9968)
+++ mptrack/mptrack.rc	(working copy)
@@ -1981,15 +1981,9 @@
 BEGIN
     GROUPBOX        "Resampling",IDC_STATIC,6,6,276,48
     LTEXT           "&Filter:",IDC_STATIC,12,18,24,12,SS_CENTERIMAGE
-    COMBOBOX        IDC_COMBO_FILTER,54,18,96,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    LTEXT           "&Window:",IDC_STATIC,156,18,30,12,SS_CENTERIMAGE
-    COMBOBOX        IDC_COMBO_FILTERWINDOW,192,18,84,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    LTEXT           "&Bandwidth:",IDC_STATIC,12,36,42,12,SS_CENTERIMAGE
-    EDITTEXT        IDC_WFIRCUTOFF,54,36,30,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER
-    CONTROL         "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,71,31,11,14
-    LTEXT           "%",IDC_STATIC,90,36,24,12,SS_CENTERIMAGE
+    COMBOBOX        IDC_COMBO_FILTER,36,18,102,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     CONTROL         "Use &Amiga resampler for Amiga modules",IDC_CHECK1,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,126,36,150,12
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,36,144,12
     GROUPBOX        "Volume Ramping",IDC_STATIC,6,60,276,48
     EDITTEXT        IDC_RAMPING_IN,12,72,36,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER
     CONTROL         "",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,42,66,11,14
Index: mptrack/resource.h
===================================================================
--- mptrack/resource.h	(revision 9968)
+++ mptrack/resource.h	(working copy)
@@ -684,8 +684,6 @@
 #define IDC_COMMAND_LIST                2129
 #define IDC_STATIC8                     2200
 #define IDC_PATINSTROPLUGGUI            2201
-#define IDC_WFIRCUTOFF                  2202
-#define IDC_WFIRTYPE                    2203
 #define IDC_RAMPING_IN                  2204
 #define IDC_PLAYEROPTIONS               2205
 #define IDC_RAMPING_OUT                 2205
Index: mptrack/SampleEditorDialogs.cpp
===================================================================
--- mptrack/SampleEditorDialogs.cpp	(revision 9968)
+++ mptrack/SampleEditorDialogs.cpp	(working copy)
@@ -530,12 +530,12 @@
 
 	CComboBox *cbnResampling = static_cast<CComboBox *>(GetDlgItem(IDC_COMBO_FILTER));
 	cbnResampling->SetRedraw(FALSE);
-	const ResamplingMode resamplingModes[] = { SRCMODE_NEAREST, SRCMODE_LINEAR, SRCMODE_SPLINE, SRCMODE_POLYPHASE, SRCMODE_FIRFILTER, SRCMODE_DEFAULT };
+	const auto resamplingModes = Resampling::AllModesWithDefault();
 	for(auto mode : resamplingModes)
 	{
-		const TCHAR *desc = _T("r8brain (High Quality)");
+		CString desc = _T("r8brain (High Quality)");
 		if(mode != SRCMODE_DEFAULT)
-			desc = CTrackApp::GetResamplingModeName(mode, false);
+			desc = CTrackApp::GetResamplingModeName(mode, 1, true);
 
 		int index = cbnResampling->AddString(desc);
 		cbnResampling->SetItemData(index, mode);
Index: mptrack/TrackerSettings.cpp
===================================================================
--- mptrack/TrackerSettings.cpp	(revision 9968)
+++ mptrack/TrackerSettings.cpp	(working copy)
@@ -76,29 +76,6 @@
 }
 
 
-static ResamplingMode GetDefaultResamplerMode()
-{
-	ResamplingMode result = CResamplerSettings().SrcMode;
-#ifdef ENABLE_ASM
-	// rough heuristic to select less cpu consuming defaults for old CPUs
-	if(GetRealProcSupport() & PROCSUPPORT_SSE)
-	{
-		result = SRCMODE_POLYPHASE;
-	} else if(GetRealProcSupport() & PROCSUPPORT_MMX)
-	{
-		result = SRCMODE_SPLINE;
-	} else
-	{
-		result = SRCMODE_LINEAR;
-	}
-#else
-	// just use a sane default
-	result = CResamplerSettings().SrcMode;
-#endif
-	return result;
-}
-
-
 static uint32 GetDefaultPatternSetup()
 {
 	return PATTERN_PLAYNEWNOTE | PATTERN_EFFECTHILIGHT
@@ -246,7 +223,7 @@
 	, MixerStereoSeparation(conf, MPT_USTRING("Sound Settings"), MPT_USTRING("StereoSeparation"), MixerSettings().m_nStereoSeparation)
 	, MixerVolumeRampUpMicroseconds(conf, MPT_USTRING("Sound Settings"), MPT_USTRING("VolumeRampUpMicroseconds"), MixerSettings().GetVolumeRampUpMicroseconds())
 	, MixerVolumeRampDownMicroseconds(conf, MPT_USTRING("Sound Settings"), MPT_USTRING("VolumeRampDownMicroseconds"), MixerSettings().GetVolumeRampDownMicroseconds())
-	, ResamplerMode(conf, MPT_USTRING("Sound Settings"), MPT_USTRING("SrcMode"), GetDefaultResamplerMode())
+	, ResamplerMode(conf, MPT_USTRING("Sound Settings"), MPT_USTRING("SrcMode"), CResamplerSettings().SrcMode)
 	, ResamplerSubMode(conf, MPT_USTRING("Sound Settings"), MPT_USTRING("XMMSModplugResamplerWFIRType"), CResamplerSettings().gbWFIRType)
 	, ResamplerCutoffPercent(conf, MPT_USTRING("Sound Settings"), MPT_USTRING("ResamplerWFIRCutoff"), Util::Round<int32>(CResamplerSettings().gdWFIRCutoff * 100.0))
 	, ResamplerEmulateAmiga(conf, MPT_USTRING("Sound Settings"), MPT_USTRING("ResamplerEmulateAmiga"), false)
@@ -548,6 +525,13 @@
 		m_SoundDeviceSettingsDefaults.UseHardwareTiming = m_SoundDeviceUseHardwareTiming;
 		m_SoundDeviceSettingsUseOldDefaults = true;
 	}
+	if(storedVersion < MAKE_VERSION_NUMERIC(1,28,00,16))
+	{
+		// reset this setting to the default when updating,
+		// because we do not provide a GUI any more,
+		// and in general, it should not get changed anyway
+		ResamplerCutoffPercent = Util::Round<int32>(CResamplerSettings().gdWFIRCutoff * 100.0);
+	}
 	if(storedVersion < MAKE_VERSION_NUMERIC(1,25,00,04))
 	{
 		m_SoundDeviceDirectSoundOldDefaultIdentifier = true;
@@ -680,7 +664,7 @@
 	}
 
 	// Sanitize resampling mode for sample editor
-	if(!IsKnownResamplingMode(sampleEditorDefaultResampler) && sampleEditorDefaultResampler != SRCMODE_DEFAULT)
+	if(!Resampling::IsKnownMode(sampleEditorDefaultResampler) && sampleEditorDefaultResampler != SRCMODE_DEFAULT)
 	{
 		sampleEditorDefaultResampler = SRCMODE_DEFAULT;
 	}
Index: soundlib/Load_it.cpp
===================================================================
--- soundlib/Load_it.cpp	(revision 9968)
+++ soundlib/Load_it.cpp	(working copy)
@@ -2357,7 +2357,7 @@
 			case MagicBE("RP.."): if(GetType() != MOD_TYPE_XM) { ORDERINDEX restartPos; ReadField(chunk, size, restartPos); Order().SetRestartPos(restartPos); } break;
 			case MagicLE("RSMP"):
 				ReadFieldCast(chunk, size, m_nResampling);
-				if(!IsKnownResamplingMode(m_nResampling)) m_nResampling = SRCMODE_DEFAULT;
+				if(!Resampling::IsKnownMode(m_nResampling)) m_nResampling = SRCMODE_DEFAULT;
 				break;
 #ifdef MODPLUG_TRACKER
 			case MagicBE("MIMA"): GetMIDIMapper().Deserialize(chunk); break;
Index: soundlib/MixFuncTable.cpp
===================================================================
--- soundlib/MixFuncTable.cpp	(revision 9968)
+++ soundlib/MixFuncTable.cpp	(working copy)
@@ -79,9 +79,9 @@
 	{
 	case SRCMODE_NEAREST:   return ndxNoInterpolation;
 	case SRCMODE_LINEAR:    return ndxLinear;
-	case SRCMODE_SPLINE:    return ndxFastSinc;
-	case SRCMODE_POLYPHASE: return ndxKaiser;
-	case SRCMODE_FIRFILTER: return ndxFIRFilter;
+	case SRCMODE_CUBIC:     return ndxFastSinc;
+	case SRCMODE_SINC8LP:   return ndxKaiser;
+	case SRCMODE_SINC8:     return ndxFIRFilter;
 	case SRCMODE_AMIGA:     return ndxAmigaBlep;
 	default:                MPT_ASSERT_NOTREACHED();
 	}
Index: soundlib/Resampler.h
===================================================================
--- soundlib/Resampler.h	(revision 9968)
+++ soundlib/Resampler.h	(working copy)
@@ -59,12 +59,12 @@
 	uint8 gbWFIRType;
 	bool emulateAmiga;
 public:
-	CResamplerSettings()
+	MPT_CONSTEXPR11_FUN CResamplerSettings()
+		: SrcMode(Resampling::Default())
+		, gdWFIRCutoff(0.97)
+		, gbWFIRType(WFIR_KAISER4T)
+		, emulateAmiga(false)
 	{
-		SrcMode = SRCMODE_POLYPHASE;
-		gdWFIRCutoff = 0.97;
-		gbWFIRType = WFIR_KAISER4T;
-		emulateAmiga = false;
 	}
 	bool operator == (const CResamplerSettings &cmp) const
 	{
@@ -125,8 +125,6 @@
 	{
 		InitializeTablesFromScratch(false);
 	}
-	~CResampler() {}
-	bool IsHQ() const { return m_Settings.SrcMode >= SRCMODE_SPLINE && m_Settings.SrcMode < SRCMODE_DEFAULT; }
 private:
 	void InitFloatmixerTables();
 	void InitializeTablesFromScratch(bool force=false);
Index: soundlib/Snd_defs.h
===================================================================
--- soundlib/Snd_defs.h	(revision 9968)
+++ soundlib/Snd_defs.h	(working copy)
@@ -290,22 +290,55 @@
 {
 	// ATTENTION: Do not change ANY of these values, as they get written out to files in per instrument interpolation settings
 	// and old files have these exact values in them which should not change meaning.
-	SRCMODE_NEAREST   = 0,
-	SRCMODE_LINEAR    = 1,
-	SRCMODE_SPLINE    = 2,
-	SRCMODE_POLYPHASE = 3,
-	SRCMODE_FIRFILTER = 4,
-	SRCMODE_DEFAULT   = 5,
+	SRCMODE_NEAREST   = 0,  // 1 tap, no AA
+	SRCMODE_LINEAR    = 1,  // 2 tap, no AA
+	SRCMODE_CUBIC     = 2,  // 4 tap, no AA
+	SRCMODE_SINC8     = 4,  // 8 tap, no AA   (yes, index 4) (XMMS-ModPlug)
+	SRCMODE_SINC8LP   = 3,  // 8 tap, with AA (yes, index 3) (Polyphase)
 
-	SRCMODE_AMIGA = 0xFF,	// Not explicitely user-selectable
+	SRCMODE_DEFAULT   = 5,  // only used for instrument settings, not used inside the mixer
+
+	SRCMODE_AMIGA  = 0xFF,  // Not explicitely user-selectable
 };
 
-static inline bool IsKnownResamplingMode(int mode)
+namespace Resampling
 {
-	return (mode >= 0) && (mode < SRCMODE_DEFAULT);
+
+static inline std::array<ResamplingMode, 5> AllModes() noexcept { return { SRCMODE_NEAREST, SRCMODE_LINEAR, SRCMODE_CUBIC, SRCMODE_SINC8, SRCMODE_SINC8LP }; }
+
+static inline std::array<ResamplingMode, 6> AllModesWithDefault() noexcept { return { SRCMODE_NEAREST, SRCMODE_LINEAR, SRCMODE_CUBIC, SRCMODE_SINC8, SRCMODE_SINC8LP, SRCMODE_DEFAULT }; }
+
+static MPT_CONSTEXPR11_FUN ResamplingMode Default() noexcept { return SRCMODE_SINC8LP; }
+
+static MPT_CONSTEXPR11_FUN bool IsKnownMode(int mode) noexcept { return (mode >= 0) && (mode < SRCMODE_DEFAULT); }
+
+static MPT_CONSTEXPR11_FUN ResamplingMode ToKnownMode(int mode) noexcept
+{
+	return Resampling::IsKnownMode(mode) ? static_cast<ResamplingMode>(mode)
+		: (mode == SRCMODE_AMIGA) ? SRCMODE_LINEAR
+		: Resampling::Default();
 }
 
+static MPT_CONSTEXPR11_FUN int Length(ResamplingMode mode) noexcept
+{
+	return mode == SRCMODE_NEAREST ? 1
+		: mode == SRCMODE_LINEAR ? 2
+		: mode == SRCMODE_CUBIC ? 4
+		: mode == SRCMODE_SINC8 ? 8
+		: mode == SRCMODE_SINC8LP ? 8
+		: 0;
+}
 
+static MPT_CONSTEXPR11_FUN bool HasAA(ResamplingMode mode) noexcept { return (mode == SRCMODE_SINC8LP); }
+
+static MPT_CONSTEXPR11_FUN ResamplingMode AddAA(ResamplingMode mode) noexcept { return (mode == SRCMODE_SINC8) ? SRCMODE_SINC8LP : mode; }
+
+static MPT_CONSTEXPR11_FUN ResamplingMode RemoveAA(ResamplingMode mode) noexcept { return (mode == SRCMODE_SINC8LP) ? SRCMODE_SINC8 : mode; }
+
+}
+
+
+
 // Release node defines
 #define ENV_RELEASE_NODE_UNSET	0xFF
 #define NOT_YET_RELEASED		(-1)
Index: soundlib/Sndmix.cpp
===================================================================
--- soundlib/Sndmix.cpp	(revision 9968)
+++ soundlib/Sndmix.cpp	(working copy)
@@ -2330,11 +2330,11 @@
 			//if (pChn->nNewRightVol > 0xFFFF) pChn->nNewRightVol = 0xFFFF;
 			//if (pChn->nNewLeftVol > 0xFFFF) pChn->nNewLeftVol = 0xFFFF;
 
-			if(pChn->pModInstrument && IsKnownResamplingMode(pChn->pModInstrument->nResampling))
+			if(pChn->pModInstrument && Resampling::IsKnownMode(pChn->pModInstrument->nResampling))
 			{
 				// For defined resampling modes, use per-instrument resampling mode if set
 				pChn->resamplingMode = static_cast<uint8>(pChn->pModInstrument->nResampling);
-			} else if(IsKnownResamplingMode(m_nResampling))
+			} else if(Resampling::IsKnownMode(m_nResampling))
 			{
 				pChn->resamplingMode = static_cast<uint8>(m_nResampling);
 			} else if(m_SongFlags[SONG_ISAMIGA] && m_Resampler.m_Settings.emulateAmiga)
Index: soundlib/Tables.cpp
===================================================================
--- soundlib/Tables.cpp	(revision 9968)
+++ soundlib/Tables.cpp	(working copy)
@@ -853,42 +853,7 @@
 	}
 }
 
-#if 0
 
-// this code is currently unused
-
-static double GetSpline(double x, double c0, double c1, double c2, double c3)
-{
-	double Xo = c1;
-	double Xa = c0 - Xo;
-	double Xb = c2 - Xo;
-	double Ux = (Xb-Xa)/2;
-	double Vx = (c3 - Xo)/2;
-	double a = Vx+Ux-2*Xb;
-	double b = 3*Xb-2*Ux-Vx;
-	return (((a*x+b)*x)+Ux)*x+Xo;
-}
-
-
-static void getdownsample2x(short int *psinc)
-{
-	for (int i=0; i<SINC_PHASES; i++)
-	{
-		double x = (double)i * (double)(0.5/SINC_PHASES);
-		psinc[i*8+7] = (short int)(GetSpline(x,     0, 0, 0, 1) * 8192);
-		psinc[i*8+6] = (short int)(GetSpline(x+0.5, 0, 0, 0, 1) * 8192);
-		psinc[i*8+5] = (short int)(GetSpline(x,     0, 0, 1, 0) * 8192);
-		psinc[i*8+4] = (short int)(GetSpline(x+0.5, 0, 0, 1, 0) * 8192);
-		psinc[i*8+3] = (short int)(GetSpline(x,     0, 1, 0, 0) * 8192);
-		psinc[i*8+2] = (short int)(GetSpline(x+0.5, 0, 1, 0, 0) * 8192);
-		psinc[i*8+1] = (short int)(GetSpline(x,     1, 0, 0, 0) * 8192);
-		psinc[i*8+0] = (short int)(GetSpline(x+0.5, 1, 0, 0, 0) * 8192);
-	}
-}
-
-#endif
-
-
 #ifdef MODPLUG_TRACKER
 bool CResampler::StaticTablesInitialized = false;
 SINC_TYPE CResampler::gKaiserSinc[SINC_PHASES*8];     // Upsampling
@@ -938,12 +903,8 @@
 		InitFloatmixerTables();
 
 		getsinc(gKaiserSinc, 9.6377, 0.97);
-		//ericus' downsampling improvement.
-		//getsinc(gDownsample13x, 8.5, 3.0/4.0);
-		//getdownsample2x(gDownsample2x);
 		getsinc(gDownsample13x, 8.5, 0.5);
 		getsinc(gDownsample2x, 2.7625, 0.425);
-		//end ericus' downsampling improvement.
 
 		#ifdef MODPLUG_TRACKER
 			StaticTablesInitialized = true;
Index: soundlib/WindowedFIR.h
===================================================================
--- soundlib/WindowedFIR.h	(revision 9968)
+++ soundlib/WindowedFIR.h	(working copy)
@@ -48,25 +48,20 @@
 #define WFIR_LOG2WIDTH		3
 #define WFIR_WIDTH			(1L<<WFIR_LOG2WIDTH)
 // cutoff (1.0 == pi/2)
-//float WFIR_CUTOFF			= 0.5f;//0.75f;	//0.90f;
 // wfir type
 enum WFIRType
 {
-	WFIR_HANN			= 0,
-	WFIR_HAMMING		= 1,
-	WFIR_BLACKMANEXACT	= 2,
-	WFIR_BLACKMAN3T61	= 3,
-	WFIR_BLACKMAN3T67	= 4,
-	WFIR_BLACKMAN4T92	= 5,
-	WFIR_BLACKMAN4T74	= 6,
-	WFIR_KAISER4T		= 7,
+	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
 };
-//int WFIR_TYPE				= WFIR_KAISER4T;//WFIR_BLACKMANEXACT;
-//int WFIR_TYPE				= TrackerSettings::Instance().gbWFIRType;
 // wfir help
-#ifndef M_zPI
 #define M_zPI				3.1415926535897932384626433832795
-#endif
 #define M_zEPS				1e-8
 
 
Index: test/test.cpp
===================================================================
--- test/test.cpp	(revision 9968)
+++ test/test.cpp	(working copy)
@@ -2739,7 +2739,7 @@
 	VERIFY_EQUAL_NONCONT(pIns->nPPC, NOTE_MIDDLEC - 1);
 
 	VERIFY_EQUAL_NONCONT(pIns->nVolRampUp, 1200);
-	VERIFY_EQUAL_NONCONT(pIns->nResampling, (unsigned)SRCMODE_POLYPHASE);
+	VERIFY_EQUAL_NONCONT(pIns->nResampling, (unsigned)SRCMODE_SINC8LP);
 
 	VERIFY_EQUAL_NONCONT(pIns->IsCutoffEnabled(), false);
 	VERIFY_EQUAL_NONCONT(pIns->GetCutoff(), 0);
@@ -2869,7 +2869,7 @@
 	VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultRowsPerBeat, 6);
 	VERIFY_EQUAL_NONCONT(sndFile.m_nDefaultRowsPerMeasure, 12);
 	VERIFY_EQUAL_NONCONT(sndFile.m_dwCreatedWithVersion, MAKE_VERSION_NUMERIC(1, 19, 02, 05));
-	VERIFY_EQUAL_NONCONT(sndFile.m_nResampling, SRCMODE_POLYPHASE);
+	VERIFY_EQUAL_NONCONT(sndFile.m_nResampling, SRCMODE_SINC8LP);
 	VERIFY_EQUAL_NONCONT(sndFile.m_songArtist, MPT_USTRING("Tester"));
 	VERIFY_EQUAL_NONCONT(sndFile.m_tempoSwing.size(), 6);
 	VERIFY_EQUAL_NONCONT(sndFile.m_tempoSwing[0], 29360125);
@@ -3032,7 +3032,7 @@
 		VERIFY_EQUAL_NONCONT(pIns->nPPC, (NOTE_MIDDLEC - NOTE_MIN) + 6);	// F#5
 
 		VERIFY_EQUAL_NONCONT(pIns->nVolRampUp, 1200);
-		VERIFY_EQUAL_NONCONT(pIns->nResampling, (unsigned)SRCMODE_POLYPHASE);
+		VERIFY_EQUAL_NONCONT(pIns->nResampling, (unsigned)SRCMODE_SINC8LP);
 
 		VERIFY_EQUAL_NONCONT(pIns->IsCutoffEnabled(), true);
 		VERIFY_EQUAL_NONCONT(pIns->GetCutoff(), 0x32);
