View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001102 | OpenMPT | Audio I/O | public | 2018-03-11 20:06 | 2018-11-25 17:55 |
Reporter | IsaacNorman | Assigned To | manx | ||
Priority | low | Severity | feature | Reproducibility | N/A |
Status | resolved | Resolution | fixed | ||
Platform | x64 | OS | Windows | OS Version | 10 |
Product Version | OpenMPT 1.27.06.00 / libopenmpt 0.3.7 (upgrade first) | ||||
Target Version | OpenMPT 1.28.01.00 / libopenmpt 0.4.0 (upgrade first) | Fixed in Version | OpenMPT 1.28.01.00 / libopenmpt 0.4.0 (upgrade first) | ||
Summary | 0001102: Rename interpolation filters (was: Sinc interpolation for audio) | ||||
Description | I've been using OpenMPT for almost 10 years, and while I didn't find a use for it then, I see one now. I'd like to ask if there will ever be an implementation of sinc interpolation for samples? If this already exists with the current interpolations, then how do I adjust them so they "are" sinc interpolation? (Or at least "close enough"?) I see MilkyTracker has 2 sinc interpolation methods, one being more precise than the other because of having a higher lookup table than the other. (Albeit it is much slower with complex modules.) This would save me trouble of having to export my .mptm modules to .xm and then having to lose all of my VST support, which MilkyTracker does not support unfortunately... :\ | ||||
Tags | No tags attached. | ||||
Attached Files | resampler-cleanup-v3.patch (28,918 bytes)
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); resampler-cleanup-v4.patch (28,943 bytes)
Index: common/versionNumber.h =================================================================== --- common/versionNumber.h (revision 10070) +++ common/versionNumber.h (working copy) @@ -19,7 +19,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 28 #define VER_MINOR 00 -#define VER_MINORMINOR 17 +#define VER_MINORMINOR 18 //Numerical value of the version. #define MPT_VERSION_CURRENT MAKE_VERSION_NUMERIC(VER_MAJORMAJOR,VER_MAJOR,VER_MINOR,VER_MINORMINOR) Index: libopenmpt/libopenmpt_impl.cpp =================================================================== --- libopenmpt/libopenmpt_impl.cpp (revision 10070) +++ 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 10070) +++ 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 10070) +++ 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 10070) +++ mptrack/Mpdlgs.cpp (working copy) @@ -928,9 +928,7 @@ ON_WM_HSCROLL() ON_WM_VSCROLL() ON_CBN_SELCHANGE(IDC_COMBO_FILTER, &COptionsMixer::OnResamplerChanged) - ON_CBN_SELCHANGE(IDC_COMBO_FILTERWINDOW, &COptionsMixer::OnSettingsChanged) ON_CBN_SELCHANGE(IDC_COMBO_POLYPHONY, &COptionsMixer::OnSettingsChanged) - ON_EN_UPDATE(IDC_WFIRCUTOFF, &COptionsMixer::OnSettingsChanged) ON_EN_UPDATE(IDC_RAMPING_IN, &COptionsMixer::OnRampingChanged) ON_EN_UPDATE(IDC_RAMPING_OUT, &COptionsMixer::OnRampingChanged) ON_COMMAND(IDC_CHECK_SOFTPAN, &COptionsMixer::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 10070) +++ 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 10070) +++ mptrack/Mptrack.cpp (working copy) @@ -2064,24 +2064,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 10070) +++ mptrack/Mptrack.h (working copy) @@ -275,7 +275,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 10070) +++ 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 10070) +++ 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 10070) +++ 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 10070) +++ mptrack/TrackerSettings.cpp (working copy) @@ -74,29 +74,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 @@ -244,7 +221,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) @@ -546,6 +523,13 @@ m_SoundDeviceSettingsDefaults.UseHardwareTiming = m_SoundDeviceUseHardwareTiming; m_SoundDeviceSettingsUseOldDefaults = true; } + if(storedVersion < MAKE_VERSION_NUMERIC(1,28,00,18)) + { + // 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; @@ -678,7 +662,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 10070) +++ 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 10070) +++ 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 10070) +++ 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 10070) +++ 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 10070) +++ 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 10070) +++ 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 10070) +++ 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 10070) +++ test/test.cpp (working copy) @@ -2755,7 +2755,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); @@ -2885,7 +2885,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); @@ -3048,7 +3048,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); resampler-cleanup-v5.patch (28,900 bytes)
Index: common/versionNumber.h =================================================================== --- common/versionNumber.h (revision 10764) +++ common/versionNumber.h (working copy) @@ -21,7 +21,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 28 #define VER_MINOR 00 -#define VER_MINORMINOR 31 +#define VER_MINORMINOR 32 //Numerical value of the version. #define MPT_VERSION_CURRENT MAKE_VERSION_NUMERIC(VER_MAJORMAJOR,VER_MAJOR,VER_MINOR,VER_MINORMINOR) Index: libopenmpt/libopenmpt_impl.cpp =================================================================== --- libopenmpt/libopenmpt_impl.cpp (revision 10764) +++ libopenmpt/libopenmpt_impl.cpp (working copy) @@ -328,13 +328,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 ) { @@ -352,11 +352,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 10764) +++ 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 10764) +++ mptrack/Ctrl_ins.cpp (working copy) @@ -991,12 +991,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 10764) +++ mptrack/Mpdlgs.cpp (working copy) @@ -928,9 +928,7 @@ ON_WM_HSCROLL() ON_WM_VSCROLL() ON_CBN_SELCHANGE(IDC_COMBO_FILTER, &COptionsMixer::OnResamplerChanged) - ON_CBN_SELCHANGE(IDC_COMBO_FILTERWINDOW, &COptionsMixer::OnSettingsChanged) ON_CBN_SELCHANGE(IDC_COMBO_POLYPHONY, &COptionsMixer::OnSettingsChanged) - ON_EN_UPDATE(IDC_WFIRCUTOFF, &COptionsMixer::OnSettingsChanged) ON_EN_UPDATE(IDC_RAMPING_IN, &COptionsMixer::OnRampingChanged) ON_EN_UPDATE(IDC_RAMPING_OUT, &COptionsMixer::OnRampingChanged) ON_COMMAND(IDC_CHECK_SOFTPAN, &COptionsMixer::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 10764) +++ mptrack/Mpdlgs.h (working copy) @@ -90,8 +90,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 10764) +++ mptrack/Mptrack.cpp (working copy) @@ -2022,24 +2022,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 = _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 10764) +++ mptrack/Mptrack.h (working copy) @@ -274,7 +274,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 10764) +++ mptrack/mptrack.rc (working copy) @@ -2093,15 +2093,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 10764) +++ mptrack/resource.h (working copy) @@ -685,8 +685,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 10764) +++ mptrack/SampleEditorDialogs.cpp (working copy) @@ -534,12 +534,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 10764) +++ mptrack/TrackerSettings.cpp (working copy) @@ -74,29 +74,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 @@ -244,7 +221,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"), mpt::saturate_round<int32>(CResamplerSettings().gdWFIRCutoff * 100.0)) , ResamplerEmulateAmiga(conf, MPT_USTRING("Sound Settings"), MPT_USTRING("ResamplerEmulateAmiga"), true) @@ -546,6 +523,13 @@ m_SoundDeviceSettingsDefaults.UseHardwareTiming = m_SoundDeviceUseHardwareTiming; m_SoundDeviceSettingsUseOldDefaults = true; } + if(storedVersion < MAKE_VERSION_NUMERIC(1,28,00,32)) + { + // 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 = mpt::saturate_round<int32>(CResamplerSettings().gdWFIRCutoff * 100.0); + } if(storedVersion < MAKE_VERSION_NUMERIC(1,25,00,04)) { m_SoundDeviceDirectSoundOldDefaultIdentifier = true; @@ -678,7 +662,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 10764) +++ soundlib/Load_it.cpp (working copy) @@ -2381,7 +2381,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 10764) +++ 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 10764) +++ soundlib/Resampler.h (working copy) @@ -61,12 +61,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 { @@ -127,8 +127,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 10764) +++ soundlib/Snd_defs.h (working copy) @@ -299,22 +299,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 10764) +++ soundlib/Sndmix.cpp (working copy) @@ -2376,11 +2376,11 @@ //if (chn.nNewRightVol > 0xFFFF) chn.nNewRightVol = 0xFFFF; //if (chn.nNewLeftVol > 0xFFFF) chn.nNewLeftVol = 0xFFFF; - if(chn.pModInstrument && IsKnownResamplingMode(chn.pModInstrument->nResampling)) + if(chn.pModInstrument && Resampling::IsKnownMode(chn.pModInstrument->nResampling)) { // For defined resampling modes, use per-instrument resampling mode if set chn.resamplingMode = static_cast<uint8>(chn.pModInstrument->nResampling); - } else if(IsKnownResamplingMode(m_nResampling)) + } else if(Resampling::IsKnownMode(m_nResampling)) { chn.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 10764) +++ soundlib/Tables.cpp (working copy) @@ -748,42 +748,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 @@ -833,12 +798,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 10764) +++ soundlib/WindowedFIR.h (working copy) @@ -50,25 +50,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 10764) +++ test/test.cpp (working copy) @@ -3070,7 +3070,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); @@ -3200,7 +3200,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); @@ -3363,7 +3363,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); resampler-cleanup-v7.patch (28,900 bytes)
Index: common/versionNumber.h =================================================================== --- common/versionNumber.h (revision 10963) +++ common/versionNumber.h (working copy) @@ -21,7 +21,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 28 #define VER_MINOR 00 -#define VER_MINORMINOR 37 +#define VER_MINORMINOR 38 //Numerical value of the version. #define MPT_VERSION_CURRENT MAKE_VERSION_NUMERIC(VER_MAJORMAJOR,VER_MAJOR,VER_MINOR,VER_MINORMINOR) Index: libopenmpt/libopenmpt_impl.cpp =================================================================== --- libopenmpt/libopenmpt_impl.cpp (revision 10963) +++ libopenmpt/libopenmpt_impl.cpp (working copy) @@ -332,13 +332,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 ) { @@ -356,11 +356,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 10963) +++ 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 10963) +++ mptrack/Ctrl_ins.cpp (working copy) @@ -992,12 +992,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 10963) +++ mptrack/Mpdlgs.cpp (working copy) @@ -928,9 +928,7 @@ ON_WM_HSCROLL() ON_WM_VSCROLL() ON_CBN_SELCHANGE(IDC_COMBO_FILTER, &COptionsMixer::OnResamplerChanged) - ON_CBN_SELCHANGE(IDC_COMBO_FILTERWINDOW, &COptionsMixer::OnSettingsChanged) ON_CBN_SELCHANGE(IDC_COMBO_POLYPHONY, &COptionsMixer::OnSettingsChanged) - ON_EN_UPDATE(IDC_WFIRCUTOFF, &COptionsMixer::OnSettingsChanged) ON_EN_UPDATE(IDC_RAMPING_IN, &COptionsMixer::OnRampingChanged) ON_EN_UPDATE(IDC_RAMPING_OUT, &COptionsMixer::OnRampingChanged) ON_COMMAND(IDC_CHECK_SOFTPAN, &COptionsMixer::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 10963) +++ mptrack/Mpdlgs.h (working copy) @@ -90,8 +90,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 10963) +++ mptrack/Mptrack.cpp (working copy) @@ -2022,24 +2022,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 = _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 10963) +++ mptrack/Mptrack.h (working copy) @@ -269,7 +269,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 10963) +++ mptrack/mptrack.rc (working copy) @@ -2143,15 +2143,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 10963) +++ mptrack/resource.h (working copy) @@ -686,8 +686,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 10963) +++ mptrack/SampleEditorDialogs.cpp (working copy) @@ -534,12 +534,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 10963) +++ mptrack/TrackerSettings.cpp (working copy) @@ -74,29 +74,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 @@ -244,7 +221,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"), mpt::saturate_round<int32>(CResamplerSettings().gdWFIRCutoff * 100.0)) , ResamplerEmulateAmiga(conf, MPT_USTRING("Sound Settings"), MPT_USTRING("ResamplerEmulateAmiga"), true) @@ -546,6 +523,13 @@ m_SoundDeviceSettingsDefaults.UseHardwareTiming = m_SoundDeviceUseHardwareTiming; m_SoundDeviceSettingsUseOldDefaults = true; } + if(storedVersion < MAKE_VERSION_NUMERIC(1,28,00,38)) + { + // 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 = mpt::saturate_round<int32>(CResamplerSettings().gdWFIRCutoff * 100.0); + } if(storedVersion < MAKE_VERSION_NUMERIC(1,25,00,04)) { m_SoundDeviceDirectSoundOldDefaultIdentifier = true; @@ -678,7 +662,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 10963) +++ soundlib/Load_it.cpp (working copy) @@ -2366,7 +2366,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 10963) +++ 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 10963) +++ soundlib/Resampler.h (working copy) @@ -61,12 +61,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 { @@ -127,8 +127,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 10963) +++ soundlib/Snd_defs.h (working copy) @@ -297,22 +297,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 10963) +++ soundlib/Sndmix.cpp (working copy) @@ -2375,11 +2375,11 @@ //if (chn.nNewRightVol > 0xFFFF) chn.nNewRightVol = 0xFFFF; //if (chn.nNewLeftVol > 0xFFFF) chn.nNewLeftVol = 0xFFFF; - if(chn.pModInstrument && IsKnownResamplingMode(chn.pModInstrument->nResampling)) + if(chn.pModInstrument && Resampling::IsKnownMode(chn.pModInstrument->nResampling)) { // For defined resampling modes, use per-instrument resampling mode if set chn.resamplingMode = static_cast<uint8>(chn.pModInstrument->nResampling); - } else if(IsKnownResamplingMode(m_nResampling)) + } else if(Resampling::IsKnownMode(m_nResampling)) { chn.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 10963) +++ soundlib/Tables.cpp (working copy) @@ -749,42 +749,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 @@ -834,12 +799,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 10963) +++ soundlib/WindowedFIR.h (working copy) @@ -50,25 +50,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 10963) +++ test/test.cpp (working copy) @@ -3077,7 +3077,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); @@ -3207,7 +3207,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); @@ -3370,7 +3370,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); resampler-cleanup-v8.patch (28,900 bytes)
Index: common/versionNumber.h =================================================================== --- common/versionNumber.h (revision 10980) +++ common/versionNumber.h (working copy) @@ -21,7 +21,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 28 #define VER_MINOR 00 -#define VER_MINORMINOR 40 +#define VER_MINORMINOR 41 //Numerical value of the version. #define MPT_VERSION_CURRENT MAKE_VERSION_NUMERIC(VER_MAJORMAJOR,VER_MAJOR,VER_MINOR,VER_MINORMINOR) Index: libopenmpt/libopenmpt_impl.cpp =================================================================== --- libopenmpt/libopenmpt_impl.cpp (revision 10980) +++ libopenmpt/libopenmpt_impl.cpp (working copy) @@ -332,13 +332,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 ) { @@ -356,11 +356,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 10980) +++ 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 10980) +++ mptrack/Ctrl_ins.cpp (working copy) @@ -992,12 +992,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 10980) +++ mptrack/Mpdlgs.cpp (working copy) @@ -928,9 +928,7 @@ ON_WM_HSCROLL() ON_WM_VSCROLL() ON_CBN_SELCHANGE(IDC_COMBO_FILTER, &COptionsMixer::OnResamplerChanged) - ON_CBN_SELCHANGE(IDC_COMBO_FILTERWINDOW, &COptionsMixer::OnSettingsChanged) ON_CBN_SELCHANGE(IDC_COMBO_POLYPHONY, &COptionsMixer::OnSettingsChanged) - ON_EN_UPDATE(IDC_WFIRCUTOFF, &COptionsMixer::OnSettingsChanged) ON_EN_UPDATE(IDC_RAMPING_IN, &COptionsMixer::OnRampingChanged) ON_EN_UPDATE(IDC_RAMPING_OUT, &COptionsMixer::OnRampingChanged) ON_COMMAND(IDC_CHECK_SOFTPAN, &COptionsMixer::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 10980) +++ mptrack/Mpdlgs.h (working copy) @@ -90,8 +90,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 10980) +++ mptrack/Mptrack.cpp (working copy) @@ -2026,24 +2026,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 = _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 10980) +++ mptrack/Mptrack.h (working copy) @@ -269,7 +269,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 10980) +++ mptrack/mptrack.rc (working copy) @@ -2159,15 +2159,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 10980) +++ mptrack/resource.h (working copy) @@ -686,8 +686,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 10980) +++ mptrack/SampleEditorDialogs.cpp (working copy) @@ -534,12 +534,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 10980) +++ mptrack/TrackerSettings.cpp (working copy) @@ -74,29 +74,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 @@ -245,7 +222,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"), mpt::saturate_round<int32>(CResamplerSettings().gdWFIRCutoff * 100.0)) , ResamplerEmulateAmiga(conf, MPT_USTRING("Sound Settings"), MPT_USTRING("ResamplerEmulateAmiga"), true) @@ -556,6 +533,13 @@ m_SoundDeviceSettingsDefaults.UseHardwareTiming = m_SoundDeviceUseHardwareTiming; m_SoundDeviceSettingsUseOldDefaults = true; } + if(storedVersion < MAKE_VERSION_NUMERIC(1,28,00,41)) + { + // 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 = mpt::saturate_round<int32>(CResamplerSettings().gdWFIRCutoff * 100.0); + } if(storedVersion < MAKE_VERSION_NUMERIC(1,25,00,04)) { m_SoundDeviceDirectSoundOldDefaultIdentifier = true; @@ -726,7 +710,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 10980) +++ soundlib/Load_it.cpp (working copy) @@ -2369,7 +2369,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 10980) +++ 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 10980) +++ soundlib/Resampler.h (working copy) @@ -61,12 +61,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 { @@ -127,8 +127,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 10980) +++ soundlib/Snd_defs.h (working copy) @@ -297,22 +297,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 10980) +++ soundlib/Sndmix.cpp (working copy) @@ -2375,11 +2375,11 @@ //if (chn.nNewRightVol > 0xFFFF) chn.nNewRightVol = 0xFFFF; //if (chn.nNewLeftVol > 0xFFFF) chn.nNewLeftVol = 0xFFFF; - if(chn.pModInstrument && IsKnownResamplingMode(chn.pModInstrument->nResampling)) + if(chn.pModInstrument && Resampling::IsKnownMode(chn.pModInstrument->nResampling)) { // For defined resampling modes, use per-instrument resampling mode if set chn.resamplingMode = static_cast<uint8>(chn.pModInstrument->nResampling); - } else if(IsKnownResamplingMode(m_nResampling)) + } else if(Resampling::IsKnownMode(m_nResampling)) { chn.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 10980) +++ soundlib/Tables.cpp (working copy) @@ -750,42 +750,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 @@ -835,12 +800,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 10980) +++ soundlib/WindowedFIR.h (working copy) @@ -50,25 +50,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 10980) +++ test/test.cpp (working copy) @@ -3077,7 +3077,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); @@ -3207,7 +3207,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); @@ -3370,7 +3370,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); | ||||
Has the bug occurred in previous versions? | |||||
Tested code revision (in case you know it) | |||||
The 4-tap filter and both 8-tap filters are implemented as truncated sinc filters. Naming of interpolation/resampling filters is confusing at best, because there is just no well established standard in how to name them. We should really improve documentation, filter selection UI and naming of the filters. |
|
I agree with you on the last statement, because I've never heard of the last two filters. If they're MPT-exclusive then that explains it. I've only heard of the standard Linear, Cubic, Sinc, (the rare Gaussian that no one seems to use for some reason...), and FIR interpolations. It's a shame that MPT doesn't include a couple more of those, because other applications do. I hope to see the descriptions, documentations and names updated in a future release so they're more precise. |
|
Both 8-tap filters in OpenMPT can rightfully be called FIR, can rightfully be called Polyphase, can rightfully be called Sinc, can even rightfully be called Polynomial. I guess you are right about the fact that "Sinc" might be a more usual name. |
|
Will the proper names be implemented in a nearby future release? (Yes, I am an audiophile when it comes to quality.) |
|
Including more filters just "because others have it" or to fill up the buzzword bingo card leads us exactly nowhere. As manx says, it's just as appropriate to call it Polyphase as to call it a FIR filter or Sinc filter. All of those just describe different details of the filter. None of these terms describe the filter in its full nature. |
|
Leaving aside "XMMS-ModPlug", which is really no useful description of the filter at all, there simply is no naming scheme that is more "proper" than any other.
The default ("Polyphase") is the best filter currently available. I think, we should rename "XMMS-ModPlug" to "Sinc (8 taps)" and "Polyphase" to "Sinc with Low-Pass (8 taps)" and re-order the list so that "Sinc with Low-Pass (8 taps)" comes after ""Sinc (8 taps)", making it increasing in quality. While at it, we should also remove the selection of the windowing function and the filter bandwidth selection. These really serve no purpose other than confuse users. We can keep them as hidden options. @IsaacNorman: Note that none of these changes will change any behaviour. This is PURELY cosmetic and only about using (hopefully) clearer naming. |
|
I do not have a particularly strong opinion about the "Sinc" name. However, "FIR" would not be useful at all, because by context each and every filter we could implement here would be FIR. "Polyphase" is kind of a long name and is afaik not a very common description used in the wild. resampler-cleanup-v1.patch (28,622 bytes)
Index: common/versionNumber.h =================================================================== --- common/versionNumber.h (revision 9920) +++ common/versionNumber.h (working copy) @@ -19,7 +19,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 28 #define VER_MINOR 00 -#define VER_MINORMINOR 14 +#define VER_MINORMINOR 15 //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 9920) +++ libopenmpt/libopenmpt_impl.cpp (working copy) @@ -316,11 +316,11 @@ } 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; } else if ( length >= 2 ) { @@ -343,8 +343,8 @@ case SRCMODE_SPLINE: 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 9920) +++ 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 9920) +++ 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 9920) +++ 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 9920) +++ 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 9920) +++ 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"); + result = _T("Linear"); + break; 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 = (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(" w/ Low-Pass") : _T(" w/ 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 9920) +++ 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 9920) +++ 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 9920) +++ 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 9920) +++ 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 9920) +++ 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,15)) + { + // 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 9920) +++ soundlib/Load_it.cpp (working copy) @@ -2358,7 +2358,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 9920) +++ soundlib/MixFuncTable.cpp (working copy) @@ -80,8 +80,8 @@ 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_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 9920) +++ 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 9920) +++ 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_SPLINE = 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) (Ericus-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() { return { SRCMODE_NEAREST, SRCMODE_LINEAR, SRCMODE_SPLINE, SRCMODE_SINC8, SRCMODE_SINC8LP }; } + +static inline std::array<ResamplingMode, 6> AllModesWithDefault() { return { SRCMODE_NEAREST, SRCMODE_LINEAR, SRCMODE_SPLINE, SRCMODE_SINC8, SRCMODE_SINC8LP, SRCMODE_DEFAULT }; } + +static MPT_CONSTEXPR11_FUN ResamplingMode Default() { return SRCMODE_SINC8LP; } + +static MPT_CONSTEXPR11_FUN bool IsKnownMode(int mode) { return (mode >= 0) && (mode < SRCMODE_DEFAULT); } + +static MPT_CONSTEXPR11_FUN ResamplingMode ToKnownMode(int mode) +{ + return Resampling::IsKnownMode(mode) ? static_cast<ResamplingMode>(mode) + : (mode == SRCMODE_AMIGA) ? SRCMODE_LINEAR + : Resampling::Default(); } +static MPT_CONSTEXPR11_FUN int Length(ResamplingMode mode) +{ + return mode == SRCMODE_NEAREST ? 1 + : mode == SRCMODE_LINEAR ? 2 + : mode == SRCMODE_SPLINE ? 4 + : mode == SRCMODE_SINC8 ? 8 + : mode == SRCMODE_SINC8LP ? 8 + : 0; +} +static MPT_CONSTEXPR11_FUN bool HasAA(ResamplingMode mode) { return (mode == SRCMODE_SINC8LP); } + +static MPT_CONSTEXPR11_FUN ResamplingMode AddAA(ResamplingMode mode) { return (mode == SRCMODE_SINC8) ? SRCMODE_SINC8LP : mode; } + +static MPT_CONSTEXPR11_FUN ResamplingMode RemoveAA(ResamplingMode mode) { 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 9920) +++ 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 9920) +++ 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 9920) +++ 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 9920) +++ test/test.cpp (working copy) @@ -2716,7 +2716,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); @@ -2846,7 +2846,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); @@ -3009,7 +3009,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); |
|
Also, on the topic of "why not add more interpolation types": Based on its mathematical properties, sinc resampling is ideal (but the resulting quality of course depends on the number of taps), so there really is no practical reason to implement other filter types. In the best case, you won't hear a difference, and in the worst case they sound worse.
I agree about the windowing function, but I think especially when taking higher mixing rates > 48 kHz into account, it makes sense to keep this configurable. On the other hand, most people do not understand what this option really does and increase the bandwidth to its maximum value because it sounds "brighter" (without realizing that it also causes more aliasing). |
|
Updated patch, no functional changes. resampler-cleanup-v2.patch (28,332 bytes)
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,15)) + { + // 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); |
|
|
|
Implemented in r10998 . |
|
Date Modified | Username | Field | Change |
---|---|---|---|
2018-03-11 20:06 | IsaacNorman | New Issue | |
2018-03-11 20:25 | manx | Note Added: 0003475 | |
2018-03-11 20:26 | manx | Target Version | => OpenMPT 1.28.01.00 / libopenmpt 0.4.0 (upgrade first) |
2018-03-11 20:37 | IsaacNorman | Note Added: 0003476 | |
2018-03-11 20:42 | manx | Note Added: 0003477 | |
2018-03-11 20:47 | IsaacNorman | Note Added: 0003478 | |
2018-03-12 11:28 | Saga Musix | Note Added: 0003479 | |
2018-03-12 16:06 | manx | Note Added: 0003480 | |
2018-03-12 16:06 | manx | Assigned To | => manx |
2018-03-12 16:06 | manx | Status | new => assigned |
2018-03-12 16:11 | manx | File Added: resampler-cleanup-v1.patch | |
2018-03-12 16:11 | manx | Note Added: 0003481 | |
2018-03-12 16:13 | manx | Summary | Sinc interpolation for audio => Rename interpolation filters (was: Sinc interpolation for audio) |
2018-03-12 16:13 | Saga Musix | Note Added: 0003482 | |
2018-03-12 16:16 | manx | Note Edited: 0003480 | |
2018-03-21 11:31 | manx | File Added: resampler-cleanup-v2.patch | |
2018-03-21 11:31 | manx | Note Added: 0003487 | |
2018-03-21 15:04 | manx | File Added: resampler-cleanup-v3.patch | |
2018-04-11 09:13 | manx | File Added: resampler-cleanup-v4.patch | |
2018-09-12 13:43 | manx | File Added: resampler-cleanup-v5.patch | |
2018-11-04 15:12 | manx | File Added: resampler-cleanup-v7.patch | |
2018-11-13 09:50 | manx | File Added: resampler-cleanup-v8.patch | |
2018-11-20 17:22 | manx | Note Added: 0003720 | |
2018-11-25 17:55 | manx | Status | assigned => resolved |
2018-11-25 17:55 | manx | Resolution | open => fixed |
2018-11-25 17:55 | manx | Fixed in Version | => OpenMPT 1.28.01.00 / libopenmpt 0.4.0 (upgrade first) |
2018-11-25 17:55 | manx | Note Added: 0003744 |