diff options
author | James Cowgill <jcowgill@debian.org> | 2019-10-30 23:08:35 +0000 |
---|---|---|
committer | James Cowgill <jcowgill@debian.org> | 2019-10-30 23:08:35 +0000 |
commit | 580d203514359a386479a96d1e69704e429974e7 (patch) | |
tree | e4804f71fcbbd229ab4bc63c4b53027a82b0b64b | |
parent | 3f8fc5dffe02081c55aa8a9fbe4ab090dd831e67 (diff) |
New upstream version 0.4.10
-rw-r--r-- | common/versionNumber.h | 4 | ||||
-rwxr-xr-x | configure | 26 | ||||
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | libopenmpt/dox/changelog.md | 17 | ||||
-rw-r--r-- | libopenmpt/libopenmpt.hpp | 2 | ||||
-rw-r--r-- | libopenmpt/libopenmpt_impl.cpp | 2 | ||||
-rw-r--r-- | libopenmpt/libopenmpt_version.h | 2 | ||||
-rw-r--r-- | libopenmpt/libopenmpt_version.mk | 4 | ||||
-rw-r--r-- | man/openmpt123.1 | 2 | ||||
-rw-r--r-- | soundlib/ITTools.cpp | 40 | ||||
-rw-r--r-- | soundlib/ITTools.h | 3 | ||||
-rw-r--r-- | soundlib/Load_it.cpp | 25 | ||||
-rw-r--r-- | soundlib/Load_itp.cpp | 48 | ||||
-rw-r--r-- | soundlib/Load_mtm.cpp | 2 | ||||
-rw-r--r-- | soundlib/Load_psm.cpp | 12 | ||||
-rw-r--r-- | soundlib/Load_s3m.cpp | 11 | ||||
-rw-r--r-- | soundlib/S3MTools.h | 5 | ||||
-rw-r--r-- | soundlib/Snd_fx.cpp | 1 | ||||
-rw-r--r-- | soundlib/Sndfile.cpp | 13 | ||||
-rw-r--r-- | soundlib/Sndfile.h | 16 | ||||
-rw-r--r-- | soundlib/Tables.cpp | 11 | ||||
-rw-r--r-- | soundlib/modcommand.cpp | 1 | ||||
-rw-r--r-- | soundlib/plugins/LFOPlugin.h | 2 | ||||
-rw-r--r-- | soundlib/tuning.h | 2 |
24 files changed, 157 insertions, 102 deletions
diff --git a/common/versionNumber.h b/common/versionNumber.h index ee67ed3..35bb47f 100644 --- a/common/versionNumber.h +++ b/common/versionNumber.h @@ -20,8 +20,8 @@ OPENMPT_NAMESPACE_BEGIN //Version definitions. The only thing that needs to be changed when changing version number. #define VER_MAJORMAJOR 1 #define VER_MAJOR 28 -#define VER_MINOR 07 -#define VER_MINORMINOR 04 +#define VER_MINOR 08 +#define VER_MINORMINOR 00 //Numerical value of the version. #define MPT_VERSION_CURRENT MAKE_VERSION_NUMERIC(VER_MAJORMAJOR,VER_MAJOR,VER_MINOR,VER_MINORMINOR) @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libopenmpt 0.4.9+release.autotools. +# Generated by GNU Autoconf 2.69 for libopenmpt 0.4.10+release.autotools. # # Report bugs to <https://bugs.openmpt.org/>. # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libopenmpt' PACKAGE_TARNAME='libopenmpt' -PACKAGE_VERSION='0.4.9+release.autotools' -PACKAGE_STRING='libopenmpt 0.4.9+release.autotools' +PACKAGE_VERSION='0.4.10+release.autotools' +PACKAGE_STRING='libopenmpt 0.4.10+release.autotools' PACKAGE_BUGREPORT='https://bugs.openmpt.org/' PACKAGE_URL='https://lib.openmpt.org/' @@ -1485,7 +1485,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libopenmpt 0.4.9+release.autotools to adapt to many kinds of systems. +\`configure' configures libopenmpt 0.4.10+release.autotools to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1556,7 +1556,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libopenmpt 0.4.9+release.autotools:";; + short | recursive ) echo "Configuration of libopenmpt 0.4.10+release.autotools:";; esac cat <<\_ACEOF @@ -1756,7 +1756,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libopenmpt configure 0.4.9+release.autotools +libopenmpt configure 0.4.10+release.autotools generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2246,7 +2246,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libopenmpt $as_me 0.4.9+release.autotools, which was +It was created by libopenmpt $as_me 0.4.10+release.autotools, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3117,7 +3117,7 @@ fi # Define the identity of the package. PACKAGE='libopenmpt' - VERSION='0.4.9+release.autotools' + VERSION='0.4.10+release.autotools' cat >>confdefs.h <<_ACEOF @@ -17281,13 +17281,13 @@ LIBOPENMPT_LTVER_AGE=1 -$as_echo "#define MPT_SVNURL \"https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.4.9\"" >>confdefs.h +$as_echo "#define MPT_SVNURL \"https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.4.10\"" >>confdefs.h -$as_echo "#define MPT_SVNVERSION \"12139\"" >>confdefs.h +$as_echo "#define MPT_SVNVERSION \"12263\"" >>confdefs.h -$as_echo "#define MPT_SVNDATE \"2019-10-02T14:33:59.345896Z\"" >>confdefs.h +$as_echo "#define MPT_SVNDATE \"2019-10-30T10:43:15.521271Z\"" >>confdefs.h $as_echo "#define MPT_PACKAGE true" >>confdefs.h @@ -23527,7 +23527,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libopenmpt $as_me 0.4.9+release.autotools, which was +This file was extended by libopenmpt $as_me 0.4.10+release.autotools, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -23594,7 +23594,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libopenmpt config.status 0.4.9+release.autotools +libopenmpt config.status 0.4.10+release.autotools configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 55f3593..81be412 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([libopenmpt], [0.4.9+release.autotools], [https://bugs.openmpt.org/], [libopenmpt], [https://lib.openmpt.org/]) +AC_INIT([libopenmpt], [0.4.10+release.autotools], [https://bugs.openmpt.org/], [libopenmpt], [https://lib.openmpt.org/]) AC_PREREQ([2.68]) AC_CONFIG_MACRO_DIR([m4]) @@ -27,9 +27,9 @@ AC_SUBST([LIBOPENMPT_LTVER_CURRENT]) AC_SUBST([LIBOPENMPT_LTVER_REVISION]) AC_SUBST([LIBOPENMPT_LTVER_AGE]) -AC_DEFINE([MPT_SVNURL], ["https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.4.9"], [svn version]) -AC_DEFINE([MPT_SVNVERSION], ["12139"], [svn version]) -AC_DEFINE([MPT_SVNDATE], ["2019-10-02T14:33:59.345896Z"], [svn date]) +AC_DEFINE([MPT_SVNURL], ["https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.4.10"], [svn version]) +AC_DEFINE([MPT_SVNVERSION], ["12263"], [svn version]) +AC_DEFINE([MPT_SVNDATE], ["2019-10-30T10:43:15.521271Z"], [svn date]) AC_DEFINE([MPT_PACKAGE], [true], [is package]) diff --git a/libopenmpt/dox/changelog.md b/libopenmpt/dox/changelog.md index 6b4c678..5b98fcf 100644 --- a/libopenmpt/dox/changelog.md +++ b/libopenmpt/dox/changelog.md @@ -5,6 +5,16 @@ Changelog {#changelog} For fully detailed change log, please see the source repository directly. This is just a high-level summary. +### libopenmpt 0.4.10 (2019-10-30) + + * The "date" metadata could contain a bogus date for some older IT files. + * Do not apply global volume ramping from initial global volume when seeking. + + * MTM: Sample loop length was off by one. + * PSM: Sample loop length was off by one in most files. + + * mpg123: Update to v1.25.13 (2019-10-26). + ### libopenmpt 0.4.9 (2019-10-02) * [**Sec**] libmodplug: C API: Limit the length of strings copied to the @@ -16,6 +26,7 @@ is just a high-level summary. applies to strings encoded in arbitrary character encodings but the API returns them converted to UTF-8, which can be longer. (reported by Antonio Morales Maldonado of Semmle Security Research Team) (r12129) + ([CVE-2019-17113](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17113)) * [**Sec**] libmodplug: C++ API: Do not return 0 in `CSoundFile::GetSampleName()` and `CSoundFile::GetInstrumentName()` when a null output pointer is provided. This behaviour differed from libmodplug and @@ -35,7 +46,7 @@ is just a high-level summary. * J2B: Ignore notes with non-existing instrument (fixes Ending.j2b). - * mpg123: Update to v1.25.13 (2019-08-24). + * mpg123: Update to v1.25.12 (2019-08-24). * ogg: Update to v1.3.4. (2019-08-31). * flac: Update to v1.3.3. (2019-08-04). @@ -59,6 +70,7 @@ is just a high-level summary. * [**Sec**] Possible crash during playback due out-of-bounds read in XM and MT2 files (r11608). + ([CVE-2019-14380](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14380)) * Breaking out of a sustain loop through Note-Off sometimes didn't continue in the regular sample loop. @@ -81,6 +93,7 @@ is just a high-level summary. * [**Sec**] Possible crash due to null-pointer access when doing a portamento from an OPL instrument to an empty instrument note map slot (r11348). + ([CVE-2019-14381](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14381)) * [**Bug**] libopenmpt did not compile on Apple platforms in C++17 mode. @@ -95,8 +108,10 @@ is just a high-level summary. * [**Sec**] DSM: Assertion failure during file parsing with debug STLs (r11209). + ([CVE-2019-14382](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14382)) * [**Sec**] J2B: Assertion failure during file parsing with debug STLs (r11216). + ([CVE-2019-14383](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14383)) * S3M: Allow volume change of OPL instruments after Note Cut. diff --git a/libopenmpt/libopenmpt.hpp b/libopenmpt/libopenmpt.hpp index 55097f8..f16ccd6 100644 --- a/libopenmpt/libopenmpt.hpp +++ b/libopenmpt/libopenmpt.hpp @@ -251,7 +251,7 @@ LIBOPENMPT_CXX_API double could_open_probability( std::istream & stream, double //! Roughly scan the input stream to find out whether libopenmpt might be able to open it /*! - \deprecated Please use openmpt::module::could_open_probability(). + \deprecated Please use openmpt::could_open_probability(). */ LIBOPENMPT_ATTR_DEPRECATED LIBOPENMPT_CXX_API LIBOPENMPT_DEPRECATED double could_open_propability( std::istream & stream, double effort = 1.0, std::ostream & log = std::clog ); diff --git a/libopenmpt/libopenmpt_impl.cpp b/libopenmpt/libopenmpt_impl.cpp index 6ade376..1f74f1c 100644 --- a/libopenmpt/libopenmpt_impl.cpp +++ b/libopenmpt/libopenmpt_impl.cpp @@ -1133,7 +1133,7 @@ std::string module_impl::get_metadata( const std::string & key ) const { } else if ( key == std::string("title") ) { return mod_string_to_utf8( m_sndFile->GetTitle() ); } else if ( key == std::string("date") ) { - if ( m_sndFile->GetFileHistory().empty() ) { + if ( m_sndFile->GetFileHistory().empty() || !m_sndFile->GetFileHistory().back().HasValidDate() ) { return std::string(); } return mpt::ToCharset(mpt::CharsetUTF8, m_sndFile->GetFileHistory().back().AsISO8601() ); diff --git a/libopenmpt/libopenmpt_version.h b/libopenmpt/libopenmpt_version.h index 686c351..ad3941e 100644 --- a/libopenmpt/libopenmpt_version.h +++ b/libopenmpt/libopenmpt_version.h @@ -19,7 +19,7 @@ /*! \brief libopenmpt minor version number */ #define OPENMPT_API_VERSION_MINOR 4 /*! \brief libopenmpt patch version number */ -#define OPENMPT_API_VERSION_PATCH 9 +#define OPENMPT_API_VERSION_PATCH 10 /*! \brief libopenmpt pre-release tag */ #define OPENMPT_API_VERSION_PREREL "" /*! \brief libopenmpt pre-release flag */ diff --git a/libopenmpt/libopenmpt_version.mk b/libopenmpt/libopenmpt_version.mk index 59dd997..1dc9026 100644 --- a/libopenmpt/libopenmpt_version.mk +++ b/libopenmpt/libopenmpt_version.mk @@ -1,8 +1,8 @@ LIBOPENMPT_VERSION_MAJOR=0 LIBOPENMPT_VERSION_MINOR=4 -LIBOPENMPT_VERSION_PATCH=9 +LIBOPENMPT_VERSION_PATCH=10 LIBOPENMPT_VERSION_PREREL= LIBOPENMPT_LTVER_CURRENT=1 -LIBOPENMPT_LTVER_REVISION=9 +LIBOPENMPT_LTVER_REVISION=10 LIBOPENMPT_LTVER_AGE=1 diff --git a/man/openmpt123.1 b/man/openmpt123.1 index 5f8572b..5a1005e 100644 --- a/man/openmpt123.1 +++ b/man/openmpt123.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH OPENMPT123 "1" "October 2019" "openmpt123 v0.4.9" "User Commands" +.TH OPENMPT123 "1" "October 2019" "openmpt123 v0.4.10" "User Commands" .SH NAME openmpt123 - command line module music player based on libopenmpt .SH SYNOPSIS diff --git a/soundlib/ITTools.cpp b/soundlib/ITTools.cpp index 56cce3e..13a3923 100644 --- a/soundlib/ITTools.cpp +++ b/soundlib/ITTools.cpp @@ -637,12 +637,15 @@ void ITHistoryStruct::ConvertToMPT(FileHistory &mptHistory) const { // Decode FAT date and time MemsetZero(mptHistory.loadDate); - mptHistory.loadDate.tm_year = ((fatdate >> 9) & 0x7F) + 80; - mptHistory.loadDate.tm_mon = Clamp((fatdate >> 5) & 0x0F, 1, 12) - 1; - mptHistory.loadDate.tm_mday = Clamp(fatdate & 0x1F, 1, 31); - mptHistory.loadDate.tm_hour = Clamp((fattime >> 11) & 0x1F, 0, 23); - mptHistory.loadDate.tm_min = Clamp((fattime >> 5) & 0x3F, 0, 59); - mptHistory.loadDate.tm_sec = Clamp((fattime & 0x1F) * 2, 0, 59); + if(fatdate != 0 || fattime != 0) + { + mptHistory.loadDate.tm_year = ((fatdate >> 9) & 0x7F) + 80; + mptHistory.loadDate.tm_mon = Clamp((fatdate >> 5) & 0x0F, 1, 12) - 1; + mptHistory.loadDate.tm_mday = Clamp(fatdate & 0x1F, 1, 31); + mptHistory.loadDate.tm_hour = Clamp((fattime >> 11) & 0x1F, 0, 23); + mptHistory.loadDate.tm_min = Clamp((fattime >> 5) & 0x3F, 0, 59); + mptHistory.loadDate.tm_sec = Clamp((fattime & 0x1F) * 2, 0, 59); + } mptHistory.openTime = static_cast<uint32>(runtime * (HISTORY_TIMER_PRECISION / 18.2)); } @@ -651,10 +654,31 @@ void ITHistoryStruct::ConvertToMPT(FileHistory &mptHistory) const void ITHistoryStruct::ConvertToIT(const FileHistory &mptHistory) { // Create FAT file dates - fatdate = static_cast<uint16>(mptHistory.loadDate.tm_mday | ((mptHistory.loadDate.tm_mon + 1) << 5) | ((mptHistory.loadDate.tm_year - 80) << 9)); - fattime = static_cast<uint16>((mptHistory.loadDate.tm_sec / 2) | (mptHistory.loadDate.tm_min << 5) | (mptHistory.loadDate.tm_hour << 11)); + if(mptHistory.HasValidDate()) + { + fatdate = static_cast<uint16>(mptHistory.loadDate.tm_mday | ((mptHistory.loadDate.tm_mon + 1) << 5) | ((mptHistory.loadDate.tm_year - 80) << 9)); + fattime = static_cast<uint16>((mptHistory.loadDate.tm_sec / 2) | (mptHistory.loadDate.tm_min << 5) | (mptHistory.loadDate.tm_hour << 11)); + } else + { + fatdate = 0; + fattime = 0; + } runtime = static_cast<uint32>(mptHistory.openTime * (18.2 / HISTORY_TIMER_PRECISION)); } +uint32 DecodeITEditTimer(uint16 cwtv, uint32 editTime) +{ + if((cwtv & 0xFFF) >= 0x0208) + { + editTime ^= 0x4954524B; // 'ITRK' + editTime = (editTime >> 7) | (editTime << (32 - 7)); + editTime = -(int32)editTime; + editTime = (editTime << 4) | (editTime >> (32 - 4)); + editTime ^= 0x4A54484C; // 'JTHL' + } + return editTime; +} + + OPENMPT_NAMESPACE_END diff --git a/soundlib/ITTools.h b/soundlib/ITTools.h index d2b3a1a..66759f2 100644 --- a/soundlib/ITTools.h +++ b/soundlib/ITTools.h @@ -317,4 +317,7 @@ struct SchismVersionFromDate } }; + +uint32 DecodeITEditTimer(uint16 cwtv, uint32 editTime); + OPENMPT_NAMESPACE_END diff --git a/soundlib/Load_it.cpp b/soundlib/Load_it.cpp index 069e4a4..e149e1d 100644 --- a/soundlib/Load_it.cpp +++ b/soundlib/Load_it.cpp @@ -344,19 +344,19 @@ static void CopyPatternName(CPattern &pattern, FileReader &file) // Get version of Schism Tracker that was used to create an IT/S3M file. -mpt::ustring CSoundFile::GetSchismTrackerVersion(uint16 cwtv) +mpt::ustring CSoundFile::GetSchismTrackerVersion(uint16 cwtv, uint32 reserved) { // Schism Tracker version information in a nutshell: // < 0x020: a proper version (files saved by such versions are likely very rare) // = 0x020: any version between the 0.2a release (2005-04-29?) and 2007-04-17 // = 0x050: anywhere from 2007-04-17 to 2009-10-31 // > 0x050: the number of days since 2009-10-31 + // = 0xFFF: any version starting from 2020-10-28 (exact version stored in reserved value) cwtv &= 0xFFF; - mpt::ustring version; if(cwtv > 0x050) { - int32 date = SchismVersionFromDate<2009, 10, 31>::date + cwtv - 0x050; + int32 date = SchismVersionFromDate<2009, 10, 31>::date + (cwtv < 0xFFF ? cwtv - 0x050 : reserved); int32 y = static_cast<int32>((Util::mul32to64(10000, date) + 14780) / 3652425); int32 ddd = date - (365 * y + y / 4 - y / 100 + y / 400); if(ddd < 0) @@ -365,15 +365,14 @@ mpt::ustring CSoundFile::GetSchismTrackerVersion(uint16 cwtv) ddd = date - (365 * y + y / 4 - y / 100 + y / 400); } int32 mi = (100 * ddd + 52) / 3060; - version = mpt::format(U_("Schism Tracker %1-%2-%3"))( + return mpt::format(U_("Schism Tracker %1-%2-%3"))( mpt::ufmt::dec0<4>(y + (mi + 2) / 12), mpt::ufmt::dec0<2>((mi + 2) % 12 + 1), mpt::ufmt::dec0<2>(ddd - (mi * 306 + 5) / 10 + 1)); } else { - version = mpt::format(U_("Schism Tracker 0.%1"))(mpt::ufmt::hex(cwtv)); + return mpt::format(U_("Schism Tracker 0.%1"))(mpt::ufmt::hex0<2>(cwtv)); } - return version; } @@ -1197,16 +1196,8 @@ bool CSoundFile::ReadIT(FileReader &file, ModLoadingFlags loadFlags) } if(m_FileHistory.empty() && fileHeader.reserved != 0) { - // Starting from version 2.07, IT encrypts the total edit time of a module in the "reserved" field - uint32 editTime = fileHeader.reserved; - if(fileHeader.cwtv >= 0x0208) - { - editTime ^= 0x4954524B; // 'ITRK' - editTime = (editTime >> 7) | (editTime << (32 - 7)); - editTime = -(int32)editTime; - editTime = (editTime << 4) | (editTime >> (32 - 4)); - editTime ^= 0x4A54484C; // 'JTHL' - } + // Starting from version 2.07, IT stores the total edit time of a module in the "reserved" field + uint32 editTime = DecodeITEditTimer(fileHeader.cwtv, fileHeader.reserved); FileHistory hist; hist.openTime = static_cast<uint32>(editTime * (HISTORY_TIMER_PRECISION / 18.2)); @@ -1215,7 +1206,7 @@ bool CSoundFile::ReadIT(FileReader &file, ModLoadingFlags loadFlags) } break; case 1: - madeWithTracker = GetSchismTrackerVersion(fileHeader.cwtv); + madeWithTracker = GetSchismTrackerVersion(fileHeader.cwtv, fileHeader.reserved); // Hertz in linear mode: Added 2015-01-29, https://github.com/schismtracker/schismtracker/commit/671b30311082a0e7df041fca25f989b5d2478f69 if(fileHeader.cwtv < SchismVersionFromDate<2015, 01, 29>::Version()) m_playBehaviour.reset(kHertzInLinearMode); diff --git a/soundlib/Load_itp.cpp b/soundlib/Load_itp.cpp index 053a26a..7c4f982 100644 --- a/soundlib/Load_itp.cpp +++ b/soundlib/Load_itp.cpp @@ -116,13 +116,13 @@ bool CSoundFile::ReadITP(FileReader &file, ModLoadingFlags loadFlags) enum ITPSongFlags { - ITP_EMBEDMIDICFG = 0x00001, // Embed macros in file - ITP_ITOLDEFFECTS = 0x00004, // Old Impulse Tracker effect implementations - ITP_ITCOMPATGXX = 0x00008, // IT "Compatible Gxx" (IT's flag to behave more like other trackers w/r/t portamento effects) - ITP_LINEARSLIDES = 0x00010, // Linear slides vs. Amiga slides - ITP_EXFILTERRANGE = 0x08000, // Cutoff Filter has double frequency range (up to ~10Khz) - ITP_ITPROJECT = 0x20000, // Is a project file - ITP_ITPEMBEDIH = 0x40000, // Embed instrument headers in project file + ITP_EMBEDMIDICFG = 0x00001, // Embed macros in file + ITP_ITOLDEFFECTS = 0x00004, // Old Impulse Tracker effect implementations + ITP_ITCOMPATGXX = 0x00008, // IT "Compatible Gxx" (IT's flag to behave more like other trackers w/r/t portamento effects) + ITP_LINEARSLIDES = 0x00010, // Linear slides vs. Amiga slides + ITP_EXFILTERRANGE = 0x08000, // Cutoff Filter has double frequency range (up to ~10Khz) + ITP_ITPROJECT = 0x20000, // Is a project file + ITP_ITPEMBEDIH = 0x40000, // Embed instrument headers in project file }; file.Rewind(); @@ -145,8 +145,7 @@ bool CSoundFile::ReadITP(FileReader &file, ModLoadingFlags loadFlags) return true; } - uint32 version, size; - version = hdr.version; + const uint32 version = hdr.version; InitializeGlobals(MOD_TYPE_IT); m_playBehaviour.reset(); @@ -161,10 +160,14 @@ bool CSoundFile::ReadITP(FileReader &file, ModLoadingFlags loadFlags) { return false; } - if(songFlags & ITP_ITOLDEFFECTS) m_SongFlags.set(SONG_ITOLDEFFECTS); - if(songFlags & ITP_ITCOMPATGXX) m_SongFlags.set(SONG_ITCOMPATGXX); - if(songFlags & ITP_LINEARSLIDES) m_SongFlags.set(SONG_LINEARSLIDES); - if(songFlags & ITP_EXFILTERRANGE) m_SongFlags.set(SONG_EXFILTERRANGE); + if(songFlags & ITP_ITOLDEFFECTS) + m_SongFlags.set(SONG_ITOLDEFFECTS); + if(songFlags & ITP_ITCOMPATGXX) + m_SongFlags.set(SONG_ITCOMPATGXX); + if(songFlags & ITP_LINEARSLIDES) + m_SongFlags.set(SONG_LINEARSLIDES); + if(songFlags & ITP_EXFILTERRANGE) + m_SongFlags.set(SONG_EXFILTERRANGE); m_nDefaultGlobalVolume = file.ReadUint32LE(); m_nSamplePreAmp = file.ReadUint32LE(); @@ -177,7 +180,7 @@ bool CSoundFile::ReadITP(FileReader &file, ModLoadingFlags loadFlags) } // channel name string length (=MAX_CHANNELNAME) - size = file.ReadUint32LE(); + uint32 size = file.ReadUint32LE(); // Channels' data for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) @@ -210,7 +213,7 @@ bool CSoundFile::ReadITP(FileReader &file, ModLoadingFlags loadFlags) } // Instruments' paths - if(version <= 0x00000102) + if(version <= 0x102) { size = file.ReadUint32LE(); // path string length } @@ -218,14 +221,14 @@ bool CSoundFile::ReadITP(FileReader &file, ModLoadingFlags loadFlags) std::vector<mpt::PathString> instrPaths(GetNumInstruments()); for(INSTRUMENTINDEX ins = 0; ins < GetNumInstruments(); ins++) { - if(version > 0x00000102) + if(version > 0x102) { size = file.ReadUint32LE(); // path string length } std::string path; file.ReadString<mpt::String::maybeNullTerminated>(path, size); #ifdef MODPLUG_TRACKER - if(version <= 0x00000102) + if(version <= 0x102) { instrPaths[ins] = mpt::PathString::FromLocaleSilent(path); } else @@ -256,7 +259,7 @@ bool CSoundFile::ReadITP(FileReader &file, ModLoadingFlags loadFlags) // modcommand data length size = file.ReadUint32LE(); - if(size != 6) + if(size != sizeof(ITPModCommand)) { return false; } @@ -318,7 +321,10 @@ bool CSoundFile::ReadITP(FileReader &file, ModLoadingFlags loadFlags) file.ReadStruct(sampleHeader); FileReader sampleData = file.ReadChunk(file.ReadUint32LE()); - if(realSample >= 1 && realSample <= GetNumSamples() && !memcmp(sampleHeader.id, "IMPS", 4) && (loadFlags & loadSampleData)) + if((loadFlags & loadSampleData) + && realSample >= 1 && realSample <= GetNumSamples() + && Samples[realSample].pData.pSample == nullptr + && !memcmp(sampleHeader.id, "IMPS", 4)) { sampleHeader.ConvertToMPT(Samples[realSample]); mpt::String::Read<mpt::String::nullTerminated>(m_szNames[realSample], sampleHeader.name); @@ -342,7 +348,7 @@ bool CSoundFile::ReadITP(FileReader &file, ModLoadingFlags loadFlags) AddToLog(LogWarning, U_("Unable to open instrument: ") + instrPaths[ins].ToUnicode()); } #else - AddToLog(LogWarning, mpt::format(U_("Loading external instrument %1 ('%2') failed: External instruments are not supported."))(ins, instrPaths[ins].ToUnicode())); + AddToLog(LogWarning, mpt::format(U_("Loading external instrument %1 ('%2') failed: External instruments are not supported."))(ins + 1, instrPaths[ins].ToUnicode())); #endif // MPT_EXTERNAL_SAMPLES } @@ -350,7 +356,7 @@ bool CSoundFile::ReadITP(FileReader &file, ModLoadingFlags loadFlags) uint32 code = file.ReadUint32LE(); // Embed instruments' header [v1.01] - if(version >= 0x00000101 && (songFlags & ITP_ITPEMBEDIH) && code == MagicBE("EBIH")) + if(version >= 0x101 && (songFlags & ITP_ITPEMBEDIH) && code == MagicBE("EBIH")) { code = file.ReadUint32LE(); diff --git a/soundlib/Load_mtm.cpp b/soundlib/Load_mtm.cpp index 3819602..0c2231a 100644 --- a/soundlib/Load_mtm.cpp +++ b/soundlib/Load_mtm.cpp @@ -54,7 +54,7 @@ struct MTMSampleHeader { mptSmp.nLength = length; mptSmp.nLoopStart = loopStart; - mptSmp.nLoopEnd = loopEnd; + mptSmp.nLoopEnd = std::max(loopEnd.get(), uint32(1)) - 1; LimitMax(mptSmp.nLoopEnd, mptSmp.nLength); if(mptSmp.nLoopStart + 4 >= mptSmp.nLoopEnd) mptSmp.nLoopStart = mptSmp.nLoopEnd = 0; if(mptSmp.nLoopEnd) mptSmp.uFlags.set(CHN_LOOP); diff --git a/soundlib/Load_psm.cpp b/soundlib/Load_psm.cpp index 3f96802..d03f092 100644 --- a/soundlib/Load_psm.cpp +++ b/soundlib/Load_psm.cpp @@ -107,10 +107,12 @@ struct PSMSampleHeader mptSmp.nC5Speed = c5Freq; mptSmp.nLength = sampleLength; mptSmp.nLoopStart = loopStart; - // It is not entirely clear if/when we should add +1 to the loopEnd value. - // Sample 8 in the medieval table music of Extreme Pinball and CONVERT.EXE v1.36 suggest that we should do so. - // But for other tunes it's not correct, e.g. the OMF 2097 music! - mptSmp.nLoopEnd = loopEnd; + // Note that we shouldn't add + 1 for MTM conversions here (e.g. the OMF 2097 music), + // but I think there is no way to figure out the original format, and in the case of the OMF 2097 soundtrack + // it doesn't make a huge audible difference anyway (no chip samples are used). + // On the other hand, sample 8 of MUSIC_A.PSM from Extreme Pinball will sound detuned if we don't adjust the loop end here. + if(loopEnd) + mptSmp.nLoopEnd = loopEnd + 1; mptSmp.nVolume = (defaultVolume + 1) * 2; mptSmp.uFlags.set(CHN_LOOP, (flags & 0x80) != 0); LimitMax(mptSmp.nLoopEnd, mptSmp.nLength); @@ -189,7 +191,7 @@ static uint8 ConvertPSMPorta(uint8 param, bool sinariaFormat) } -// Read a Pattern ID (something like "P0 " or "P13 " in the old format, or "PATT0 " in Sinaria) +// Read a Pattern ID (something like "P0 " or "P13 ", or "PATT0 " in Sinaria) static PATTERNINDEX ReadPSMPatternIndex(FileReader &file, bool &sinariaFormat) { char patternID[5]; diff --git a/soundlib/Load_s3m.cpp b/soundlib/Load_s3m.cpp index f5faa90..5171166 100644 --- a/soundlib/Load_s3m.cpp +++ b/soundlib/Load_s3m.cpp @@ -277,6 +277,15 @@ bool CSoundFile::ReadS3M(FileReader &file, ModLoadingFlags loadFlags) { madeWithTracker = mpt::format(U_("Impulse Tracker 2.14p%1"))(fileHeader.cwtv - S3MFileHeader::trkIT2_14); } + if(fileHeader.cwtv >= S3MFileHeader::trkIT2_07 && fileHeader.reserved3 != 0) + { + // Starting from version 2.07, IT stores the total edit time of a module in the "reserved" field + uint32 editTime = DecodeITEditTimer(fileHeader.cwtv, fileHeader.reserved3); + + FileHistory hist; + hist.openTime = static_cast<uint32>(editTime * (HISTORY_TIMER_PRECISION / 18.2)); + m_FileHistory.push_back(hist); + } nonCompatTracker = true; m_nMinPeriod = 1; break; @@ -287,7 +296,7 @@ bool CSoundFile::ReadS3M(FileReader &file, ModLoadingFlags loadFlags) m_playBehaviour.set(kST3LimitPeriod); } else { - madeWithTracker = GetSchismTrackerVersion(fileHeader.cwtv); + madeWithTracker = GetSchismTrackerVersion(fileHeader.cwtv, fileHeader.reserved2); m_nMinPeriod = 1; isSchism = true; } diff --git a/soundlib/S3MTools.h b/soundlib/S3MTools.h index 00753aa..c27e707 100644 --- a/soundlib/S3MTools.h +++ b/soundlib/S3MTools.h @@ -44,6 +44,7 @@ struct S3MFileHeader trkCreamTracker = 0x7000, trkST3_20 = 0x1320, + trkIT2_07 = 0x3207, trkIT2_14 = 0x3214, trkBeRoTrackerOld = 0x4100, // Used from 2004 to 2012 trkCamoto = 0xCA00, @@ -82,7 +83,9 @@ struct S3MFileHeader uint8le masterVolume; // Sample Volume (0...127, stereo if high bit is set) uint8le ultraClicks; // Number of channels used for ultra click removal uint8le usePanningTable; // 0xFC => read extended panning table - char reserved2[8]; // More reserved bytes + uint16le reserved2; // Schism Tracker uses this for its extended version information + uint32le reserved3; // Impulse Tracker hides its edit timer here + uint16le reserved4; uint16le special; // Pointer to special custom data (unused) uint8le channels[32]; // Channel setup }; diff --git a/soundlib/Snd_fx.cpp b/soundlib/Snd_fx.cpp index 3252d3c..77f86ea 100644 --- a/soundlib/Snd_fx.cpp +++ b/soundlib/Snd_fx.cpp @@ -1257,6 +1257,7 @@ std::vector<GetLengthType> CSoundFile::GetLength(enmGetLengthResetMode adjustMod { // Target found, or there is no target (i.e. play whole song)... m_PlayState = std::move(playState); + m_PlayState.ResetGlobalVolumeRamping(); m_PlayState.m_nNextRow = m_PlayState.m_nRow; m_PlayState.m_nFrameDelay = m_PlayState.m_nPatternDelay = 0; m_PlayState.m_nTickCount = Util::MaxValueOfType(m_PlayState.m_nTickCount) - 1; diff --git a/soundlib/Sndfile.cpp b/soundlib/Sndfile.cpp index 45e0ed6..cce5e50 100644 --- a/soundlib/Sndfile.cpp +++ b/soundlib/Sndfile.cpp @@ -536,10 +536,7 @@ bool CSoundFile::Create(FileReader file, ModLoadingFlags loadFlags) m_PlayState.m_nCurrentRowsPerBeat = m_nDefaultRowsPerBeat; m_PlayState.m_nCurrentRowsPerMeasure = m_nDefaultRowsPerMeasure; m_PlayState.m_nGlobalVolume = static_cast<int32>(m_nDefaultGlobalVolume); - m_PlayState.m_lHighResRampingGlobalVolume = m_PlayState.m_nGlobalVolume<<VOLUMERAMPPRECISION; - m_PlayState.m_nGlobalVolumeDestination = m_PlayState.m_nGlobalVolume; - m_PlayState.m_nSamplesToGlobalVolRampDest = 0; - m_PlayState.m_nGlobalVolumeRampAmount = 0; + m_PlayState.ResetGlobalVolumeRamping(); m_PlayState.m_nNextOrder = 0; m_PlayState.m_nCurrentOrder = 0; m_PlayState.m_nPattern = 0; @@ -766,11 +763,8 @@ void CSoundFile::ResetPlayPos() m_PlayState.m_nMusicSpeed = m_nDefaultSpeed; m_PlayState.m_nMusicTempo = m_nDefaultTempo; - // do not ramp global volume when starting playback - m_PlayState.m_lHighResRampingGlobalVolume = m_PlayState.m_nGlobalVolume<<VOLUMERAMPPRECISION; - m_PlayState.m_nGlobalVolumeDestination = m_PlayState.m_nGlobalVolume; - m_PlayState.m_nSamplesToGlobalVolRampDest = 0; - m_PlayState.m_nGlobalVolumeRampAmount = 0; + // Do not ramp global volume when starting playback + m_PlayState.ResetGlobalVolumeRamping(); m_PlayState.m_nNextOrder = 0; m_PlayState.m_nNextRow = 0; @@ -780,7 +774,6 @@ void CSoundFile::ResetPlayPos() m_PlayState.m_nFrameDelay = 0; m_PlayState.m_nNextPatStartRow = 0; m_PlayState.m_lTotalSampleCount = 0; - //m_nSeqOverride = 0; } diff --git a/soundlib/Sndfile.h b/soundlib/Sndfile.h index 5b55043..26ffafe 100644 --- a/soundlib/Sndfile.h +++ b/soundlib/Sndfile.h @@ -225,13 +225,15 @@ class CModDoc; struct FileHistory { - FileHistory() : openTime(0) { MemsetZero(loadDate); } + FileHistory() { MemsetZero(loadDate); } // Date when the file was loaded in the the tracker or created. tm loadDate; // Time the file was open in the editor, in 1/18.2th seconds (frequency of a standard DOS timer, to keep compatibility with Impulse Tracker easy). - uint32 openTime; + uint32 openTime = 0; // Return the date as a (possibly truncated if not enough precision is available) ISO 8601 formatted date. mpt::ustring AsISO8601() const; + // Returns true if the date component is valid. Some formats only store edit time, not edit date. + bool HasValidDate() const { return loadDate.tm_mday != 0; } }; @@ -506,6 +508,14 @@ public: { std::fill(std::begin(Chn), std::end(Chn), ModChannel()); } + + void ResetGlobalVolumeRamping() + { + m_lHighResRampingGlobalVolume = m_nGlobalVolume << VOLUMERAMPPRECISION; + m_nGlobalVolumeDestination = m_nGlobalVolume; + m_nSamplesToGlobalVolRampDest = 0; + m_nGlobalVolumeRampAmount = 0; + } }; PlayState m_PlayState; @@ -820,7 +830,7 @@ public: void LoadExtendedSongProperties(FileReader &file, bool ignoreChannelCount, bool* pInterpretMptMade = nullptr); void LoadMPTMProperties(FileReader &file, uint16 cwtv); - mpt::ustring GetSchismTrackerVersion(uint16 cwtv); + static mpt::ustring GetSchismTrackerVersion(uint16 cwtv, uint32 reserved); // Reads extended instrument properties(XM/IT/MPTM). // Returns true if extended instrument properties were found. diff --git a/soundlib/Tables.cpp b/soundlib/Tables.cpp index 3a701b2..fc0f3fd 100644 --- a/soundlib/Tables.cpp +++ b/soundlib/Tables.cpp @@ -765,12 +765,9 @@ void CResampler::InitializeTablesFromScratch(bool force) { initParameterIndependentTables = true; } - #ifdef MODPLUG_TRACKER - if(!StaticTablesInitialized) - { - initParameterIndependentTables = true; - } - #endif // MODPLUG_TRACKER +#ifdef MODPLUG_TRACKER + initParameterIndependentTables = !StaticTablesInitialized; +#endif // MODPLUG_TRACKER MPT_MAYBE_CONSTANT_IF(initParameterIndependentTables) { @@ -802,7 +799,7 @@ void CResampler::InitializeTablesFromScratch(bool force) static const CResampler & GetCachedResampler() { static CResampler s_CachedResampler(true); - return s_CachedResampler; + return s_CachedResampler; } diff --git a/soundlib/modcommand.cpp b/soundlib/modcommand.cpp index 1c9217d..99a4fc2 100644 --- a/soundlib/modcommand.cpp +++ b/soundlib/modcommand.cpp @@ -308,6 +308,7 @@ void ModCommand::Convert(MODTYPE fromType, MODTYPE toType, const CSoundFile &snd { param = 0x0F | (std::min<PARAM>(0x0E, param & 0x0F) << 4); } + break; default: break; diff --git a/soundlib/plugins/LFOPlugin.h b/soundlib/plugins/LFOPlugin.h index 2a44474..7301070 100644 --- a/soundlib/plugins/LFOPlugin.h +++ b/soundlib/plugins/LFOPlugin.h @@ -145,7 +145,7 @@ protected: public: static LFOWaveform ParamToWaveform(float param) { return static_cast<LFOWaveform>(mpt::saturate_round<int>(param * 32.0f)); } - static float WaveformToParam(LFOWaveform waveform) { return waveform / 32.0f; } + static float WaveformToParam(LFOWaveform waveform) { return static_cast<int>(waveform) / 32.0f; } }; OPENMPT_NAMESPACE_END diff --git a/soundlib/tuning.h b/soundlib/tuning.h index 050e6a1..828f2e3 100644 --- a/soundlib/tuning.h +++ b/soundlib/tuning.h @@ -140,7 +140,7 @@ public: { CTuningRTI *pT = new CTuningRTI(); pT->SetName(name); - VRPAIR range = std::make_pair(s_StepMinDefault, static_cast<NOTEINDEXTYPE>(s_StepMinDefault + s_RatioTableSizeDefault - 1)); + VRPAIR range = std::make_pair(s_StepMinDefault, static_cast<NOTEINDEXTYPE>(static_cast<NOTEINDEXTYPE>(s_StepMinDefault) + static_cast<NOTEINDEXTYPE>(s_RatioTableSizeDefault) - 1)); range.second = std::max(range.second, mpt::saturate_cast<NOTEINDEXTYPE>(ratios.size() - 1)); range.first = 0 - range.second - 1; if(pT->CreateGroupGeometric(ratios, groupratio, range, 0) != false) |