From ebb9c5b4f1b19e6f58836cd9416f86cc3d796148 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Sun, 30 Jan 2022 15:19:36 -0800 Subject: [PATCH] libOpenMPT Legacy: Updated to version 0.5.16 Signed-off-by: Christopher Snowhill --- Frameworks/OpenMPT.old/OpenMPT/LICENSE | 2 +- Frameworks/OpenMPT.old/OpenMPT/Makefile | 4 ++ Frameworks/OpenMPT.old/OpenMPT/build/dist.mk | 6 +- .../OpenMPT/build/make/config-emscripten.mk | 5 +- .../OpenMPT/build/svn_version/svn_version.h | 8 +-- .../OpenMPT.old/OpenMPT/common/mptBaseUtils.h | 24 +++++++ .../OpenMPT.old/OpenMPT/common/version.cpp | 8 +-- .../OpenMPT/common/versionNumber.h | 2 +- .../contrib/libmodplug-0.8.8.5/LICENSE | 2 +- .../contrib/libmodplug-0.8.9.0/LICENSE | 2 +- .../OpenMPT/libopenmpt/dox/changelog.md | 33 +++++++++ .../OpenMPT/libopenmpt/in_openmpt.cpp | 2 +- .../OpenMPT/libopenmpt/libopenmpt_config.h | 2 + .../OpenMPT/libopenmpt/libopenmpt_version.h | 2 +- .../OpenMPT/libopenmpt/libopenmpt_version.mk | 4 +- .../OpenMPT/libopenmpt/libopenmpt_version.rc | 2 +- .../OpenMPT/libopenmpt/xmp-openmpt.cpp | 2 +- .../OpenMPT/openmpt123/openmpt123.cpp | 6 +- .../soundbase/SampleFormatConverters.h | 69 +++++++++++++++---- .../OpenMPT/soundlib/ContainerXPK.cpp | 8 +-- .../OpenMPT.old/OpenMPT/soundlib/Load_ams.cpp | 10 +-- .../OpenMPT.old/OpenMPT/soundlib/Load_med.cpp | 7 +- .../OpenMPT.old/OpenMPT/soundlib/Load_mo3.cpp | 14 ++-- .../OpenMPT.old/OpenMPT/soundlib/Load_mod.cpp | 53 +++++++------- .../OpenMPT.old/OpenMPT/soundlib/Load_s3m.cpp | 3 + .../OpenMPT/soundlib/ModChannel.cpp | 1 + .../OpenMPT.old/OpenMPT/soundlib/ModChannel.h | 9 +-- .../OpenMPT.old/OpenMPT/soundlib/Snd_defs.h | 4 +- .../OpenMPT.old/OpenMPT/soundlib/Snd_flt.cpp | 6 +- .../OpenMPT.old/OpenMPT/soundlib/Snd_fx.cpp | 3 +- .../OpenMPT.old/OpenMPT/soundlib/Sndmix.cpp | 4 +- .../OpenMPT.old/OpenMPT/soundlib/pattern.cpp | 3 +- .../OpenMPT/soundlib/patternContainer.cpp | 7 +- .../soundlib/plugins/dmo/I3DL2Reverb.cpp | 5 +- .../OpenMPT.old/OpenMPT/soundlib/tuning.cpp | 36 +++++++++- 35 files changed, 246 insertions(+), 112 deletions(-) diff --git a/Frameworks/OpenMPT.old/OpenMPT/LICENSE b/Frameworks/OpenMPT.old/OpenMPT/LICENSE index ae92400c3..3938cce29 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/LICENSE +++ b/Frameworks/OpenMPT.old/OpenMPT/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2021, OpenMPT contributors +Copyright (c) 2004-2022, OpenMPT contributors Copyright (c) 1997-2003, Olivier Lapicque All rights reserved. diff --git a/Frameworks/OpenMPT.old/OpenMPT/Makefile b/Frameworks/OpenMPT.old/OpenMPT/Makefile index 20c4553cc..9828e530c 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/Makefile +++ b/Frameworks/OpenMPT.old/OpenMPT/Makefile @@ -74,6 +74,7 @@ # LOCAL_OGG=1 Build local copy of libogg, even if found # LOCAL_VORBIS=1 Build local copy of libvorbis, even if found # +# NO_MINIZ=1 Do not fallback to miniz # NO_MINIMP3=1 Do not fallback to minimp3 # NO_STBVORBIS=1 Do not fallback to stb_vorbis # @@ -867,11 +868,14 @@ LIBOPENMPT_C_SOURCES += $(LOCAL_ZLIB_SOURCES) LIBOPENMPTTEST_C_SOURCES += $(LOCAL_ZLIB_SOURCES) else ifeq ($(NO_ZLIB),1) +ifeq ($(NO_MINIZ),1) +else LIBOPENMPT_C_SOURCES += include/miniz/miniz.c LIBOPENMPTTEST_C_SOURCES += include/miniz/miniz.c CPPFLAGS += -DMPT_WITH_MINIZ endif endif +endif include/minimp3/minimp3.o : CFLAGS+=$(CFLAGS_SILENT) include/minimp3/minimp3.test.o : CFLAGS+=$(CFLAGS_SILENT) diff --git a/Frameworks/OpenMPT.old/OpenMPT/build/dist.mk b/Frameworks/OpenMPT.old/OpenMPT/build/dist.mk index c7f839a1f..39531d178 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/build/dist.mk +++ b/Frameworks/OpenMPT.old/OpenMPT/build/dist.mk @@ -1,4 +1,4 @@ -MPT_SVNVERSION=16119 -MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.14 -MPT_SVNDATE=2021-12-05T14:17:40.071493Z +MPT_SVNVERSION=16768 +MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.16 +MPT_SVNDATE=2022-01-30T16:50:10.915999Z diff --git a/Frameworks/OpenMPT.old/OpenMPT/build/make/config-emscripten.mk b/Frameworks/OpenMPT.old/OpenMPT/build/make/config-emscripten.mk index ed6112b7f..080138cfd 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/build/make/config-emscripten.mk +++ b/Frameworks/OpenMPT.old/OpenMPT/build/make/config-emscripten.mk @@ -40,11 +40,10 @@ LDFLAGS += -s ALLOW_MEMORY_GROWTH=1 else ifeq ($(EMSCRIPTEN_TARGET),all) # emits native wasm AND javascript with full wasm optimizations. -# as of emscripten 1.38, this is equivalent to default. CPPFLAGS += -DMPT_BUILD_WASM CXXFLAGS += CFLAGS += -LDFLAGS += -s WASM=2 -s LEGACY_VM_SUPPORT=1 +LDFLAGS += -s WASM=2 -s LEGACY_VM_SUPPORT=1 -Wno-transpile LDFLAGS += -s ALLOW_MEMORY_GROWTH=1 @@ -71,7 +70,7 @@ else ifeq ($(EMSCRIPTEN_TARGET),js) CPPFLAGS += -DMPT_BUILD_ASMJS CXXFLAGS += CFLAGS += -LDFLAGS += -s WASM=0 -s LEGACY_VM_SUPPORT=1 +LDFLAGS += -s WASM=0 -s LEGACY_VM_SUPPORT=1 -Wno-transpile LDFLAGS += -s ALLOW_MEMORY_GROWTH=1 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 3a2529e56..41e7534bb 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 "16119" -#define OPENMPT_VERSION_REVISION 16119 +#define OPENMPT_VERSION_SVNVERSION "16768" +#define OPENMPT_VERSION_REVISION 16768 #define OPENMPT_VERSION_DIRTY 0 #define OPENMPT_VERSION_MIXEDREVISIONS 0 -#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.14" -#define OPENMPT_VERSION_DATE "2021-12-05T14:17:40.071493Z" +#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_IS_PACKAGE 1 diff --git a/Frameworks/OpenMPT.old/OpenMPT/common/mptBaseUtils.h b/Frameworks/OpenMPT.old/OpenMPT/common/mptBaseUtils.h index a5f37a31b..5e9103407 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/common/mptBaseUtils.h +++ b/Frameworks/OpenMPT.old/OpenMPT/common/mptBaseUtils.h @@ -418,6 +418,30 @@ inline T ExponentialGrow(const T &x) } //namespace Util +namespace mpt +{ + +template +inline T sanitize_nan(T val) +{ + static_assert(std::is_floating_point::value); + if(std::isnan(val)) + { + return T(0.0); + } + return val; +} + +template +inline T safe_clamp(T v, T lo, T hi) +{ + static_assert(std::is_floating_point::value); + return std::clamp(mpt::sanitize_nan(v), lo, hi); +} + +} // namespace mpt + + // Limits 'val' to given range. If 'val' is less than 'lowerLimit', 'val' is set to value 'lowerLimit'. // Similarly if 'val' is greater than 'upperLimit', 'val' is set to value 'upperLimit'. // If 'lowerLimit' > 'upperLimit', 'val' won't be modified. diff --git a/Frameworks/OpenMPT.old/OpenMPT/common/version.cpp b/Frameworks/OpenMPT.old/OpenMPT/common/version.cpp index 8684b7044..f612cd9a8 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/common/version.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/common/version.cpp @@ -565,12 +565,12 @@ mpt::ustring GetFullCreditsString() "libopenmpt (based on OpenMPT / ModPlug Tracker)\n" #endif "\n" - "Copyright \xC2\xA9 2004-2021 Contributors\n" + "Copyright \xC2\xA9 2004-2022 Contributors\n" "Copyright \xC2\xA9 1997-2003 Olivier Lapicque\n" "\n" "Contributors:\n" - "Johannes Schultz (2008-2021)\n" - "J\xC3\xB6rn Heusipp (2012-2021)\n" + "Johannes Schultz (2008-2022)\n" + "J\xC3\xB6rn Heusipp (2012-2022)\n" "Ahti Lepp\xC3\xA4nen (2005-2011)\n" "Robin Fernandes (2004-2007)\n" "Sergiy Pylypenko (2007)\n" @@ -760,7 +760,7 @@ mpt::ustring GetFullCreditsString() mpt::ustring GetLicenseString() { return MPT_UTF8( - "Copyright (c) 2004-2021, OpenMPT contributors" "\n" + "Copyright (c) 2004-2022, OpenMPT contributors" "\n" "Copyright (c) 1997-2003, Olivier Lapicque" "\n" "All rights reserved." "\n" "" "\n" diff --git a/Frameworks/OpenMPT.old/OpenMPT/common/versionNumber.h b/Frameworks/OpenMPT.old/OpenMPT/common/versionNumber.h index fbd29f0e0..c0308f759 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 00 +#define VER_MINORMINOR 04 OPENMPT_NAMESPACE_END diff --git a/Frameworks/OpenMPT.old/OpenMPT/contrib/libmodplug-0.8.8.5/LICENSE b/Frameworks/OpenMPT.old/OpenMPT/contrib/libmodplug-0.8.8.5/LICENSE index ae92400c3..3938cce29 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/contrib/libmodplug-0.8.8.5/LICENSE +++ b/Frameworks/OpenMPT.old/OpenMPT/contrib/libmodplug-0.8.8.5/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2021, OpenMPT contributors +Copyright (c) 2004-2022, OpenMPT contributors Copyright (c) 1997-2003, Olivier Lapicque All rights reserved. diff --git a/Frameworks/OpenMPT.old/OpenMPT/contrib/libmodplug-0.8.9.0/LICENSE b/Frameworks/OpenMPT.old/OpenMPT/contrib/libmodplug-0.8.9.0/LICENSE index ae92400c3..3938cce29 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/contrib/libmodplug-0.8.9.0/LICENSE +++ b/Frameworks/OpenMPT.old/OpenMPT/contrib/libmodplug-0.8.9.0/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2021, OpenMPT contributors +Copyright (c) 2004-2022, OpenMPT contributors Copyright (c) 1997-2003, Olivier Lapicque All rights reserved. diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/dox/changelog.md b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/dox/changelog.md index 13dad2485..23a0495c5 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/dox/changelog.md +++ b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/dox/changelog.md @@ -5,6 +5,39 @@ Changelog {#changelog} For fully detailed change log, please see the source repository directly. This is just a high-level summary. +### libopenmpt 0.5.16 (2022-01-30) + + * [**Bug**] Possible hang with malformed DMF, DSM, MED and OKT files + containing 65536 or more patterns when destroying the module. + * [**Bug**] Avoid NaNs and infinite values with custom tunings. + + * The letter "z" is now evaluated in fixed MIDI macros (Z80...ZFF) the same + way as in Impulse Tracker. + * MOD: Loosened VBlank timing heuristics so that "frame of mind" by Dascon + plays correctly. + * MOD: Validate the contents of "hidden" patterns beyond the end of the order + list when the file size matches the expected size when only taken "official" + patterns into account. This fixes Shofixti Ditty.mod from Star Control 2 + while keeping other (partly broken) modules working. + * MED: Command 20 (reverse sample) is now only applied when it's next to a + note. + +### libopenmpt 0.5.15 (2021-12-23) + + * [**Sec**] Possible out-of-bounds read of stack-allocated array in malformed + AMS files. (r16243) + + * [**Bug**] Fixed various undefined behaviour found with ubsan. + + * IT: Even after libopenmpt 0.5.14 the filter reset logic was still not 100% + identical to Impulse Tracker: A note triggered on tick 0 of a row with a + Pattern Delay effect still caused the filter to be reset on repetitions of + that row even though the note wasn't retriggered. + * MOD: Loosened VBlank timing heuristics so that the original copy of + Guitar Slinger from Dizzy Tunes II plays correctly. + + * mpg123: Update to v1.29.3 (2021-12-11). + ### libopenmpt 0.5.14 (2021-12-05) * [**Sec**] Possible out-of-bounds read in Chorus plugin with NaN plugin diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/in_openmpt.cpp b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/in_openmpt.cpp index 65159a240..e2c136ee5 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/in_openmpt.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/in_openmpt.cpp @@ -214,7 +214,7 @@ static void config( HWND hwndParent ) { static void about( HWND hwndParent ) { std::ostringstream about; about << SHORT_TITLE << " version " << openmpt::string::get( "library_version" ) << " " << "(built " << openmpt::string::get( "build" ) << ")" << std::endl; - about << " Copyright (c) 2013-2021 OpenMPT developers (https://lib.openmpt.org/)" << std::endl; + about << " Copyright (c) 2013-2022 OpenMPT developers (https://lib.openmpt.org/)" << std::endl; about << " OpenMPT version " << openmpt::string::get( "core_version" ) << std::endl; about << std::endl; about << openmpt::string::get( "contact" ) << std::endl; diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_config.h b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_config.h index 5aed65c28..562f9054b 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_config.h +++ b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_config.h @@ -159,6 +159,8 @@ LIBOPENMPT_DEPRECATED static const int LIBOPENMPT_DEPRECATED_STRING_CONSTANT = 0 #else #define LIBOPENMPT_DEPRECATED_STRING( str ) str #endif +#else +#define LIBOPENMPT_DEPRECATED_STRING( str ) str #endif diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.h b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.h index 7eba605eb..ea5ecda81 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 14 +#define OPENMPT_API_VERSION_PATCH 16 /*! \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 8d04f9c9b..992bc8804 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=14 +LIBOPENMPT_VERSION_PATCH=16 LIBOPENMPT_VERSION_PREREL= LIBOPENMPT_LTVER_CURRENT=2 -LIBOPENMPT_LTVER_REVISION=14 +LIBOPENMPT_LTVER_REVISION=16 LIBOPENMPT_LTVER_AGE=2 diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.rc b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.rc index 4f122945c..facb6719a 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.rc +++ b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/libopenmpt_version.rc @@ -192,7 +192,7 @@ BEGIN VALUE "FileDescription", VER_FILEDESC_STR VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", VER_FILENAME_STR - VALUE "LegalCopyright", "Copyright © 2004-2020 OpenMPT contributors, Copyright © 1997-2003 Olivier Lapicque" + VALUE "LegalCopyright", "Copyright © 2004-2022 OpenMPT contributors, Copyright © 1997-2003 Olivier Lapicque" VALUE "OriginalFilename", VER_FILENAME_STR VALUE "ProductName", "libopenmpt" VALUE "ProductVersion", VER_FILEVERSION_STR diff --git a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/xmp-openmpt.cpp b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/xmp-openmpt.cpp index 51f158a2e..0eee88157 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/xmp-openmpt.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/libopenmpt/xmp-openmpt.cpp @@ -468,7 +468,7 @@ static void clear_current_timeinfo() { static void WINAPI openmpt_About( HWND win ) { std::ostringstream about; about << SHORT_TITLE << " version " << openmpt::string::get( "library_version" ) << " " << "(built " << openmpt::string::get( "build" ) << ")" << std::endl; - about << " Copyright (c) 2013-2021 OpenMPT developers (https://lib.openmpt.org/)" << std::endl; + about << " Copyright (c) 2013-2022 OpenMPT developers (https://lib.openmpt.org/)" << std::endl; about << " OpenMPT version " << openmpt::string::get( "core_version" ) << std::endl; about << std::endl; about << openmpt::string::get( "contact" ) << std::endl; diff --git a/Frameworks/OpenMPT.old/OpenMPT/openmpt123/openmpt123.cpp b/Frameworks/OpenMPT.old/OpenMPT/openmpt123/openmpt123.cpp index ceb93203e..c5186cd8c 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/openmpt123/openmpt123.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/openmpt123/openmpt123.cpp @@ -8,7 +8,7 @@ */ static const char * const license = -"Copyright (c) 2004-2021, OpenMPT contributors" "\n" +"Copyright (c) 2004-2022, OpenMPT contributors" "\n" "Copyright (c) 1997-2003, Olivier Lapicque" "\n" "All rights reserved." "\n" "" "\n" @@ -461,7 +461,7 @@ static std::string seconds_to_string( double time ) { static void show_info( std::ostream & log, bool verbose ) { log << "openmpt123" << " v" << OPENMPT123_VERSION_STRING << ", libopenmpt " << openmpt::string::get( "library_version" ) << " (" << "OpenMPT " << openmpt::string::get( "core_version" ) << ")" << std::endl; - log << "Copyright (c) 2013-2021 OpenMPT developers " << std::endl; + log << "Copyright (c) 2013-2022 OpenMPT developers " << std::endl; if ( !verbose ) { log << std::endl; return; @@ -538,7 +538,7 @@ static void show_info( std::ostream & log, bool verbose ) { static void show_man_version( textout & log ) { log << "openmpt123" << " v" << OPENMPT123_VERSION_STRING << std::endl; log << std::endl; - log << "Copyright (c) 2013-2021 OpenMPT developers " << std::endl; + log << "Copyright (c) 2013-2022 OpenMPT developers " << std::endl; } static void show_short_version( textout & log ) { diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundbase/SampleFormatConverters.h b/Frameworks/OpenMPT.old/OpenMPT/soundbase/SampleFormatConverters.h index 7b53de1e8..db80ef42d 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundbase/SampleFormatConverters.h +++ b/Frameworks/OpenMPT.old/OpenMPT/soundbase/SampleFormatConverters.h @@ -213,7 +213,19 @@ struct DecodeFloat32 static constexpr std::size_t input_inc = 4; MPT_FORCEINLINE output_t operator() (const input_t *inBuf) { - return IEEE754binary32LE(inBuf[loLoByteIndex], inBuf[loHiByteIndex], inBuf[hiLoByteIndex], inBuf[hiHiByteIndex]); + float32 val = IEEE754binary32LE(inBuf[loLoByteIndex], inBuf[loHiByteIndex], inBuf[hiLoByteIndex], inBuf[hiHiByteIndex]); + val = mpt::sanitize_nan(val); + if(std::isinf(val)) + { + if(val >= 0.0f) + { + val = 1.0f; + } else + { + val = -1.0f; + } + } + return val; } }; @@ -226,7 +238,20 @@ struct DecodeScaledFloat32 float factor; MPT_FORCEINLINE output_t operator() (const input_t *inBuf) { - return factor * IEEE754binary32LE(inBuf[loLoByteIndex], inBuf[loHiByteIndex], inBuf[hiLoByteIndex], inBuf[hiHiByteIndex]); + float32 val = IEEE754binary32LE(inBuf[loLoByteIndex], inBuf[loHiByteIndex], inBuf[hiLoByteIndex], inBuf[hiHiByteIndex]); + val = mpt::sanitize_nan(val); + if(std::isinf(val)) + { + if(val >= 0.0f) + { + val = 1.0f; + } else + { + val = -1.0f; + } + } + return factor * val; + } MPT_FORCEINLINE DecodeScaledFloat32(float scaleFactor) : factor(scaleFactor) @@ -243,7 +268,19 @@ struct DecodeFloat64 static constexpr std::size_t input_inc = 8; MPT_FORCEINLINE output_t operator() (const input_t *inBuf) { - return IEEE754binary64LE(inBuf[b0], inBuf[b1], inBuf[b2], inBuf[b3], inBuf[b4], inBuf[b5], inBuf[b6], inBuf[b7]); + float64 val = IEEE754binary64LE(inBuf[b0], inBuf[b1], inBuf[b2], inBuf[b3], inBuf[b4], inBuf[b5], inBuf[b6], inBuf[b7]); + val = mpt::sanitize_nan(val); + if(std::isinf(val)) + { + if(val >= 0.0) + { + val = 1.0; + } else + { + val = -1.0; + } + } + return val; } }; @@ -371,7 +408,7 @@ struct Convert typedef uint8 output_t; MPT_FORCEINLINE output_t operator() (input_t val) { - Limit(val, -1.0f, 1.0f); + val = mpt::safe_clamp(val, -1.0f, 1.0f); val *= 128.0f; return static_cast(mpt::saturate_cast(static_cast(MPT_SC_FASTROUND(val)))+0x80); } @@ -384,7 +421,7 @@ struct Convert typedef uint8 output_t; MPT_FORCEINLINE output_t operator() (input_t val) { - Limit(val, -1.0, 1.0); + val = mpt::safe_clamp(val, -1.0, 1.0); val *= 128.0; return static_cast(mpt::saturate_cast(static_cast(MPT_SC_FASTROUND(val)))+0x80); } @@ -452,7 +489,7 @@ struct Convert typedef int8 output_t; MPT_FORCEINLINE output_t operator() (input_t val) { - Limit(val, -1.0f, 1.0f); + val = mpt::safe_clamp(val, -1.0f, 1.0f); val *= 128.0f; return mpt::saturate_cast(static_cast(MPT_SC_FASTROUND(val))); } @@ -465,7 +502,7 @@ struct Convert typedef int8 output_t; MPT_FORCEINLINE output_t operator() (input_t val) { - Limit(val, -1.0, 1.0); + val = mpt::safe_clamp(val, -1.0, 1.0); val *= 128.0; return mpt::saturate_cast(static_cast(MPT_SC_FASTROUND(val))); } @@ -533,7 +570,7 @@ struct Convert typedef int16 output_t; MPT_FORCEINLINE output_t operator() (input_t val) { - Limit(val, -1.0f, 1.0f); + val = mpt::safe_clamp(val, -1.0f, 1.0f); val *= 32768.0f; return mpt::saturate_cast(static_cast(MPT_SC_FASTROUND(val))); } @@ -546,7 +583,7 @@ struct Convert typedef int16 output_t; MPT_FORCEINLINE output_t operator() (input_t val) { - Limit(val, -1.0, 1.0); + val = mpt::safe_clamp(val, -1.0, 1.0); val *= 32768.0; return mpt::saturate_cast(static_cast(MPT_SC_FASTROUND(val))); } @@ -614,7 +651,7 @@ struct Convert typedef int24 output_t; MPT_FORCEINLINE output_t operator() (input_t val) { - Limit(val, -1.0f, 1.0f); + val = mpt::safe_clamp(val, -1.0f, 1.0f); val *= 2147483648.0f; return static_cast(MPT_SC_RSHIFT_SIGNED(mpt::saturate_cast(static_cast(MPT_SC_FASTROUND(val))), 8)); } @@ -627,7 +664,7 @@ struct Convert typedef int24 output_t; MPT_FORCEINLINE output_t operator() (input_t val) { - Limit(val, -1.0, 1.0); + val = mpt::safe_clamp(val, -1.0, 1.0); val *= 2147483648.0; return static_cast(MPT_SC_RSHIFT_SIGNED(mpt::saturate_cast(static_cast(MPT_SC_FASTROUND(val))), 8)); } @@ -695,7 +732,7 @@ struct Convert typedef int32 output_t; MPT_FORCEINLINE output_t operator() (input_t val) { - Limit(val, -1.0f, 1.0f); + val = mpt::safe_clamp(val, -1.0f, 1.0f); val *= 2147483648.0f; return mpt::saturate_cast(static_cast(MPT_SC_FASTROUND(val))); } @@ -708,7 +745,7 @@ struct Convert typedef int32 output_t; MPT_FORCEINLINE output_t operator() (input_t val) { - Limit(val, -1.0, 1.0); + val = mpt::safe_clamp(val, -1.0, 1.0); val *= 2147483648.0; return mpt::saturate_cast(static_cast(MPT_SC_FASTROUND(val))); } @@ -776,7 +813,7 @@ struct Convert typedef int64 output_t; MPT_FORCEINLINE output_t operator() (input_t val) { - Limit(val, -1.0f, 1.0f); + val = mpt::safe_clamp(val, -1.0f, 1.0f); val *= static_cast(uint64(1)<<63); return mpt::saturate_cast(MPT_SC_FASTROUND(val)); } @@ -789,7 +826,7 @@ struct Convert typedef int64 output_t; MPT_FORCEINLINE output_t operator() (input_t val) { - Limit(val, -1.0, 1.0); + val = mpt::safe_clamp(val, -1.0, 1.0); val *= static_cast(uint64(1)<<63); return mpt::saturate_cast(MPT_SC_FASTROUND(val)); } @@ -1155,6 +1192,7 @@ struct ConvertToFixedPoint MPT_FORCEINLINE output_t operator() (input_t val) { static_assert(fractionalBits >= 0 && fractionalBits <= sizeof(input_t)*8-1); + val = mpt::sanitize_nan(val); return mpt::saturate_cast(MPT_SC_FASTROUND(val * factor)); } }; @@ -1173,6 +1211,7 @@ struct ConvertToFixedPoint MPT_FORCEINLINE output_t operator() (input_t val) { static_assert(fractionalBits >= 0 && fractionalBits <= sizeof(input_t)*8-1); + val = mpt::sanitize_nan(val); return mpt::saturate_cast(MPT_SC_FASTROUND(val * factor)); } }; diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/ContainerXPK.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/ContainerXPK.cpp index 7f35f999d..fb30710a7 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/ContainerXPK.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/ContainerXPK.cpp @@ -58,7 +58,7 @@ struct XPK_BufferBounds static int32 bfextu(std::size_t p, int32 bo, int32 bc, XPK_BufferBounds &bufs) { - int32 r; + uint32 r; p += bo / 8; r = bufs.SrcRead(p); p++; @@ -75,7 +75,7 @@ static int32 bfextu(std::size_t p, int32 bo, int32 bc, XPK_BufferBounds &bufs) static int32 bfexts(std::size_t p, int32 bo, int32 bc, XPK_BufferBounds &bufs) { - int32 r; + uint32 r; p += bo / 8; r = bufs.SrcRead(p); p++; @@ -84,9 +84,7 @@ static int32 bfexts(std::size_t p, int32 bo, int32 bc, XPK_BufferBounds &bufs) r <<= 8; r |= bufs.SrcRead(p); r <<= (bo % 8) + 8; - r >>= 32 - bc; - - return r; + return mpt::rshift_signed(static_cast(r), 32 - bc); } diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_ams.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_ams.cpp index e9e1b302b..b3c3e10f7 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_ams.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_ams.cpp @@ -438,14 +438,14 @@ bool CSoundFile::ReadAMS(FileReader &file, ModLoadingFlags loadFlags) file.ReadSizedString(ChnSettings[chn].szName); } - // Read pattern names + // Read pattern names and create patterns Patterns.ResizeArray(fileHeader.numPats); for(PATTERNINDEX pat = 0; pat < fileHeader.numPats; pat++) { char name[11]; - file.ReadSizedString(name); + const bool ok = file.ReadSizedString(name); // Create pattern now, so name won't be reset later. - if(Patterns.Insert(pat, 64)) + if(Patterns.Insert(pat, 64) && ok) { Patterns[pat].SetName(name); } @@ -973,8 +973,8 @@ bool CSoundFile::ReadAMS2(FileReader &file, ModLoadingFlags loadFlags) } char patternName[11]; - patternChunk.ReadSizedString(patternName); - Patterns[pat].SetName(patternName); + if(patternChunk.ReadSizedString(patternName)) + Patterns[pat].SetName(patternName); ReadAMSPattern(Patterns[pat], true, patternChunk); } diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_med.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_med.cpp index de6f01102..71c16a4ec 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_med.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_med.cpp @@ -543,8 +543,11 @@ static void ConvertMEDEffect(ModCommand &m, bool is8ch, bool bpmMode, uint8 rows case 0x20: // Reverse sample + skip samples if(m.param == 0 && m.vol == 0) { - m.command = CMD_S3MCMDEX; - m.param = 0x9F; + if(m.IsNote()) + { + m.command = CMD_S3MCMDEX; + m.param = 0x9F; + } } else { // Skip given number of samples diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_mo3.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_mo3.cpp index 387c7dacf..95a4aceb0 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_mo3.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_mo3.cpp @@ -279,7 +279,7 @@ struct MO3Sample smpCompressionMask = 0x1000 | 0x2000 | 0x4000 | 0x8000 }; - int32le freqFinetune; // Frequency in S3M and IT, finetune (0...255) in MOD, MTM, XM + uint32le freqFinetune; // Frequency in S3M and IT, finetune (0...255) in MOD, MTM, XM int8le transpose; uint8le defaultVolume; // 0...64 uint16le panning; // 0...256 if enabled, 0xFFFF otherwise @@ -304,9 +304,9 @@ struct MO3Sample if(type & (MOD_TYPE_IT | MOD_TYPE_S3M)) { if(frequencyIsHertz) - mptSmp.nC5Speed = static_cast(freqFinetune); + mptSmp.nC5Speed = freqFinetune; else - mptSmp.nC5Speed = mpt::saturate_round(8363.0 * std::pow(2.0, (freqFinetune + 1408) / 1536.0)); + mptSmp.nC5Speed = mpt::saturate_round(8363.0 * std::pow(2.0, static_cast(freqFinetune + 1408) / 1536.0)); } else { mptSmp.nFineTune = static_cast(freqFinetune); @@ -394,7 +394,7 @@ struct MO3SampleChunk do \ { \ READ_CTRL_BIT; \ - strLen = (strLen << 1) + carry; \ + strLen = mpt::lshift_signed(strLen, 1) + carry; \ READ_CTRL_BIT; \ } while(carry); \ } @@ -441,7 +441,7 @@ static bool UnpackMO3Data(FileReader &file, std::vector &uncompressed, co { // LZ ptr in ctrl stream if(uint8 b; file.Read(b)) - strOffset = (strLen << 8) | b; // read less significant offset byte from stream + strOffset = mpt::lshift_signed(strLen, 8) | b; // read less significant offset byte from stream else break; strLen = 0; @@ -456,9 +456,9 @@ static bool UnpackMO3Data(FileReader &file, std::vector &uncompressed, co // read the next 2 bits as part of strLen READ_CTRL_BIT; - strLen = (strLen << 1) + carry; + strLen = mpt::lshift_signed(strLen, 1) + carry; READ_CTRL_BIT; - strLen = (strLen << 1) + carry; + strLen = mpt::lshift_signed(strLen, 1) + carry; if(strLen == 0) { // length does not fit in 2 bits diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_mod.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_mod.cpp index a5e8bcb4d..c48b674dd 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_mod.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_mod.cpp @@ -54,7 +54,7 @@ void CSoundFile::ConvertModCommand(ModCommand &m) break; // Extension for XM extended effects - case 'G' - 55: m.command = CMD_GLOBALVOLUME; break; //16 + case 'G' - 55: m.command = CMD_GLOBALVOLUME; break; //16 case 'H' - 55: m.command = CMD_GLOBALVOLSLIDE; break; case 'K' - 55: m.command = CMD_KEYOFF; break; case 'L' - 55: m.command = CMD_SETENVPOSITION; break; @@ -63,11 +63,11 @@ void CSoundFile::ConvertModCommand(ModCommand &m) case 'T' - 55: m.command = CMD_TREMOR; break; case 'W' - 55: m.command = CMD_DUMMY; break; case 'X' - 55: m.command = CMD_XFINEPORTAUPDOWN; break; - case 'Y' - 55: m.command = CMD_PANBRELLO; break; //34 - case 'Z' - 55: m.command = CMD_MIDI; break; //35 - case '\\' - 56: m.command = CMD_SMOOTHMIDI; break; //rewbs.smoothVST: 36 - note: this is actually displayed as "-" in FT2, but seems to be doing nothing. - //case ':' - 21: m.command = CMD_DELAYCUT; break; //37 - case '#' + 3: m.command = CMD_XPARAM; break; //rewbs.XMfixes - Xm.param is 38 + case 'Y' - 55: m.command = CMD_PANBRELLO; break; // 34 + case 'Z' - 55: m.command = CMD_MIDI; break; // 35 + case '\\' - 56: m.command = CMD_SMOOTHMIDI; break; // 36 - note: this is actually displayed as "-" in FT2, but seems to be doing nothing. + case 37: m.command = CMD_SMOOTHMIDI; break; // BeRoTracker uses this for smooth MIDI macros for some reason; in old OpenMPT versions this was reserved for the unimplemented "velocity" command + case '#' + 3: m.command = CMD_XPARAM; break; // 38 default: m.command = CMD_NONE; } } @@ -206,7 +206,7 @@ void CSoundFile::ModSaveCommand(uint8 &command, uint8 ¶m, bool toXM, bool co struct MODFileHeader { uint8be numOrders; - uint8be restartPos; + uint8be restartPos; // Tempo (early SoundTracker) or restart position (only PC trackers?) uint8be orderList[128]; }; @@ -582,6 +582,7 @@ static PATTERNINDEX GetNumPatterns(FileReader &file, ModSequence &Order, ORDERIN const size_t patternStartOffset = file.GetPosition(); const size_t sizeWithoutPatterns = totalSampleLen + patternStartOffset; + const size_t sizeWithOfficialPatterns = sizeWithoutPatterns + officialPatterns * numChannels * 256; if(wowSampleLen && (wowSampleLen + patternStartOffset) + numPatterns * 8 * 256 == (file.GetLength() & ~1)) { @@ -592,8 +593,9 @@ static PATTERNINDEX GetNumPatterns(FileReader &file, ModSequence &Order, ORDERIN if(ValidateMODPatternData(file, 16, true)) numChannels = 8; file.Seek(patternStartOffset); - } else if(numPatterns != officialPatterns && validateHiddenPatterns) + } else if(numPatterns != officialPatterns && (validateHiddenPatterns || sizeWithOfficialPatterns == file.GetLength())) { + // 15-sample SoundTracker specifics: // Fix SoundTracker modules where "hidden" patterns should be ignored. // razor-1911.mod (MD5 b75f0f471b0ae400185585ca05bf7fe8, SHA1 4de31af234229faec00f1e85e1e8f78f405d454b) // and captain_fizz.mod (MD5 55bd89fe5a8e345df65438dbfc2df94e, SHA1 9e0e8b7dc67939885435ea8d3ff4be7704207a43) @@ -606,28 +608,21 @@ static PATTERNINDEX GetNumPatterns(FileReader &file, ModSequence &Order, ORDERIN // only play correctly if we ignore the hidden patterns. // Hence, we have a peek at the first hidden pattern and check if it contains a lot of illegal data. // If that is the case, we assume it's part of the sample data and only consider the "official" patterns. - file.Seek(patternStartOffset + officialPatterns * 1024); + + // 31-sample NoiseTracker / ProTracker specifics: + // Interestingly, (broken) variants of the ProTracker modules + // "killing butterfly" (MD5 bd676358b1dbb40d40f25435e845cf6b, SHA1 9df4ae21214ff753802756b616a0cafaeced8021), + // "quartex" by Reflex (MD5 35526bef0fb21cb96394838d94c14bab, SHA1 116756c68c7b6598dcfbad75a043477fcc54c96c), + // seem to have the "correct" file size when only taking the "official" patterns into account, but they only play + // correctly when also loading the inofficial patterns. + // On the other hand, "Shofixti Ditty.mod" from Star Control 2 (MD5 62b7b0819123400e4d5a7813eef7fc7d, SHA1 8330cd595c61f51c37a3b6f2a8559cf3fcaaa6e8) + // doesn't sound correct when taking the second "inofficial" pattern into account. + file.Seek(patternStartOffset + officialPatterns * numChannels * 256); if(!ValidateMODPatternData(file, 64, true)) numPatterns = officialPatterns; file.Seek(patternStartOffset); } -#ifdef MPT_BUILD_DEBUG - // Check if the "hidden" patterns in the order list are actually real, i.e. if they are saved in the file. - // OpenMPT did this check in the past, but no other tracker appears to do this. - // Interestingly, (broken) variants of the ProTracker modules - // "killing butterfly" (MD5 bd676358b1dbb40d40f25435e845cf6b, SHA1 9df4ae21214ff753802756b616a0cafaeced8021), - // "quartex" by Reflex (MD5 35526bef0fb21cb96394838d94c14bab, SHA1 116756c68c7b6598dcfbad75a043477fcc54c96c), - // seem to have the "correct" file size when only taking the "official" patterns into account, but they only play - // correctly when also loading the inofficial patterns. - // See also the above check for ambiguities with SoundTracker modules. - // Keep this assertion in the code to find potential other broken MODs. - if(numPatterns != officialPatterns && sizeWithoutPatterns + officialPatterns * numChannels * 256 == file.GetLength()) - { - MPT_ASSERT(false); - //numPatterns = officialPatterns; - } else -#endif if(numPatternsIllegal > numPatterns && sizeWithoutPatterns + numPatternsIllegal * numChannels * 256 == file.GetLength()) { // Even those illegal pattern indexes (> 128) appear to be valid... What a weird file! @@ -776,7 +771,7 @@ static bool CheckMODMagic(const char magic[4], MODMagicResult &result) CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderMOD(MemoryFileReader file, const uint64 *pfilesize) { - if(!file.CanRead(1080 + 4)) + if(!file.LengthIsAtLeast(1080 + 4)) { return ProbeWantMoreData; } @@ -1283,7 +1278,7 @@ bool CSoundFile::ReadMOD(FileReader &file, ModLoadingFlags loadFlags) } #endif // MPT_EXTERNAL_SAMPLES || MPT_BUILD_FUZZER - // Fix VBlank MODs. Arbitrary threshold: 10 minutes. + // Fix VBlank MODs. Arbitrary threshold: 8 minutes (enough for "frame of mind" by Dascon...). // Basically, this just converts all tempo commands into speed commands // for MODs which are supposed to have VBlank timing (instead of CIA timing). // There is no perfect way to do this, since both MOD types look the same, @@ -1296,12 +1291,12 @@ bool CSoundFile::ReadMOD(FileReader &file, ModLoadingFlags loadFlags) if(isMdKd && hasTempoCommands && !definitelyCIA) { const double songTime = GetLength(eNoAdjust).front().duration; - if(songTime >= 600.0) + if(songTime >= 480.0) { m_playBehaviour.set(kMODVBlankTiming); if(GetLength(eNoAdjust, GetLengthTarget(songTime)).front().targetReached) { - // This just makes things worse, song is at least as long as in CIA mode (e.g. in "Stary Hallway" by Neurodancer) + // This just makes things worse, song is at least as long as in CIA mode // Obviously we should keep using CIA timing then... m_playBehaviour.reset(kMODVBlankTiming); } else diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_s3m.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_s3m.cpp index e4e2f549c..586f2da24 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_s3m.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Load_s3m.cpp @@ -59,6 +59,9 @@ void CSoundFile::S3MConvert(ModCommand &m, bool fromIT) // Chars under 0x40 don't save properly, so map : to ] and # to [. case ']': m.command = CMD_DELAYCUT; break; case '[': m.command = CMD_XPARAM; break; + // BeRoTracker extensions + case '1' + 0x41: m.command = fromIT ? CMD_KEYOFF : CMD_NONE; break; + case '2' + 0x41: m.command = fromIT ? CMD_SETENVPOSITION : CMD_NONE; break; default: m.command = CMD_NONE; } } diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/ModChannel.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/ModChannel.cpp index 15321a06e..1584a1888 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/ModChannel.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/ModChannel.cpp @@ -41,6 +41,7 @@ void ModChannel::Reset(ResetFlags resetMask, const CSoundFile &sndFile, CHANNELI prevNoteOffset = 0; lastZxxParam = 0xFF; isFirstTick = false; + triggerNote = false; isPreviewNote = false; rowCommand.Clear(); } diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/ModChannel.h b/Frameworks/OpenMPT.old/OpenMPT/soundlib/ModChannel.h index a1af33a10..0262a6327 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/ModChannel.h +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/ModChannel.h @@ -71,7 +71,7 @@ struct ModChannel int32 newLeftVol, newRightVol; int32 nRealVolume, nRealPan; int32 nVolume, nPan, nFadeOutVol; - int32 nPeriod; // Frequency in Hz if !CSoundFile::PeriodsAreFrequencies() or using custom tuning, 4x Amiga periods otherwise + int32 nPeriod; // Frequency in Hz if CSoundFile::PeriodsAreFrequencies() or using custom tuning, 4x Amiga periods otherwise int32 nC5Speed, nPortamentoDest; int32 cachedPeriod, glissandoPeriod; int32 nCalcVolume; // Calculated channel volume, 14-Bit (without global volume, pre-amp etc applied) - for MIDI macros @@ -116,9 +116,10 @@ struct ModChannel FilterMode nFilterMode; uint8 nEFxSpeed, nEFxDelay; // memory for Invert Loop (EFx, .MOD only) uint8 nNoteSlideCounter, nNoteSlideSpeed, nNoteSlideStep; // IMF / PTM Note Slide - uint8 lastZxxParam; // Memory for \xx slides - bool isFirstTick : 1; - bool isPreviewNote : 1; + uint8 lastZxxParam; // Memory for \xx slides + bool isFirstTick : 1; // Execute tick-0 effects on this channel? (condition differs between formats due to Pattern Delay commands) + bool triggerNote : 1; // Trigger note on this tick on this channel if there is one? + bool isPreviewNote : 1; // Notes preview in editor //-->Variables used to make user-definable tuning modes work with pattern effects. //If true, freq should be recalculated in ReadNote() on first tick. diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_defs.h b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_defs.h index a8e6d729f..2082a688f 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_defs.h +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_defs.h @@ -649,8 +649,8 @@ public: MPT_CONSTEXPR11_FUN FPInt() : v(0) { } MPT_CONSTEXPR11_FUN FPInt(T intPart, T fractPart) : v((intPart * fractFact) + (fractPart % fractFact)) { } - explicit MPT_CONSTEXPR11_FUN FPInt(float f) : v(static_cast(f * float(fractFact))) { } - explicit MPT_CONSTEXPR11_FUN FPInt(double f) : v(static_cast(f * double(fractFact))) { } + explicit MPT_CONSTEXPR11_FUN FPInt(float f) : v(mpt::saturate_round(f * float(fractFact))) { } + explicit MPT_CONSTEXPR11_FUN FPInt(double f) : v(mpt::saturate_round(f * double(fractFact))) { } // Set integer and fractional part MPT_CONSTEXPR14_FUN FPInt &Set(T intPart, T fractPart = 0) { v = (intPart * fractFact) + (fractPart % fractFact); return *this; } diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_flt.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_flt.cpp index 29c8dd9a1..bfd34c2f6 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_flt.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_flt.cpp @@ -81,10 +81,10 @@ int CSoundFile::SetupChannelFilter(ModChannel &chn, bool bReset, int envModifier // Filtering is only ever done in IT if either cutoff is not full or if resonance is set. if(m_playBehaviour[kITFilterBehaviour] && resonance == 0 && computedCutoff >= 254) { - if(chn.rowCommand.IsNote() && !chn.rowCommand.IsPortamento() && !chn.nMasterChn && chn.isFirstTick) + if(chn.rowCommand.IsNote() && !chn.rowCommand.IsPortamento() && !chn.nMasterChn && chn.triggerNote) { // Z7F next to a note disables the filter, however in other cases this should not happen. - // Test cases: filter-reset.it, filter-reset-carry.it, filter-reset-envelope.it, filter-nna.it + // Test cases: filter-reset.it, filter-reset-carry.it, filter-reset-envelope.it, filter-nna.it, FilterResetPatDelay.it chn.dwFlags.reset(CHN_FILTER); } return -1; @@ -148,7 +148,7 @@ int CSoundFile::SetupChannelFilter(ModChannel &chn, bool bReset, int envModifier #endif // MPT_INTMIXER break; } -#undef FILTER_CONVERT +#undef MPT_FILTER_CONVERT if (bReset) { diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_fx.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_fx.cpp index 24f6fe7c1..46cc21b21 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_fx.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Snd_fx.cpp @@ -2659,6 +2659,7 @@ bool CSoundFile::ProcessEffects() { chn.isFirstTick = tickCount == nStartTick; } + chn.triggerNote = triggerNote; // FT2 compatibility: Note + portamento + note delay = no portamento // Test case: PortaDelay.xm @@ -5082,7 +5083,7 @@ void CSoundFile::ProcessMIDIMacro(CHANNELINDEX nChn, bool isSmooth, const char * } else if(macro[pos] == 'z') { // Zxx parameter - data = param & 0x7F; + data = param; if(isSmooth && chn.lastZxxParam < 0x80 && (outPos < 3 || out[outPos - 3] != 0xF0 || out[outPos - 2] < 0xF0)) { diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Sndmix.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Sndmix.cpp index 1edb97333..f90421404 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/Sndmix.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/Sndmix.cpp @@ -1908,6 +1908,8 @@ void CSoundFile::ProcessSampleAutoVibrato(ModChannel &chn, int &period, Tuning:: void CSoundFile::ProcessRamping(ModChannel &chn) const { chn.leftRamp = chn.rightRamp = 0; + LimitMax(chn.newLeftVol, int32_max >> VOLUMERAMPPRECISION); + LimitMax(chn.newRightVol, int32_max >> VOLUMERAMPPRECISION); if(chn.dwFlags[CHN_VOLUMERAMP] && (chn.leftVol != chn.newLeftVol || chn.rightVol != chn.newRightVol)) { const bool rampUp = (chn.newLeftVol > chn.leftVol) || (chn.newRightVol > chn.rightVol); @@ -2509,7 +2511,7 @@ void CSoundFile::ProcessMacroOnChannel(CHANNELINDEX nChn) if(chn.rowCommand.param < 0x80) ProcessMIDIMacro(nChn, (chn.rowCommand.command == CMD_SMOOTHMIDI), m_MidiCfg.szMidiSFXExt[chn.nActiveMacro], chn.rowCommand.param); else - ProcessMIDIMacro(nChn, (chn.rowCommand.command == CMD_SMOOTHMIDI), m_MidiCfg.szMidiZXXExt[(chn.rowCommand.param & 0x7F)], 0); + ProcessMIDIMacro(nChn, (chn.rowCommand.command == CMD_SMOOTHMIDI), m_MidiCfg.szMidiZXXExt[(chn.rowCommand.param & 0x7F)], chn.rowCommand.param); } } } diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/pattern.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/pattern.cpp index 9583ebf95..c6c8543a0 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/pattern.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/pattern.cpp @@ -262,7 +262,8 @@ bool CPattern::SetName(const char *newName, size_t maxChars) { return false; } - m_PatternName = mpt::truncate(newName, maxChars); + const auto nameEnd = std::find(newName, newName + maxChars, '\0'); + m_PatternName.assign(newName, nameEnd); return true; } diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/patternContainer.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/patternContainer.cpp index fe1ff17ad..2dfbbcfcd 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/patternContainer.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/patternContainer.cpp @@ -28,10 +28,7 @@ void CPatternContainer::ClearPatterns() void CPatternContainer::DestroyPatterns() { - for(PATTERNINDEX i = 0; i < m_Patterns.size(); i++) - { - Remove(i); - } + m_Patterns.clear(); } @@ -67,7 +64,7 @@ PATTERNINDEX CPatternContainer::InsertAny(const ROWINDEX rows, bool respectQtyLi bool CPatternContainer::Insert(const PATTERNINDEX index, const ROWINDEX rows) { - if(rows > MAX_PATTERN_ROWS || rows == 0) + if(rows > MAX_PATTERN_ROWS || rows == 0 || index >= PATTERNINDEX_INVALID) return false; if(IsValidPat(index)) return false; diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/plugins/dmo/I3DL2Reverb.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/plugins/dmo/I3DL2Reverb.cpp index 658767830..97eed3867 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/plugins/dmo/I3DL2Reverb.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/plugins/dmo/I3DL2Reverb.cpp @@ -616,10 +616,11 @@ float I3DL2Reverb::CalcDecayCoeffs(int32 index) float c2 = 0.0f; float c21 = (std::pow(c1, 2.0f - 2.0f / decayHFRatio) - 1.0f) / (1.0f - std::cos(hfRef)); - if(c21 != 0) + if(c21 != 0 && std::isfinite(c21)) { float c22 = -2.0f * c21 - 2.0f; - float c23 = std::sqrt(c22 * c22 - c21 * c21 * 4.0f); + float c23sq = c22 * c22 - c21 * c21 * 4.0f; + float c23 = c23sq > 0.0f ? std::sqrt(c23sq) : 0.0f; c2 = (c23 - c22) / (c21 + c21); if(std::abs(c2) > 1.0f) c2 = (-c22 - c23) / (c21 + c21); diff --git a/Frameworks/OpenMPT.old/OpenMPT/soundlib/tuning.cpp b/Frameworks/OpenMPT.old/OpenMPT/soundlib/tuning.cpp index a9d4a9952..e4ebbe928 100644 --- a/Frameworks/OpenMPT.old/OpenMPT/soundlib/tuning.cpp +++ b/Frameworks/OpenMPT.old/OpenMPT/soundlib/tuning.cpp @@ -23,6 +23,10 @@ OPENMPT_NAMESPACE_BEGIN namespace Tuning { +static RATIOTYPE SanitizeGroupRatio(RATIOTYPE ratio) +{ + return std::clamp(std::abs(ratio), 1e-15f, 1e+07f); +} namespace CTuningS11n { @@ -256,7 +260,12 @@ RATIOTYPE CTuning::GetRatio(const NOTEINDEXTYPE note) const { return s_DefaultFallbackRatio; } - return m_RatioTable[note - m_NoteMin]; + const auto ratio = m_RatioTable[note - m_NoteMin]; + if(ratio <= 1e-15f) + { + return s_DefaultFallbackRatio; + } + return ratio; } @@ -479,6 +488,17 @@ SerializationResult CTuning::InitDeserialize(std::istream &iStrm, mpt::Charset d UNOTEINDEXTYPE ratiotableSize = 0; ssb.ReadItem(ratiotableSize, "RTI4"); + m_GroupRatio = SanitizeGroupRatio(m_GroupRatio); + if(!std::isfinite(m_GroupRatio)) + { + return SerializationResult::Failure; + } + for(auto ratio : m_RatioTable) + { + if(!std::isfinite(ratio)) + return SerializationResult::Failure; + } + // If reader status is ok and m_NoteMin is somewhat reasonable, process data. if(!((ssb.GetStatus() & srlztn::SNT_FAILURE) == 0 && m_NoteMin >= -300 && m_NoteMin <= 300)) { @@ -682,6 +702,11 @@ SerializationResult CTuning::InitDeserializeOLD(std::istream &inStrm, mpt::Chars return SerializationResult::Failure; } } + for(auto ratio : m_RatioTable) + { + if(!std::isfinite(ratio)) + return SerializationResult::Failure; + } //Fineratios if(version <= 2) @@ -697,6 +722,11 @@ SerializationResult CTuning::InitDeserializeOLD(std::istream &inStrm, mpt::Chars return SerializationResult::Failure; } } + for(auto ratio : m_RatioTableFine) + { + if(!std::isfinite(ratio)) + return SerializationResult::Failure; + } m_FineStepCount = mpt::saturate_cast(m_RatioTableFine.size()); // m_NoteMin @@ -720,8 +750,8 @@ SerializationResult CTuning::InitDeserializeOLD(std::istream &inStrm, mpt::Chars //m_GroupRatio IEEE754binary32LE groupratio = IEEE754binary32LE(0.0f); mpt::IO::Read(inStrm, groupratio); - m_GroupRatio = groupratio; - if(m_GroupRatio < 0) + m_GroupRatio = SanitizeGroupRatio(groupratio); + if(!std::isfinite(m_GroupRatio)) { return SerializationResult::Failure; }