summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cowgill <jcowgill@debian.org>2019-10-30 23:08:35 +0000
committerJames Cowgill <jcowgill@debian.org>2019-10-30 23:08:35 +0000
commit580d203514359a386479a96d1e69704e429974e7 (patch)
treee4804f71fcbbd229ab4bc63c4b53027a82b0b64b
parent3f8fc5dffe02081c55aa8a9fbe4ab090dd831e67 (diff)
New upstream version 0.4.10
-rw-r--r--common/versionNumber.h4
-rwxr-xr-xconfigure26
-rw-r--r--configure.ac8
-rw-r--r--libopenmpt/dox/changelog.md17
-rw-r--r--libopenmpt/libopenmpt.hpp2
-rw-r--r--libopenmpt/libopenmpt_impl.cpp2
-rw-r--r--libopenmpt/libopenmpt_version.h2
-rw-r--r--libopenmpt/libopenmpt_version.mk4
-rw-r--r--man/openmpt123.12
-rw-r--r--soundlib/ITTools.cpp40
-rw-r--r--soundlib/ITTools.h3
-rw-r--r--soundlib/Load_it.cpp25
-rw-r--r--soundlib/Load_itp.cpp48
-rw-r--r--soundlib/Load_mtm.cpp2
-rw-r--r--soundlib/Load_psm.cpp12
-rw-r--r--soundlib/Load_s3m.cpp11
-rw-r--r--soundlib/S3MTools.h5
-rw-r--r--soundlib/Snd_fx.cpp1
-rw-r--r--soundlib/Sndfile.cpp13
-rw-r--r--soundlib/Sndfile.h16
-rw-r--r--soundlib/Tables.cpp11
-rw-r--r--soundlib/modcommand.cpp1
-rw-r--r--soundlib/plugins/LFOPlugin.h2
-rw-r--r--soundlib/tuning.h2
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)
diff --git a/configure b/configure
index 86d7b40..ed94fa3 100755
--- a/configure
+++ b/configure
@@ -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)