From 3815ba0baf9aa497c37c6032a35681a5c58b6001 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Mon, 14 Mar 2022 04:35:36 -0700 Subject: [PATCH] libOpenMPT Legacy: Updated to version 0.5.17 Signed-off-by: Christopher Snowhill --- Frameworks/OpenMPT.old/OpenMPT/build/dist.mk | 6 +- .../OpenMPT/build/svn_version/svn_version.h | 8 +- .../OpenMPT/common/versionNumber.h | 2 +- .../OpenMPT/libopenmpt/dox/changelog.md | 15 ++++ .../OpenMPT/libopenmpt/libopenmpt.hpp | 8 +- .../OpenMPT/libopenmpt/libopenmpt_config.h | 16 ++++ .../OpenMPT/libopenmpt/libopenmpt_ext.hpp | 20 +++-- .../OpenMPT/libopenmpt/libopenmpt_impl.cpp | 10 ++- .../OpenMPT/libopenmpt/libopenmpt_version.h | 2 +- .../OpenMPT/libopenmpt/libopenmpt_version.mk | 4 +- .../OpenMPT.old/OpenMPT/soundlib/FloatMixer.h | 42 ++++----- .../OpenMPT.old/OpenMPT/soundlib/IntMixer.h | 87 ++++++++++--------- .../OpenMPT/soundlib/MixerInterface.h | 18 +--- .../OpenMPT.old/OpenMPT/soundlib/Snd_fx.cpp | 19 ++-- .../OpenMPT/soundlib/plugins/LFOPlugin.cpp | 2 +- 15 files changed, 150 insertions(+), 109 deletions(-) diff --git a/Frameworks/OpenMPT.old/OpenMPT/build/dist.mk b/Frameworks/OpenMPT.old/OpenMPT/build/dist.mk index 39531d178..5a9411b72 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/build/dist.mk +++ b/Frameworks/OpenMPT.old/OpenMPT/build/dist.mk @@ -1,4 +1,4 @@ -MPT_SVNVERSION=16768 -MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.16 -MPT_SVNDATE=2022-01-30T16:50:10.915999Z +MPT_SVNVERSION=17112 +MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.17 +MPT_SVNDATE=2022-03-13T14:51:00.976461Z diff --git a/Frameworks/OpenMPT.old/OpenMPT/build/svn_version/svn_version.h b/Frameworks/OpenMPT.old/OpenMPT/build/svn_version/svn_version.h index 41e7534bb..b92cdb9e9 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/build/svn_version/svn_version.h +++ b/Frameworks/OpenMPT.old/OpenMPT/build/svn_version/svn_version.h @@ -1,10 +1,10 @@ #pragma once -#define OPENMPT_VERSION_SVNVERSION "16768" -#define OPENMPT_VERSION_REVISION 16768 +#define OPENMPT_VERSION_SVNVERSION "17112" +#define OPENMPT_VERSION_REVISION 17112 #define OPENMPT_VERSION_DIRTY 0 #define OPENMPT_VERSION_MIXEDREVISIONS 0 -#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.16" -#define OPENMPT_VERSION_DATE "2022-01-30T16:50:10.915999Z" +#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.17" +#define OPENMPT_VERSION_DATE "2022-03-13T14:51:00.976461Z" #define OPENMPT_VERSION_IS_PACKAGE 1 diff --git a/Frameworks/OpenMPT.old/OpenMPT/common/versionNumber.h b/Frameworks/OpenMPT.old/OpenMPT/common/versionNumber.h index c0308f759..9be0a5c9b 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/common/versionNumber.h +++ b/Frameworks/OpenMPT.old/OpenMPT/common/versionNumber.h @@ -18,6 +18,6 @@ OPENMPT_NAMESPACE_BEGIN #define VER_MAJORMAJOR 1 #define VER_MAJOR 29 #define VER_MINOR 15 -#define VER_MINORMINOR 04 +#define VER_MINORMINOR 06 OPENMPT_NAMESPACE_END diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/dox/changelog.md b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/dox/changelog.md index 23a0495c5..7c7f9cf29 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/dox/changelog.md +++ b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/dox/changelog.md @@ -5,6 +5,21 @@ Changelog {#changelog} For fully detailed change log, please see the source repository directly. This is just a high-level summary. +### libopenmpt 0.5.17 (2022-03-13) + + * [**Sec**] Possible out-of-bounds write in malformed IT / XM / MPTM files + using the internal LFO plugin. (r17081) + * [**Sec**] Possible out-of-bounds read when using Amiga BLEP interpolation + with extremely high-pitched notes. (r17082) + + * MO3: Pattern indices 254 / 255 were not treated as playable patterns even if + the original file was a MOD / XM. + * Correctly apply ST3-style effect memory when seeking in S3M files. + * Command S (S3M / IT style) effect memory was not applied when seeking. + + * FLAC: Update to v1.3.4 (2022-02-21). + * pugixml: Update to v1.12.1 (2022-02-16). + ### libopenmpt 0.5.16 (2022-01-30) * [**Bug**] Possible hang with malformed DMF, DSM, MED and OKT files diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt.hpp b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt.hpp index e51b6bfb3..a7bad1dc2 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt.hpp +++ b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt.hpp @@ -127,12 +127,12 @@ /*! \defgroup libopenmpt_cpp libopenmpt C++ */ +namespace openmpt { + /*! \addtogroup libopenmpt_cpp @{ */ -namespace openmpt { - #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable:4275) @@ -1163,10 +1163,10 @@ public: }; // class module -} // namespace openmpt - /*! @} */ +} // namespace openmpt + #endif // LIBOPENMPT_HPP diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_config.h b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_config.h index 562f9054b..d73019ba8 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_config.h +++ b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_config.h @@ -22,6 +22,14 @@ #define LIBOPENMPT_CXX_API #undef LIBOPENMPT_CXX_API +/*! + @} +*/ + +/*! \addtogroup libopenmpt_c + @{ +*/ + /*! \brief Defined if libopenmpt/libopenmpt_stream_callbacks_buffer.h exists. */ #define LIBOPENMPT_STREAM_CALLBACKS_BUFFER @@ -51,6 +59,14 @@ */ #define LIBOPENMPT_STREAM_CALLBACKS_FILE +/*! + @} +*/ + +/*! \addtogroup libopenmpt + @{ +*/ + #if defined(__DOXYGEN__) #define LIBOPENMPT_API_HELPER_EXPORT diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_ext.hpp b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_ext.hpp index 12452b405..1134e7c5d 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_ext.hpp +++ b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_ext.hpp @@ -26,12 +26,12 @@ /*! \defgroup libopenmpt_ext_cpp libopenmpt_ext C++ */ +namespace openmpt { + /*! \addtogroup libopenmpt_ext_cpp @{ */ -namespace openmpt { - class module_ext_impl; class LIBOPENMPT_CXX_API module_ext : public module { @@ -77,8 +77,16 @@ public: }; // class module_ext +/*! + @} +*/ + namespace ext { +/*! \addtogroup libopenmpt_ext_cpp + @{ +*/ + #define LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE(name) \ static const char name ## _id [] = # name ; \ class name; \ @@ -300,12 +308,12 @@ class interactive { #undef LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE #undef LIBOPENMPT_EXT_CXX_INTERFACE -} // namespace ext - -} // namespace openmpt - /*! @} */ +} // namespace ext + +} // namespace openmpt + #endif // LIBOPENMPT_EXT_HPP diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_impl.cpp b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_impl.cpp index 800a84291..22b58241d 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_impl.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_impl.cpp @@ -34,12 +34,20 @@ #include "soundlib/mod_specifications.h" #include "soundlib/AudioReadTarget.h" +#if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT +#include +#endif // MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT + OPENMPT_NAMESPACE_BEGIN #if !defined(MPT_BUILD_SILENCE_LIBOPENMPT_CONFIGURATION_WARNINGS) #if MPT_OS_WINDOWS && MPT_OS_WINDOWS_WINRT -#if defined(_WIN32_WINNT) +#if defined(NTDDI_VERSION) +#if (NTDDI_VERSION < 0x06020000) +MPT_WARNING("Warning: libopenmpt for WinRT is built with reduced functionality. Please #define NTDDI_VERSION 0x0602000.") +#endif +#elif defined(_WIN32_WINNT) #if (_WIN32_WINNT < 0x0602) MPT_WARNING("Warning: libopenmpt for WinRT is built with reduced functionality. Please #define _WIN32_WINNT 0x0602.") #endif // _WIN32_WINNT diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.h b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.h index ea5ecda81..55d997d38 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.h +++ b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.h @@ -19,7 +19,7 @@ /*! \brief libopenmpt minor version number */ #define OPENMPT_API_VERSION_MINOR 5 /*! \brief libopenmpt patch version number */ -#define OPENMPT_API_VERSION_PATCH 16 +#define OPENMPT_API_VERSION_PATCH 17 /*! \brief libopenmpt pre-release tag */ #define OPENMPT_API_VERSION_PREREL "" /*! \brief libopenmpt pre-release flag */ diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.mk b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.mk index 992bc8804..e153fc769 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.mk +++ b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.mk @@ -1,8 +1,8 @@ LIBOPENMPT_VERSION_MAJOR=0 LIBOPENMPT_VERSION_MINOR=5 -LIBOPENMPT_VERSION_PATCH=16 +LIBOPENMPT_VERSION_PATCH=17 LIBOPENMPT_VERSION_PREREL= LIBOPENMPT_LTVER_CURRENT=2 -LIBOPENMPT_LTVER_REVISION=16 +LIBOPENMPT_LTVER_REVISION=17 LIBOPENMPT_LTVER_AGE=2 diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/FloatMixer.h b/Frameworks/OpenMPT.old/OpenMPT/soundlib/FloatMixer.h index 8f9301ff5..ca80385aa 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/FloatMixer.h +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/FloatMixer.h @@ -41,9 +41,7 @@ typedef IntToFloatTraits<2, 2, mixsample_t, int16, -int16_min> Int16SToFloatS; template struct LinearInterpolation { - MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &) { } - - MPT_FORCEINLINE void End(const ModChannel &) { } + MPT_FORCEINLINE LinearInterpolation(const ModChannel &, const CResampler &, unsigned int) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const inBuffer, const uint32 posLo) { @@ -64,8 +62,7 @@ struct LinearInterpolation template struct FastSincInterpolation { - MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &) { } - MPT_FORCEINLINE void End(const ModChannel &) { } + MPT_FORCEINLINE FastSincInterpolation(const ModChannel &, const CResampler &, unsigned int) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const inBuffer, const uint32 posLo) { @@ -89,14 +86,12 @@ struct PolyphaseInterpolation { const typename Traits::output_t *sinc; - MPT_FORCEINLINE void Start(const ModChannel &chn, const CResampler &resampler) + MPT_FORCEINLINE PolyphaseInterpolation(const ModChannel &chn, const CResampler &resampler, unsigned int) { sinc = (((chn.increment > SamplePosition(0x130000000ll)) || (chn.increment < -SamplePosition(-0x130000000ll))) ? (((chn.increment > SamplePosition(0x180000000ll)) || (chn.increment < SamplePosition(-0x180000000ll))) ? resampler.gDownsample2x : resampler.gDownsample13x) : resampler.gKaiserSinc); } - MPT_FORCEINLINE void End(const ModChannel &) { } - MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const inBuffer, const uint32 posLo) { static_assert(static_cast(Traits::numChannelsIn) <= static_cast(Traits::numChannelsOut), "Too many input channels"); @@ -123,13 +118,11 @@ struct FIRFilterInterpolation { const typename Traits::output_t *WFIRlut; - MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &resampler) + MPT_FORCEINLINE FIRFilterInterpolation(const ModChannel &, const CResampler &resampler, unsigned int) { WFIRlut = resampler.m_WindowedFIR.lut; } - MPT_FORCEINLINE void End(const ModChannel &) { } - MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const inBuffer, const uint32 posLo) { static_assert(static_cast(Traits::numChannelsIn) <= static_cast(Traits::numChannelsOut), "Too many input channels"); @@ -159,30 +152,30 @@ struct NoRamp { typename Traits::output_t lVol, rVol; - MPT_FORCEINLINE void Start(const ModChannel &chn) + MPT_FORCEINLINE NoRamp(const ModChannel &chn) { lVol = static_cast(chn.leftVol) * (1.0f / 4096.0f); rVol = static_cast(chn.rightVol) * (1.0f / 4096.0f); } - - MPT_FORCEINLINE void End(const ModChannel &) { } }; struct Ramp { + ModChannel &channel; int32 lRamp, rRamp; - MPT_FORCEINLINE void Start(const ModChannel &chn) + MPT_FORCEINLINE Ramp(ModChannel &chn) + : channel{chn} { lRamp = chn.rampLeftVol; rRamp = chn.rampRightVol; } - MPT_FORCEINLINE void End(ModChannel &chn) + MPT_FORCEINLINE ~Ramp() { - chn.rampLeftVol = lRamp; chn.leftVol = lRamp >> VOLUMERAMPPRECISION; - chn.rampRightVol = rRamp; chn.rightVol = rRamp >> VOLUMERAMPPRECISION; + channel.rampLeftVol = lRamp; channel.leftVol = lRamp >> VOLUMERAMPPRECISION; + channel.rampRightVol = rRamp; channel.rightVol = rRamp >> VOLUMERAMPPRECISION; } }; @@ -259,8 +252,7 @@ struct MixStereoRamp : public Ramp template struct NoFilter { - MPT_FORCEINLINE void Start(const ModChannel &) { } - MPT_FORCEINLINE void End(const ModChannel &) { } + MPT_FORCEINLINE NoFilter(const ModChannel &) { } MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &, const ModChannel &) { } }; @@ -270,10 +262,12 @@ struct NoFilter template struct ResonantFilter { + ModChannel &channel; // Filter history typename Traits::output_t fy[Traits::numChannelsIn][2]; - MPT_FORCEINLINE void Start(const ModChannel &chn) + MPT_FORCEINLINE ResonantFilter(ModChannel &chn) + : channel{chn} { for(int i = 0; i < Traits::numChannelsIn; i++) { @@ -282,12 +276,12 @@ struct ResonantFilter } } - MPT_FORCEINLINE void End(ModChannel &chn) + MPT_FORCEINLINE ~ResonantFilter(ModChannel &chn) { for(int i = 0; i < Traits::numChannelsIn; i++) { - chn.nFilter_Y[i][0] = fy[i][0]; - chn.nFilter_Y[i][1] = fy[i][1]; + channel.nFilter_Y[i][0] = fy[i][0]; + channel.nFilter_Y[i][1] = fy[i][1]; } } diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/IntMixer.h b/Frameworks/OpenMPT.old/OpenMPT/soundlib/IntMixer.h index 90810bd11..cacf2cd39 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/IntMixer.h +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/IntMixer.h @@ -50,23 +50,34 @@ template struct AmigaBlepInterpolation { SamplePosition subIncrement; - Paula::State *paula; - const Paula::BlepArray *WinSincIntegral; - int numSteps; + Paula::State &paula; + const Paula::BlepArray &WinSincIntegral; + const int numSteps; + unsigned int remainingSamples = 0; - MPT_FORCEINLINE void Start(ModChannel &chn, const CResampler &resampler) + MPT_FORCEINLINE AmigaBlepInterpolation(ModChannel &chn, const CResampler &resampler, unsigned int numSamples) + : paula{chn.paulaState} + , WinSincIntegral{resampler.blepTables.GetAmigaTable(resampler.m_Settings.emulateAmiga, chn.dwFlags[CHN_AMIGAFILTER])} + , numSteps{chn.paulaState.numSteps} { - paula = &chn.paulaState; - numSteps = paula->numSteps; - WinSincIntegral = &resampler.blepTables.GetAmigaTable(resampler.m_Settings.emulateAmiga, chn.dwFlags[CHN_AMIGAFILTER]); if(numSteps) + { subIncrement = chn.increment / numSteps; + // May we read past the start or end of sample if we do partial sample increments? + // If that's the case, don't apply any sub increments on the source sample if we reached the last output sample + // Note that this should only happen with notes well outside the Amiga note range, e.g. in software-mixed formats like MED + const int32 targetPos = (chn.position + chn.increment * numSamples).GetInt(); + if(static_cast(targetPos) > chn.nLength) + remainingSamples = numSamples; + } + } - MPT_FORCEINLINE void End(const ModChannel &) { } - MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const MPT_RESTRICT inBuffer, const uint32 posLo) { + if(--remainingSamples == 0) + subIncrement = {}; + SamplePosition pos(0, posLo); // First, process steps of full length (one Amiga clock interval) for(int step = numSteps; step > 0; step--) @@ -75,26 +86,26 @@ struct AmigaBlepInterpolation int32 posInt = pos.GetInt() * Traits::numChannelsIn; for(int32 i = 0; i < Traits::numChannelsIn; i++) inSample += Traits::Convert(inBuffer[posInt + i]); - paula->InputSample(static_cast(inSample / (4 * Traits::numChannelsIn))); - paula->Clock(Paula::MINIMUM_INTERVAL); + paula.InputSample(static_cast(inSample / (4 * Traits::numChannelsIn))); + paula.Clock(Paula::MINIMUM_INTERVAL); pos += subIncrement; } - paula->remainder += paula->stepRemainder; + paula.remainder += paula.stepRemainder; // Now, process any remaining integer clock amount < MINIMUM_INTERVAL - uint32 remainClocks = paula->remainder.GetInt(); + uint32 remainClocks = paula.remainder.GetInt(); if(remainClocks) { typename Traits::output_t inSample = 0; int32 posInt = pos.GetInt() * Traits::numChannelsIn; for(int32 i = 0; i < Traits::numChannelsIn; i++) inSample += Traits::Convert(inBuffer[posInt + i]); - paula->InputSample(static_cast(inSample / (4 * Traits::numChannelsIn))); - paula->Clock(remainClocks); - paula->remainder.RemoveInt(); + paula.InputSample(static_cast(inSample / (4 * Traits::numChannelsIn))); + paula.Clock(remainClocks); + paula.remainder.RemoveInt(); } - auto out = paula->OutputSample(*WinSincIntegral); + auto out = paula.OutputSample(WinSincIntegral); for(int i = 0; i < Traits::numChannelsOut; i++) outSample[i] = out; } @@ -104,9 +115,7 @@ struct AmigaBlepInterpolation template struct LinearInterpolation { - MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &) { } - - MPT_FORCEINLINE void End(const ModChannel &) { } + MPT_FORCEINLINE LinearInterpolation(const ModChannel &, const CResampler &, unsigned int) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const MPT_RESTRICT inBuffer, const uint32 posLo) { @@ -127,8 +136,7 @@ struct LinearInterpolation template struct FastSincInterpolation { - MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &) { } - MPT_FORCEINLINE void End(const ModChannel &) { } + MPT_FORCEINLINE FastSincInterpolation(const ModChannel &, const CResampler &, unsigned int) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const MPT_RESTRICT inBuffer, const uint32 posLo) { @@ -152,7 +160,7 @@ struct PolyphaseInterpolation { const SINC_TYPE *sinc; - MPT_FORCEINLINE void Start(const ModChannel &chn, const CResampler &resampler) + MPT_FORCEINLINE PolyphaseInterpolation(const ModChannel &chn, const CResampler &resampler, unsigned int) { #ifdef MODPLUG_TRACKER // Otherwise causes "warning C4100: 'resampler' : unreferenced formal parameter" @@ -164,8 +172,6 @@ struct PolyphaseInterpolation (((chn.increment > SamplePosition(0x180000000ll)) || (chn.increment < SamplePosition(-0x180000000ll))) ? resampler.gDownsample2x : resampler.gDownsample13x) : resampler.gKaiserSinc); } - MPT_FORCEINLINE void End(const ModChannel &) { } - MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const MPT_RESTRICT inBuffer, const uint32 posLo) { static_assert(static_cast(Traits::numChannelsIn) <= static_cast(Traits::numChannelsOut), "Too many input channels"); @@ -192,13 +198,11 @@ struct FIRFilterInterpolation { const int16 *WFIRlut; - MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &resampler) + MPT_FORCEINLINE FIRFilterInterpolation(const ModChannel &, const CResampler &resampler, unsigned int) { WFIRlut = resampler.m_WindowedFIR.lut; } - MPT_FORCEINLINE void End(const ModChannel &) { } - MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const MPT_RESTRICT inBuffer, const uint32 posLo) { static_assert(static_cast(Traits::numChannelsIn) <= static_cast(Traits::numChannelsOut), "Too many input channels"); @@ -230,30 +234,30 @@ struct NoRamp { typename Traits::output_t lVol, rVol; - MPT_FORCEINLINE void Start(const ModChannel &chn) + MPT_FORCEINLINE NoRamp(const ModChannel &chn) { lVol = chn.leftVol; rVol = chn.rightVol; } - - MPT_FORCEINLINE void End(const ModChannel &) { } }; struct Ramp { + ModChannel &channel; int32 lRamp, rRamp; - MPT_FORCEINLINE void Start(const ModChannel &chn) + MPT_FORCEINLINE Ramp(ModChannel &chn) + : channel{chn} { lRamp = chn.rampLeftVol; rRamp = chn.rampRightVol; } - MPT_FORCEINLINE void End(ModChannel &chn) + MPT_FORCEINLINE ~Ramp() { - chn.rampLeftVol = lRamp; chn.leftVol = lRamp >> VOLUMERAMPPRECISION; - chn.rampRightVol = rRamp; chn.rightVol = rRamp >> VOLUMERAMPPRECISION; + channel.rampLeftVol = lRamp; channel.leftVol = lRamp >> VOLUMERAMPPRECISION; + channel.rampRightVol = rRamp; channel.rightVol = rRamp >> VOLUMERAMPPRECISION; } }; @@ -331,8 +335,7 @@ struct MixStereoRamp : public Ramp template struct NoFilter { - MPT_FORCEINLINE void Start(const ModChannel &) { } - MPT_FORCEINLINE void End(const ModChannel &) { } + MPT_FORCEINLINE NoFilter(const ModChannel &) { } MPT_FORCEINLINE void operator() (const typename Traits::outbuf_t &, const ModChannel &) { } }; @@ -342,10 +345,12 @@ struct NoFilter template struct ResonantFilter { + ModChannel &channel; // Filter history typename Traits::output_t fy[Traits::numChannelsIn][2]; - MPT_FORCEINLINE void Start(const ModChannel &chn) + MPT_FORCEINLINE ResonantFilter(ModChannel &chn) + : channel{chn} { for(int i = 0; i < Traits::numChannelsIn; i++) { @@ -354,12 +359,12 @@ struct ResonantFilter } } - MPT_FORCEINLINE void End(ModChannel &chn) + MPT_FORCEINLINE ~ResonantFilter() { for(int i = 0; i < Traits::numChannelsIn; i++) { - chn.nFilter_Y[i][0] = fy[i][0]; - chn.nFilter_Y[i][1] = fy[i][1]; + channel.nFilter_Y[i][0] = fy[i][0]; + channel.nFilter_Y[i][1] = fy[i][1]; } } diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/MixerInterface.h b/Frameworks/OpenMPT.old/OpenMPT/soundlib/MixerInterface.h index 09a9f7001..c8ac012c4 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/MixerInterface.h +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/MixerInterface.h @@ -41,8 +41,7 @@ struct MixerTraits template struct NoInterpolation { - MPT_FORCEINLINE void Start(const ModChannel &, const CResampler &) { } - MPT_FORCEINLINE void End(const ModChannel &) { } + MPT_FORCEINLINE NoInterpolation(const ModChannel &, const CResampler &, unsigned int) { } MPT_FORCEINLINE void operator() (typename Traits::outbuf_t &outSample, const typename Traits::input_t * const inBuffer, const int32) { @@ -72,14 +71,9 @@ static void SampleLoop(ModChannel &chn, const CResampler &resampler, typename Tr ModChannel &c = chn; const typename Traits::input_t * MPT_RESTRICT inSample = static_cast(c.pCurrentSample); - InterpolationFunc interpolate; - FilterFunc filter; - MixFunc mix; - - // Do initialisation if necessary - interpolate.Start(c, resampler); - filter.Start(c); - mix.Start(c); + InterpolationFunc interpolate{c, resampler, numSamples}; + FilterFunc filter{c}; + MixFunc mix{c}; unsigned int samples = numSamples; SamplePosition smpPos = c.position; // Fixed-point sample position @@ -96,10 +90,6 @@ static void SampleLoop(ModChannel &chn, const CResampler &resampler, typename Tr smpPos += increment; } - mix.End(c); - filter.End(c); - interpolate.End(c); - c.position = smpPos; } diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_fx.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_fx.cpp index 46cc21b21..111798913 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_fx.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_fx.cpp @@ -500,6 +500,10 @@ std::vector CSoundFile::GetLength(enmGetLengthResetMode adjustMod break; case CMD_S3MCMDEX: + if(!chn.rowCommand.param && (GetType() & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT))) + chn.rowCommand.param = chn.nOldCmdEx; + else + chn.nOldCmdEx = static_cast(chn.rowCommand.param); if((p->param & 0xF0) == 0x60) { // Fine Pattern Delay @@ -958,6 +962,11 @@ std::vector CSoundFile::GetLength(enmGetLengthResetMode adjustMod } break; } + + if(m_playBehaviour[kST3EffectMemory] && param != 0) + { + UpdateS3MEffectMemory(chn, param); + } } // Interpret F00 effect in XM files as "stop song" @@ -3439,10 +3448,6 @@ bool CSoundFile::ProcessEffects() // S3M/IT Sxx Extended Commands case CMD_S3MCMDEX: - if(m_playBehaviour[kST3EffectMemory] && param == 0) - { - param = chn.nArpeggio; // S00 uses the last non-zero effect parameter as memory, like other effects including Arpeggio, so we "borrow" our memory there. - } ExtendedS3MCommands(nChn, static_cast(param)); break; @@ -3702,9 +3707,9 @@ void CSoundFile::UpdateS3MEffectMemory(ModChannel &chn, ModCommand::PARAM param) chn.nTremorParam = param; // Ixy chn.nArpeggio = param; // Jxy chn.nRetrigParam = param; // Qxy - chn.nTremoloDepth = (param & 0x0F) << 2; // Rxy - chn.nTremoloSpeed = (param >> 4) & 0x0F; // Rxy - // Sxy is not handled here. + chn.nTremoloDepth = (param & 0x0F) << 2; // Rxy + chn.nTremoloSpeed = (param >> 4) & 0x0F; // Rxy + chn.nOldCmdEx = param; // Sxy } diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/plugins/LFOPlugin.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/plugins/LFOPlugin.cpp index 65823cda8..78d63c9c5 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/plugins/LFOPlugin.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/plugins/LFOPlugin.cpp @@ -117,7 +117,7 @@ void LFOPlugin::Process(float *pOutL, float *pOutR, uint32 numFrames) if(m_outputToCC) { plugin->MidiSend(MIDIEvents::CC(static_cast(m_outputParam & 0x7F), static_cast((m_outputParam >> 8) & 0x0F), mpt::saturate_round(value * 127.0f))); - } else + } else if(m_outputParam >= 0) { plugin->SetParameter(m_outputParam, static_cast(value)); }