Updated libopenmpt to version 0.4.10
parent
24c130ae0b
commit
91e6511427
|
@ -1,4 +1,4 @@
|
|||
|
||||
MPT_SVNVERSION=12139
|
||||
MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.4.9
|
||||
MPT_SVNDATE=2019-10-02T14:33:59.345896Z
|
||||
MPT_SVNVERSION=12263
|
||||
MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.4.10
|
||||
MPT_SVNDATE=2019-10-30T10:43:15.521271Z
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
#pragma once
|
||||
#define OPENMPT_VERSION_SVNVERSION "12139"
|
||||
#define OPENMPT_VERSION_REVISION 12139
|
||||
#define OPENMPT_VERSION_SVNVERSION "12263"
|
||||
#define OPENMPT_VERSION_REVISION 12263
|
||||
#define OPENMPT_VERSION_DIRTY 0
|
||||
#define OPENMPT_VERSION_MIXEDREVISIONS 0
|
||||
#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.4.9"
|
||||
#define OPENMPT_VERSION_DATE "2019-10-02T14:33:59.345896Z"
|
||||
#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.4.10"
|
||||
#define OPENMPT_VERSION_DATE "2019-10-30T10:43:15.521271Z"
|
||||
#define OPENMPT_VERSION_IS_PACKAGE 1
|
||||
|
||||
|
|
|
@ -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,4 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
cd "${0%/*}"
|
||||
cd ../..
|
||||
AFL_HARDEN=1 CONFIG=afl make clean all EXAMPLES=0 TEST=0 OPENMPT123=0 NO_VORBIS=1 NO_VORBISFILE=1 USE_MINIMP3=1
|
||||
AFL_HARDEN=1 CONFIG=afl make clean all EXAMPLES=0 TEST=0 OPENMPT123=0 NO_VORBIS=1 NO_VORBISFILE=1 NO_MPG123=1
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
cd "${0%/*}"
|
||||
rm afl-latest.tgz
|
||||
wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz || exit
|
||||
tar -xzvf afl-latest.tgz
|
||||
rm afl-latest.tgz
|
||||
cd afl-*
|
||||
|
||||
AFL_VERSION="$(wget --quiet -O - "https://api.github.com/repos/google/AFL/releases/latest" | grep -Po '"tag_name": "\K.*?(?=")')"
|
||||
AFL_FILENAME="$AFL_VERSION.tar.gz"
|
||||
AFL_URL="https://github.com/google/AFL/archive/$AFL_FILENAME"
|
||||
|
||||
rm $AFL_FILENAME
|
||||
wget $AFL_URL || exit
|
||||
tar -xzvf $AFL_FILENAME
|
||||
rm $AFL_FILENAME
|
||||
cd AFL-*
|
||||
make || exit
|
||||
cd llvm_mode
|
||||
# may need to prepend LLVM_CONFIG=/usr/bin/llvm-config-3.8 or similar, depending on the system
|
||||
|
@ -13,4 +18,4 @@ cd ../libdislocator
|
|||
make || exit
|
||||
cd ../..
|
||||
rm -rf afl
|
||||
mv afl-* afl
|
||||
mv AFL-* afl
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -317,4 +317,7 @@ struct SchismVersionFromDate
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
uint32 DecodeITEditTimer(uint16 cwtv, uint32 editTime);
|
||||
|
||||
OPENMPT_NAMESPACE_END
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue