libOpenMPT: Updated to version 0.8.2
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
b9ced57d5f
commit
ecfbee6f53
35 changed files with 348 additions and 99 deletions
|
@ -360,6 +360,9 @@ endif
|
||||||
ifeq ($(UNAME_S),OpenBSD)
|
ifeq ($(UNAME_S),OpenBSD)
|
||||||
HOST_FLAVOUR=OPENBSD
|
HOST_FLAVOUR=OPENBSD
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(UNAME_S),DragonFly)
|
||||||
|
HOST_FLAVOUR=DRAGONFLY
|
||||||
|
endif
|
||||||
ifeq ($(UNAME_S),Haiku)
|
ifeq ($(UNAME_S),Haiku)
|
||||||
HOST_FLAVOUR=HAIKU
|
HOST_FLAVOUR=HAIKU
|
||||||
endif
|
endif
|
||||||
|
@ -408,6 +411,8 @@ TAR_C=tar -c -N
|
||||||
else
|
else
|
||||||
TAR_C=tar -c -F pax -N
|
TAR_C=tar -c -F pax -N
|
||||||
endif
|
endif
|
||||||
|
else ifeq ($(findstring DragonFly,$(UNAME_S)),DragonFly)
|
||||||
|
TAR_C=tar -c --format pax --numeric-owner --uname "" --gname "" --uid 0 --gid 0
|
||||||
else ifeq ($(findstring BSD,$(UNAME_S)),BSD)
|
else ifeq ($(findstring BSD,$(UNAME_S)),BSD)
|
||||||
TAR_C=tar -c --format pax --numeric-owner --uname "" --gname "" --uid 0 --gid 0
|
TAR_C=tar -c --format pax --numeric-owner --uname "" --gname "" --uid 0 --gid 0
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
|
|
||||||
MPT_SVNVERSION=23497
|
MPT_SVNVERSION=23826
|
||||||
MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.8.1
|
MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.8.2
|
||||||
MPT_SVNDATE=2025-06-14T13:04:39.042416Z
|
MPT_SVNDATE=2025-07-19T10:45:24.126020Z
|
||||||
|
|
|
@ -53,6 +53,13 @@ LDLIBS_PLATFORM=-lc++ -lc
|
||||||
include build/make/config-clang.mk
|
include build/make/config-clang.mk
|
||||||
MPT_COMPILER_NOALLOCAH=1
|
MPT_COMPILER_NOALLOCAH=1
|
||||||
|
|
||||||
|
else ifeq ($(HOST_FLAVOUR),DRAGONFLY)
|
||||||
|
|
||||||
|
NO_PORTAUDIOCPP?=1
|
||||||
|
NO_PULSEAUDIO?=1
|
||||||
|
include build/make/config-gcc.mk
|
||||||
|
MPT_COMPILER_NOALLOCAH=1
|
||||||
|
|
||||||
else ifeq ($(HOST_FLAVOUR),HAIKU)
|
else ifeq ($(HOST_FLAVOUR),HAIKU)
|
||||||
|
|
||||||
NO_PULSEAUDIO?=1
|
NO_PULSEAUDIO?=1
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#define OPENMPT_VERSION_SVNVERSION "23497"
|
#define OPENMPT_VERSION_SVNVERSION "23826"
|
||||||
#define OPENMPT_VERSION_REVISION 23497
|
#define OPENMPT_VERSION_REVISION 23826
|
||||||
#define OPENMPT_VERSION_DIRTY 0
|
#define OPENMPT_VERSION_DIRTY 0
|
||||||
#define OPENMPT_VERSION_MIXEDREVISIONS 0
|
#define OPENMPT_VERSION_MIXEDREVISIONS 0
|
||||||
#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.8.1"
|
#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.8.2"
|
||||||
#define OPENMPT_VERSION_DATE "2025-06-14T13:04:39.042416Z"
|
#define OPENMPT_VERSION_DATE "2025-07-19T10:45:24.126020Z"
|
||||||
#define OPENMPT_VERSION_IS_PACKAGE 1
|
#define OPENMPT_VERSION_IS_PACKAGE 1
|
||||||
|
|
||||||
|
|
|
@ -364,6 +364,7 @@
|
||||||
54F2D0191B80C78B8982EE59 /* algorithm.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = algorithm.hpp; path = ../../src/mpt/base/algorithm.hpp; sourceTree = "<group>"; };
|
54F2D0191B80C78B8982EE59 /* algorithm.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = algorithm.hpp; path = ../../src/mpt/base/algorithm.hpp; sourceTree = "<group>"; };
|
||||||
55356226EAAC215859487866 /* span.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = span.hpp; path = ../../src/mpt/audio/span.hpp; sourceTree = "<group>"; };
|
55356226EAAC215859487866 /* span.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = span.hpp; path = ../../src/mpt/audio/span.hpp; sourceTree = "<group>"; };
|
||||||
55C6E46D9A1589DFDC3CC2AD /* Dlsbank.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Dlsbank.cpp; path = ../../soundlib/Dlsbank.cpp; sourceTree = "<group>"; };
|
55C6E46D9A1589DFDC3CC2AD /* Dlsbank.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Dlsbank.cpp; path = ../../soundlib/Dlsbank.cpp; sourceTree = "<group>"; };
|
||||||
|
55E9D1C649E91B38CED43006 /* feature_fence.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = feature_fence.hpp; path = ../../src/mpt/arch/feature_fence.hpp; sourceTree = "<group>"; };
|
||||||
55EF6B83EC187D75AD7ED9C3 /* tests_endian_int24.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = tests_endian_int24.hpp; path = ../../src/mpt/endian/tests/tests_endian_int24.hpp; sourceTree = "<group>"; };
|
55EF6B83EC187D75AD7ED9C3 /* tests_endian_int24.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = tests_endian_int24.hpp; path = ../../src/mpt/endian/tests/tests_endian_int24.hpp; sourceTree = "<group>"; };
|
||||||
5609DBF3C331EA65C4C4DA33 /* utility.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = utility.hpp; path = ../../src/mpt/base/utility.hpp; sourceTree = "<group>"; };
|
5609DBF3C331EA65C4C4DA33 /* utility.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = utility.hpp; path = ../../src/mpt/base/utility.hpp; sourceTree = "<group>"; };
|
||||||
567D9E616834DE53DDA2CCA1 /* InstrumentExtensions.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = InstrumentExtensions.cpp; path = ../../soundlib/InstrumentExtensions.cpp; sourceTree = "<group>"; };
|
567D9E616834DE53DDA2CCA1 /* InstrumentExtensions.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = InstrumentExtensions.cpp; path = ../../soundlib/InstrumentExtensions.cpp; sourceTree = "<group>"; };
|
||||||
|
@ -1517,6 +1518,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
09573FAA7A79E09C30408DEA /* arch.hpp */,
|
09573FAA7A79E09C30408DEA /* arch.hpp */,
|
||||||
|
55E9D1C649E91B38CED43006 /* feature_fence.hpp */,
|
||||||
1197459E05968F108A81A3DE /* feature_flags.hpp */,
|
1197459E05968F108A81A3DE /* feature_flags.hpp */,
|
||||||
473316F00DC10E627BC33530 /* x86_amd64.hpp */,
|
473316F00DC10E627BC33530 /* x86_amd64.hpp */,
|
||||||
);
|
);
|
||||||
|
|
|
@ -364,6 +364,7 @@
|
||||||
54F2D0191B80C78B8982EE59 /* algorithm.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = algorithm.hpp; path = ../../src/mpt/base/algorithm.hpp; sourceTree = "<group>"; };
|
54F2D0191B80C78B8982EE59 /* algorithm.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = algorithm.hpp; path = ../../src/mpt/base/algorithm.hpp; sourceTree = "<group>"; };
|
||||||
55356226EAAC215859487866 /* span.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = span.hpp; path = ../../src/mpt/audio/span.hpp; sourceTree = "<group>"; };
|
55356226EAAC215859487866 /* span.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = span.hpp; path = ../../src/mpt/audio/span.hpp; sourceTree = "<group>"; };
|
||||||
55C6E46D9A1589DFDC3CC2AD /* Dlsbank.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Dlsbank.cpp; path = ../../soundlib/Dlsbank.cpp; sourceTree = "<group>"; };
|
55C6E46D9A1589DFDC3CC2AD /* Dlsbank.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Dlsbank.cpp; path = ../../soundlib/Dlsbank.cpp; sourceTree = "<group>"; };
|
||||||
|
55E9D1C649E91B38CED43006 /* feature_fence.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = feature_fence.hpp; path = ../../src/mpt/arch/feature_fence.hpp; sourceTree = "<group>"; };
|
||||||
55EF6B83EC187D75AD7ED9C3 /* tests_endian_int24.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = tests_endian_int24.hpp; path = ../../src/mpt/endian/tests/tests_endian_int24.hpp; sourceTree = "<group>"; };
|
55EF6B83EC187D75AD7ED9C3 /* tests_endian_int24.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = tests_endian_int24.hpp; path = ../../src/mpt/endian/tests/tests_endian_int24.hpp; sourceTree = "<group>"; };
|
||||||
5609DBF3C331EA65C4C4DA33 /* utility.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = utility.hpp; path = ../../src/mpt/base/utility.hpp; sourceTree = "<group>"; };
|
5609DBF3C331EA65C4C4DA33 /* utility.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = utility.hpp; path = ../../src/mpt/base/utility.hpp; sourceTree = "<group>"; };
|
||||||
567D9E616834DE53DDA2CCA1 /* InstrumentExtensions.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = InstrumentExtensions.cpp; path = ../../soundlib/InstrumentExtensions.cpp; sourceTree = "<group>"; };
|
567D9E616834DE53DDA2CCA1 /* InstrumentExtensions.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = InstrumentExtensions.cpp; path = ../../soundlib/InstrumentExtensions.cpp; sourceTree = "<group>"; };
|
||||||
|
@ -1517,6 +1518,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
09573FAA7A79E09C30408DEA /* arch.hpp */,
|
09573FAA7A79E09C30408DEA /* arch.hpp */,
|
||||||
|
55E9D1C649E91B38CED43006 /* feature_fence.hpp */,
|
||||||
1197459E05968F108A81A3DE /* feature_flags.hpp */,
|
1197459E05968F108A81A3DE /* feature_flags.hpp */,
|
||||||
473316F00DC10E627BC33530 /* x86_amd64.hpp */,
|
473316F00DC10E627BC33530 /* x86_amd64.hpp */,
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,12 +12,15 @@
|
||||||
|
|
||||||
#include "openmpt/all/BuildSettings.hpp"
|
#include "openmpt/all/BuildSettings.hpp"
|
||||||
|
|
||||||
#include "mptString.h"
|
|
||||||
#include "mpt/io/io.hpp"
|
#include "mpt/io/io.hpp"
|
||||||
#include "mpt/io/io_stdstream.hpp"
|
#include "mpt/io/io_stdstream.hpp"
|
||||||
|
|
||||||
|
#include "mptString.h"
|
||||||
|
|
||||||
#ifdef MPT_WITH_ZLIB
|
#ifdef MPT_WITH_ZLIB
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
OPENMPT_NAMESPACE_BEGIN
|
OPENMPT_NAMESPACE_BEGIN
|
||||||
|
@ -25,15 +28,31 @@ OPENMPT_NAMESPACE_BEGIN
|
||||||
inline void WriteGzip(std::ostream &output, std::string &outData, const mpt::ustring &fileName)
|
inline void WriteGzip(std::ostream &output, std::string &outData, const mpt::ustring &fileName)
|
||||||
{
|
{
|
||||||
z_stream strm{};
|
z_stream strm{};
|
||||||
|
int zlib_errc = Z_OK;
|
||||||
strm.avail_in = static_cast<uInt>(outData.size());
|
strm.avail_in = static_cast<uInt>(outData.size());
|
||||||
strm.next_in = reinterpret_cast<Bytef *>(outData.data());
|
strm.next_in = reinterpret_cast<Bytef *>(outData.data());
|
||||||
if(deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, 15 | 16, 9, Z_DEFAULT_STRATEGY) != Z_OK)
|
zlib_errc = deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, 15 | 16, 9, Z_DEFAULT_STRATEGY);
|
||||||
throw std::runtime_error{"zlib init failed"};
|
if(zlib_errc == Z_MEM_ERROR)
|
||||||
|
{
|
||||||
|
mpt::throw_out_of_memory();
|
||||||
|
} else if(zlib_errc < Z_OK)
|
||||||
|
{
|
||||||
|
throw std::runtime_error{"zlib: deflateInit2() failed"};
|
||||||
|
}
|
||||||
gz_header gzHeader{};
|
gz_header gzHeader{};
|
||||||
gzHeader.time = static_cast<uLong>(time(nullptr));
|
gzHeader.time = static_cast<uLong>(std::time(nullptr));
|
||||||
std::string filenameISO = mpt::ToCharset(mpt::Charset::ISO8859_1, fileName);
|
std::string filenameISO = mpt::ToCharset(mpt::Charset::ISO8859_1, fileName);
|
||||||
gzHeader.name = reinterpret_cast<Bytef *>(filenameISO.data());
|
gzHeader.name = reinterpret_cast<Bytef *>(filenameISO.data());
|
||||||
deflateSetHeader(&strm, &gzHeader);
|
zlib_errc = deflateSetHeader(&strm, &gzHeader);
|
||||||
|
if(zlib_errc == Z_MEM_ERROR)
|
||||||
|
{
|
||||||
|
deflateEnd(&strm);
|
||||||
|
mpt::throw_out_of_memory();
|
||||||
|
} else if(zlib_errc < Z_OK)
|
||||||
|
{
|
||||||
|
deflateEnd(&strm);
|
||||||
|
throw std::runtime_error{"zlib: deflateSetHeader() failed"};
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
|
@ -41,15 +60,33 @@ inline void WriteGzip(std::ostream &output, std::string &outData, const mpt::ust
|
||||||
std::array<Bytef, mpt::IO::BUFFERSIZE_TINY> buffer;
|
std::array<Bytef, mpt::IO::BUFFERSIZE_TINY> buffer;
|
||||||
strm.avail_out = static_cast<uInt>(buffer.size());
|
strm.avail_out = static_cast<uInt>(buffer.size());
|
||||||
strm.next_out = buffer.data();
|
strm.next_out = buffer.data();
|
||||||
deflate(&strm, Z_FINISH);
|
zlib_errc = deflate(&strm, Z_FINISH);
|
||||||
|
if(zlib_errc == Z_BUF_ERROR)
|
||||||
|
{
|
||||||
|
// expected
|
||||||
|
} else if(zlib_errc == Z_MEM_ERROR)
|
||||||
|
{
|
||||||
|
mpt::throw_out_of_memory();
|
||||||
|
} else if(zlib_errc < Z_OK)
|
||||||
|
{
|
||||||
|
throw std::runtime_error{"zlib: deflate() failed"};
|
||||||
|
}
|
||||||
mpt::IO::WritePartial(output, buffer, buffer.size() - strm.avail_out);
|
mpt::IO::WritePartial(output, buffer, buffer.size() - strm.avail_out);
|
||||||
} while(strm.avail_out == 0);
|
} while(strm.avail_out == 0);
|
||||||
|
} catch(mpt::out_of_memory e)
|
||||||
|
{
|
||||||
deflateEnd(&strm);
|
deflateEnd(&strm);
|
||||||
|
mpt::rethrow_out_of_memory(e);
|
||||||
} catch(const std::exception &)
|
} catch(const std::exception &)
|
||||||
|
{
|
||||||
|
deflateEnd(&strm);
|
||||||
|
throw;
|
||||||
|
} catch(...)
|
||||||
{
|
{
|
||||||
deflateEnd(&strm);
|
deflateEnd(&strm);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
deflateEnd(&strm);
|
||||||
}
|
}
|
||||||
|
|
||||||
OPENMPT_NAMESPACE_END
|
OPENMPT_NAMESPACE_END
|
||||||
|
|
|
@ -42,7 +42,7 @@ OPENMPT_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
|
||||||
#ifdef SSB_LOGGING
|
#ifdef SSB_LOGGING
|
||||||
#define SSB_LOG(x) MPT_LOG_GLOBAL(LogDebug, "serialization", x)
|
#define SSB_LOG(x) MPT_LOG_GLOBAL(LogDebug, "serialization", (x))
|
||||||
#else
|
#else
|
||||||
#define SSB_LOG(x) do { } while(0)
|
#define SSB_LOG(x) do { } while(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,5 +15,5 @@
|
||||||
// Version definitions. The only thing that needs to be changed when changing version number.
|
// Version definitions. The only thing that needs to be changed when changing version number.
|
||||||
#define VER_MAJORMAJOR 1
|
#define VER_MAJORMAJOR 1
|
||||||
#define VER_MAJOR 32
|
#define VER_MAJOR 32
|
||||||
#define VER_MINOR 01
|
#define VER_MINOR 03
|
||||||
#define VER_MINORMINOR 04
|
#define VER_MINORMINOR 00
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
/*! \brief libopenmpt minor version number */
|
/*! \brief libopenmpt minor version number */
|
||||||
#define OPENMPT_API_VERSION_MINOR 8
|
#define OPENMPT_API_VERSION_MINOR 8
|
||||||
/*! \brief libopenmpt patch version number */
|
/*! \brief libopenmpt patch version number */
|
||||||
#define OPENMPT_API_VERSION_PATCH 1
|
#define OPENMPT_API_VERSION_PATCH 2
|
||||||
/*! \brief libopenmpt pre-release tag */
|
/*! \brief libopenmpt pre-release tag */
|
||||||
#define OPENMPT_API_VERSION_PREREL ""
|
#define OPENMPT_API_VERSION_PREREL ""
|
||||||
/*! \brief libopenmpt pre-release flag */
|
/*! \brief libopenmpt pre-release flag */
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
LIBOPENMPT_VERSION_MAJOR=0
|
LIBOPENMPT_VERSION_MAJOR=0
|
||||||
LIBOPENMPT_VERSION_MINOR=8
|
LIBOPENMPT_VERSION_MINOR=8
|
||||||
LIBOPENMPT_VERSION_PATCH=1
|
LIBOPENMPT_VERSION_PATCH=2
|
||||||
LIBOPENMPT_VERSION_PREREL=
|
LIBOPENMPT_VERSION_PREREL=
|
||||||
|
|
||||||
LIBOPENMPT_LTVER_CURRENT=5
|
LIBOPENMPT_LTVER_CURRENT=5
|
||||||
LIBOPENMPT_LTVER_REVISION=1
|
LIBOPENMPT_LTVER_REVISION=2
|
||||||
LIBOPENMPT_LTVER_AGE=5
|
LIBOPENMPT_LTVER_AGE=5
|
||||||
|
|
|
@ -38,6 +38,25 @@ static const char * const license =
|
||||||
#include "openmpt123_config.hpp"
|
#include "openmpt123_config.hpp"
|
||||||
|
|
||||||
#include "mpt/base/detect_compiler.hpp"
|
#include "mpt/base/detect_compiler.hpp"
|
||||||
|
|
||||||
|
#if MPT_COMPILER_GCC
|
||||||
|
|
||||||
|
#ifdef MPT_COMPILER_SETTING_QUIRK_GCC_BROKEN_IPA
|
||||||
|
// See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115049>.
|
||||||
|
#if MPT_GCC_BEFORE(9, 0, 0)
|
||||||
|
// Earlier GCC get confused about setting a global function attribute.
|
||||||
|
// We need to check for 9.0 instead of 9.1 because of
|
||||||
|
// <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1028580>.
|
||||||
|
// It also gets confused when setting global optimization -O1,
|
||||||
|
// so we have no way of fixing GCC 8 or earlier.
|
||||||
|
//#pragma GCC optimize("O1")
|
||||||
|
#else
|
||||||
|
#pragma GCC optimize("no-ipa-ra")
|
||||||
|
#endif
|
||||||
|
#endif // MPT_COMPILER_SETTING_QUIRK_GCC_BROKEN_IPA
|
||||||
|
|
||||||
|
#endif // MPT_COMPILER_GCC
|
||||||
|
|
||||||
#include "mpt/base/detect_os.hpp"
|
#include "mpt/base/detect_os.hpp"
|
||||||
#include "mpt/base/detect_quirks.hpp"
|
#include "mpt/base/detect_quirks.hpp"
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "mpt/base/saturate_round.hpp"
|
#include "mpt/base/saturate_round.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#if MPT_PLATFORM_MULTITHREADED && !defined(MPT_COMPILER_QUIRK_NO_STDCPP_THREADS)
|
#if MPT_PLATFORM_MULTITHREADED && !defined(MPT_LIBCXX_QUIRK_NO_STD_THREAD)
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ public:
|
||||||
FLAC__stream_encoder_set_bits_per_sample( encoder, flags.use_float ? 24 : 16 );
|
FLAC__stream_encoder_set_bits_per_sample( encoder, flags.use_float ? 24 : 16 );
|
||||||
FLAC__stream_encoder_set_sample_rate( encoder, flags.samplerate );
|
FLAC__stream_encoder_set_sample_rate( encoder, flags.samplerate );
|
||||||
FLAC__stream_encoder_set_compression_level( encoder, 8 );
|
FLAC__stream_encoder_set_compression_level( encoder, 8 );
|
||||||
#if (FLAC_API_VERSION_CURRENT >= 14) && MPT_PLATFORM_MULTITHREADED && !defined(MPT_COMPILER_QUIRK_NO_STDCPP_THREADS)
|
#if (FLAC_API_VERSION_CURRENT >= 14) && MPT_PLATFORM_MULTITHREADED && !defined(MPT_LIBCXX_QUIRK_NO_STD_THREAD)
|
||||||
std::uint32_t threads = static_cast<std::uint32_t>(std::max(std::thread::hardware_concurrency(), static_cast<unsigned int>(1)));
|
std::uint32_t threads = static_cast<std::uint32_t>(std::max(std::thread::hardware_concurrency(), static_cast<unsigned int>(1)));
|
||||||
// Work-around <https://github.com/xiph/flac/issues/823>.
|
// Work-around <https://github.com/xiph/flac/issues/823>.
|
||||||
//FLAC__stream_encoder_set_num_threads( encoder, threads );
|
//FLAC__stream_encoder_set_num_threads( encoder, threads );
|
||||||
|
|
|
@ -90,7 +90,7 @@ public:
|
||||||
switch (new_mode) {
|
switch (new_mode) {
|
||||||
case FILE_mode::text:
|
case FILE_mode::text:
|
||||||
fflush( file );
|
fflush( file );
|
||||||
#if defined(UNICODE)
|
#if defined(UNICODE) && MPT_LIBC_MS_AT_LEAST(MPT_LIBC_MS_VER_UCRT)
|
||||||
old_mode = _setmode( _fileno( file ), _O_U8TEXT );
|
old_mode = _setmode( _fileno( file ), _O_U8TEXT );
|
||||||
#else
|
#else
|
||||||
old_mode = _setmode( _fileno( file ), _O_TEXT );
|
old_mode = _setmode( _fileno( file ), _O_TEXT );
|
||||||
|
|
|
@ -102,6 +102,7 @@ void CEQ::ProcessTemplate(TMixSample *frontBuffer, TMixSample *rearBuffer, std::
|
||||||
unsigned int old_csr = 0;
|
unsigned int old_csr = 0;
|
||||||
if(CPU::HasFeatureSet(CPU::feature::sse) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
if(CPU::HasFeatureSet(CPU::feature::sse) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
||||||
{
|
{
|
||||||
|
mpt::arch::feature_fence_aquire();
|
||||||
old_csr = _mm_getcsr();
|
old_csr = _mm_getcsr();
|
||||||
_mm_setcsr((old_csr & ~(_MM_DENORMALS_ZERO_MASK | _MM_FLUSH_ZERO_MASK)) | _MM_DENORMALS_ZERO_ON | _MM_FLUSH_ZERO_ON);
|
_mm_setcsr((old_csr & ~(_MM_DENORMALS_ZERO_MASK | _MM_FLUSH_ZERO_MASK)) | _MM_DENORMALS_ZERO_ON | _MM_FLUSH_ZERO_ON);
|
||||||
}
|
}
|
||||||
|
@ -124,6 +125,7 @@ void CEQ::ProcessTemplate(TMixSample *frontBuffer, TMixSample *rearBuffer, std::
|
||||||
if(CPU::HasFeatureSet(CPU::feature::sse) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
if(CPU::HasFeatureSet(CPU::feature::sse) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
||||||
{
|
{
|
||||||
_mm_setcsr(old_csr);
|
_mm_setcsr(old_csr);
|
||||||
|
mpt::arch::feature_fence_release();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ const REFLECTIONPRESET gReflectionsPreset[ENVIRONMENT_NUMREFLECTIONS] =
|
||||||
// Implementation
|
// Implementation
|
||||||
//
|
//
|
||||||
|
|
||||||
MPT_FORCEINLINE int32 ftol(float f) { return static_cast<int32>(f); }
|
static MPT_FORCEINLINE int32 ftol(float f) { return static_cast<int32>(f); }
|
||||||
|
|
||||||
static void I3dl2_to_Generic(
|
static void I3dl2_to_Generic(
|
||||||
const SNDMIX_REVERB_PROPERTIES *pReverb,
|
const SNDMIX_REVERB_PROPERTIES *pReverb,
|
||||||
|
@ -597,6 +597,7 @@ void CReverb::ReverbProcessPostFiltering1x(const int32 * MPT_RESTRICT pRvb, int3
|
||||||
#if defined(MPT_WANT_ARCH_INTRINSICS_X86_SSE2) && defined(MPT_ARCH_INTRINSICS_X86_SSE2)
|
#if defined(MPT_WANT_ARCH_INTRINSICS_X86_SSE2) && defined(MPT_ARCH_INTRINSICS_X86_SSE2)
|
||||||
if(CPU::HasFeatureSet(CPU::feature::sse2) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
if(CPU::HasFeatureSet(CPU::feature::sse2) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
||||||
{
|
{
|
||||||
|
mpt::arch::feature_fence_guard arch_feature_guard;
|
||||||
__m128i nDCRRvb_Y1 = Load64SSE(gnDCRRvb_Y1);
|
__m128i nDCRRvb_Y1 = Load64SSE(gnDCRRvb_Y1);
|
||||||
__m128i nDCRRvb_X1 = Load64SSE(gnDCRRvb_X1);
|
__m128i nDCRRvb_X1 = Load64SSE(gnDCRRvb_X1);
|
||||||
__m128i in = _mm_set1_epi32(0);
|
__m128i in = _mm_set1_epi32(0);
|
||||||
|
@ -659,6 +660,7 @@ void CReverb::ReverbDCRemoval(int32 * MPT_RESTRICT pBuffer, uint32 nSamples)
|
||||||
#if defined(MPT_WANT_ARCH_INTRINSICS_X86_SSE2) && defined(MPT_ARCH_INTRINSICS_X86_SSE2)
|
#if defined(MPT_WANT_ARCH_INTRINSICS_X86_SSE2) && defined(MPT_ARCH_INTRINSICS_X86_SSE2)
|
||||||
if(CPU::HasFeatureSet(CPU::feature::sse2) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
if(CPU::HasFeatureSet(CPU::feature::sse2) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
||||||
{
|
{
|
||||||
|
mpt::arch::feature_fence_guard arch_feature_guard;
|
||||||
__m128i nDCRRvb_Y1 = Load64SSE(gnDCRRvb_Y1);
|
__m128i nDCRRvb_Y1 = Load64SSE(gnDCRRvb_Y1);
|
||||||
__m128i nDCRRvb_X1 = Load64SSE(gnDCRRvb_X1);
|
__m128i nDCRRvb_X1 = Load64SSE(gnDCRRvb_X1);
|
||||||
while(nSamples--)
|
while(nSamples--)
|
||||||
|
@ -724,6 +726,7 @@ void CReverb::ProcessPreDelay(SWRvbRefDelay * MPT_RESTRICT pPreDelay, const int3
|
||||||
#if defined(MPT_WANT_ARCH_INTRINSICS_X86_SSE2) && defined(MPT_ARCH_INTRINSICS_X86_SSE2)
|
#if defined(MPT_WANT_ARCH_INTRINSICS_X86_SSE2) && defined(MPT_ARCH_INTRINSICS_X86_SSE2)
|
||||||
if(CPU::HasFeatureSet(CPU::feature::sse2) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
if(CPU::HasFeatureSet(CPU::feature::sse2) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
||||||
{
|
{
|
||||||
|
mpt::arch::feature_fence_guard arch_feature_guard;
|
||||||
__m128i coeffs = _mm_cvtsi32_si128(pPreDelay->nCoeffs.lr);
|
__m128i coeffs = _mm_cvtsi32_si128(pPreDelay->nCoeffs.lr);
|
||||||
__m128i history = _mm_cvtsi32_si128(pPreDelay->History.lr);
|
__m128i history = _mm_cvtsi32_si128(pPreDelay->History.lr);
|
||||||
__m128i preDifCoeffs = _mm_cvtsi32_si128(pPreDelay->nPreDifCoeffs.lr);
|
__m128i preDifCoeffs = _mm_cvtsi32_si128(pPreDelay->nPreDifCoeffs.lr);
|
||||||
|
@ -796,6 +799,7 @@ void CReverb::ProcessReflections(SWRvbRefDelay * MPT_RESTRICT pPreDelay, LR16 *
|
||||||
#if defined(MPT_WANT_ARCH_INTRINSICS_X86_SSE2) && defined(MPT_ARCH_INTRINSICS_X86_SSE2)
|
#if defined(MPT_WANT_ARCH_INTRINSICS_X86_SSE2) && defined(MPT_ARCH_INTRINSICS_X86_SSE2)
|
||||||
if(CPU::HasFeatureSet(CPU::feature::sse2) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
if(CPU::HasFeatureSet(CPU::feature::sse2) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
||||||
{
|
{
|
||||||
|
mpt::arch::feature_fence_guard arch_feature_guard;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
__m128i xmm;
|
__m128i xmm;
|
||||||
|
@ -891,6 +895,7 @@ void CReverb::ProcessLateReverb(SWLateReverb * MPT_RESTRICT pReverb, LR16 * MPT_
|
||||||
#if defined(MPT_WANT_ARCH_INTRINSICS_X86_SSE2) && defined(MPT_ARCH_INTRINSICS_X86_SSE2)
|
#if defined(MPT_WANT_ARCH_INTRINSICS_X86_SSE2) && defined(MPT_ARCH_INTRINSICS_X86_SSE2)
|
||||||
if(CPU::HasFeatureSet(CPU::feature::sse2) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
if(CPU::HasFeatureSet(CPU::feature::sse2) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
||||||
{
|
{
|
||||||
|
mpt::arch::feature_fence_guard arch_feature_guard;
|
||||||
int delayPos = pReverb->nDelayPos & RVBDLY_MASK;
|
int delayPos = pReverb->nDelayPos & RVBDLY_MASK;
|
||||||
__m128i rvbOutGains = Load64SSE(pReverb->RvbOutGains);
|
__m128i rvbOutGains = Load64SSE(pReverb->RvbOutGains);
|
||||||
__m128i difCoeffs = Load64SSE(pReverb->nDifCoeffs);
|
__m128i difCoeffs = Load64SSE(pReverb->nDifCoeffs);
|
||||||
|
|
|
@ -97,7 +97,7 @@ struct MixLoopState
|
||||||
// Check how many samples can be rendered without encountering loop or sample end, and also update loop position / direction
|
// Check how many samples can be rendered without encountering loop or sample end, and also update loop position / direction
|
||||||
MPT_FORCEINLINE uint32 GetSampleCount(ModChannel &chn, uint32 nSamples) const
|
MPT_FORCEINLINE uint32 GetSampleCount(ModChannel &chn, uint32 nSamples) const
|
||||||
{
|
{
|
||||||
int32 nLoopStart = chn.dwFlags[CHN_LOOP] ? chn.nLoopStart : 0;
|
const int32 nLoopStart = chn.dwFlags[CHN_LOOP] ? chn.nLoopStart : 0;
|
||||||
SamplePosition nInc = chn.increment;
|
SamplePosition nInc = chn.increment;
|
||||||
|
|
||||||
if(nSamples <= 0 || nInc.IsZero() || !chn.nLength || !samplePointer)
|
if(nSamples <= 0 || nInc.IsZero() || !chn.nLength || !samplePointer)
|
||||||
|
@ -227,35 +227,24 @@ struct MixLoopState
|
||||||
{
|
{
|
||||||
if(nPosInt >= lookaheadStart)
|
if(nPosInt >= lookaheadStart)
|
||||||
{
|
{
|
||||||
#if 0
|
if(nInc.IsNegative())
|
||||||
const uint32 oldCount = nSmpCount;
|
|
||||||
|
|
||||||
// When going backwards - we can only go back up to lookaheadStart.
|
|
||||||
// When going forwards - read through the whole pre-computed wrap-around buffer if possible.
|
|
||||||
// TODO: ProTracker sample swapping needs hard cut at sample end.
|
|
||||||
int32 samplesToRead = nInc.IsNegative()
|
|
||||||
? (nPosInt - lookaheadStart)
|
|
||||||
//: 2 * InterpolationMaxLookahead - (nPosInt - mixLoopState.lookaheadStart);
|
|
||||||
: (chn.nLoopEnd - nPosInt);
|
|
||||||
//LimitMax(samplesToRead, chn.nLoopEnd - chn.nLoopStart);
|
|
||||||
nSmpCount = SamplesToBufferLength(samplesToRead, chn);
|
|
||||||
Limit(nSmpCount, 1u, oldCount);
|
|
||||||
#else
|
|
||||||
if (nInc.IsNegative())
|
|
||||||
{
|
{
|
||||||
nSmpCount = DistanceToBufferLength(SamplePosition(lookaheadStart, 0), nPos, nInv);
|
nSmpCount = DistanceToBufferLength(SamplePosition(lookaheadStart, 0), nPos, nInv);
|
||||||
} else
|
chn.pCurrentSample = lookaheadPointer;
|
||||||
|
} else if(nPosInt <= chn.nLoopEnd)
|
||||||
{
|
{
|
||||||
nSmpCount = DistanceToBufferLength(nPos, SamplePosition(chn.nLoopEnd, 0), nInv);
|
nSmpCount = DistanceToBufferLength(nPos, SamplePosition(chn.nLoopEnd, 0), nInv);
|
||||||
}
|
|
||||||
#endif
|
|
||||||
chn.pCurrentSample = lookaheadPointer;
|
chn.pCurrentSample = lookaheadPointer;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
nSmpCount = DistanceToBufferLength(nPos, SamplePosition(chn.nLength, 0), nInv);
|
||||||
|
}
|
||||||
checkDest = false;
|
checkDest = false;
|
||||||
} else if(chn.dwFlags[CHN_WRAPPED_LOOP] && isAtLoopStart)
|
} else if(chn.dwFlags[CHN_WRAPPED_LOOP] && isAtLoopStart)
|
||||||
{
|
{
|
||||||
// We just restarted the loop, so interpolate correctly after wrapping around
|
// We just restarted the loop, so interpolate correctly after wrapping around
|
||||||
nSmpCount = DistanceToBufferLength(nPos, SamplePosition(nLoopStart + InterpolationLookaheadBufferSize, 0), nInv);
|
nSmpCount = DistanceToBufferLength(nPos, SamplePosition(nLoopStart + InterpolationLookaheadBufferSize, 0), nInv);
|
||||||
chn.pCurrentSample = lookaheadPointer + (chn.nLoopEnd - nLoopStart) * chn.pModSample->GetBytesPerSample();
|
chn.pCurrentSample = lookaheadPointer + (chn.nLength - nLoopStart) * chn.pModSample->GetBytesPerSample();
|
||||||
checkDest = false;
|
checkDest = false;
|
||||||
} else if(nInc.IsPositive() && static_cast<SmpLength>(nPosDest) >= lookaheadStart && nSmpCount > 1)
|
} else if(nInc.IsPositive() && static_cast<SmpLength>(nPosDest) >= lookaheadStart && nSmpCount > 1)
|
||||||
{
|
{
|
||||||
|
@ -325,12 +314,45 @@ void CSoundFile::CreateStereoMix(int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::pair<mixsample_t *, mixsample_t *> CSoundFile::GetChannelOffsets(const ModChannel &chn, CHANNELINDEX channel)
|
||||||
|
{
|
||||||
|
mixsample_t *pOfsR = &m_dryROfsVol;
|
||||||
|
mixsample_t *pOfsL = &m_dryLOfsVol;
|
||||||
|
#ifndef NO_REVERB
|
||||||
|
if(((m_MixerSettings.DSPMask & SNDDSP_REVERB) && !chn.dwFlags[CHN_NOREVERB]) || chn.dwFlags[CHN_REVERB])
|
||||||
|
{
|
||||||
|
pOfsR = &m_RvbROfsVol;
|
||||||
|
pOfsL = &m_RvbLOfsVol;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(chn.dwFlags[CHN_SURROUND] && m_MixerSettings.gnChannels > 2)
|
||||||
|
{
|
||||||
|
pOfsR = &m_surroundROfsVol;
|
||||||
|
pOfsL = &m_surroundLOfsVol;
|
||||||
|
}
|
||||||
|
// Look for plugins associated with this implicit tracker channel.
|
||||||
|
#ifndef NO_PLUGINS
|
||||||
|
const PLUGINDEX mixPlugin = GetBestPlugin(chn, channel, PrioritiseInstrument, RespectMutes);
|
||||||
|
if((mixPlugin > 0) && (mixPlugin <= MAX_MIXPLUGINS) && m_MixPlugins[mixPlugin - 1].pMixPlugin != nullptr)
|
||||||
|
{
|
||||||
|
// Render into plugin buffer instead of global buffer
|
||||||
|
SNDMIXPLUGINSTATE &mixState = m_MixPlugins[mixPlugin - 1].pMixPlugin->m_MixState;
|
||||||
|
if(mixState.pMixBuffer)
|
||||||
|
{
|
||||||
|
pOfsR = &mixState.nVolDecayR;
|
||||||
|
pOfsL = &mixState.nVolDecayL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // NO_PLUGINS
|
||||||
|
return std::make_pair(pOfsL, pOfsR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CSoundFile::MixChannel(int count, ModChannel &chn, CHANNELINDEX channel, bool doMix)
|
bool CSoundFile::MixChannel(int count, ModChannel &chn, CHANNELINDEX channel, bool doMix)
|
||||||
{
|
{
|
||||||
if(chn.pCurrentSample || chn.nLOfs || chn.nROfs)
|
if(chn.pCurrentSample || chn.nLOfs || chn.nROfs)
|
||||||
{
|
{
|
||||||
mixsample_t *pOfsR = &m_dryROfsVol;
|
auto [pOfsL, pOfsR] = GetChannelOffsets(chn, channel);
|
||||||
mixsample_t *pOfsL = &m_dryLOfsVol;
|
|
||||||
|
|
||||||
uint32 functionNdx = MixFuncTable::ResamplingModeToMixFlags(static_cast<ResamplingMode>(chn.resamplingMode));
|
uint32 functionNdx = MixFuncTable::ResamplingModeToMixFlags(static_cast<ResamplingMode>(chn.resamplingMode));
|
||||||
if(chn.dwFlags[CHN_16BIT]) functionNdx |= MixFuncTable::ndx16Bit;
|
if(chn.dwFlags[CHN_16BIT]) functionNdx |= MixFuncTable::ndx16Bit;
|
||||||
|
@ -345,15 +367,11 @@ bool CSoundFile::MixChannel(int count, ModChannel &chn, CHANNELINDEX channel, bo
|
||||||
{
|
{
|
||||||
m_Reverb.TouchReverbSendBuffer(ReverbSendBuffer, m_RvbROfsVol, m_RvbLOfsVol, count);
|
m_Reverb.TouchReverbSendBuffer(ReverbSendBuffer, m_RvbROfsVol, m_RvbLOfsVol, count);
|
||||||
pbuffer = ReverbSendBuffer;
|
pbuffer = ReverbSendBuffer;
|
||||||
pOfsR = &m_RvbROfsVol;
|
|
||||||
pOfsL = &m_RvbLOfsVol;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(chn.dwFlags[CHN_SURROUND] && m_MixerSettings.gnChannels > 2)
|
if(chn.dwFlags[CHN_SURROUND] && m_MixerSettings.gnChannels > 2)
|
||||||
{
|
{
|
||||||
pbuffer = MixRearBuffer;
|
pbuffer = MixRearBuffer;
|
||||||
pOfsR = &m_surroundROfsVol;
|
|
||||||
pOfsL = &m_surroundLOfsVol;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for plugins associated with this implicit tracker channel.
|
// Look for plugins associated with this implicit tracker channel.
|
||||||
|
@ -366,8 +384,6 @@ bool CSoundFile::MixChannel(int count, ModChannel &chn, CHANNELINDEX channel, bo
|
||||||
if (mixState.pMixBuffer)
|
if (mixState.pMixBuffer)
|
||||||
{
|
{
|
||||||
pbuffer = mixState.pMixBuffer;
|
pbuffer = mixState.pMixBuffer;
|
||||||
pOfsR = &mixState.nVolDecayR;
|
|
||||||
pOfsL = &mixState.nVolDecayL;
|
|
||||||
if (!(mixState.dwFlags & SNDMIXPLUGINSTATE::psfMixReady))
|
if (!(mixState.dwFlags & SNDMIXPLUGINSTATE::psfMixReady))
|
||||||
{
|
{
|
||||||
StereoFill(pbuffer, count, *pOfsR, *pOfsL);
|
StereoFill(pbuffer, count, *pOfsR, *pOfsL);
|
||||||
|
|
|
@ -83,8 +83,9 @@ struct FCFileHeader
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
static constexpr uint32 MAX_FC_SIZE = 0x8'0000; // According to manual: Sample memory allocated = 100,000 bytes
|
static constexpr uint32 MAX_FC_SIZE = 0x8'0000; // According to manual: Sample memory allocated = 100,000 bytes
|
||||||
if(sequenceSize % sizeof(FCPlaylistEntry) > 1 // Some files have a mysterious extra byte
|
const uint32 seqSize = SequenceSize();
|
||||||
|| sequenceSize < sizeof(FCPlaylistEntry) || sequenceSize > 256 * 13
|
if(seqSize % sizeof(FCPlaylistEntry) > 1 // Some files have a mysterious extra byte
|
||||||
|
|| seqSize < sizeof(FCPlaylistEntry) || seqSize > 256 * 13
|
||||||
|| patternsSize % 64u || !patternsSize || patternsSize > 64 * 256 || patternsOffset > MAX_FC_SIZE
|
|| patternsSize % 64u || !patternsSize || patternsSize > 64 * 256 || patternsOffset > MAX_FC_SIZE
|
||||||
|| freqSequenceSize % 64u || !freqSequenceSize || freqSequenceSize > 64 * 256 || freqSequenceOffset > MAX_FC_SIZE
|
|| freqSequenceSize % 64u || !freqSequenceSize || freqSequenceSize > 64 * 256 || freqSequenceOffset > MAX_FC_SIZE
|
||||||
|| volSequenceSize % 64u || !volSequenceSize || volSequenceSize > 64 * 256 || volSequenceOffset > MAX_FC_SIZE
|
|| volSequenceSize % 64u || !volSequenceSize || volSequenceSize > 64 * 256 || volSequenceOffset > MAX_FC_SIZE
|
||||||
|
@ -102,12 +103,22 @@ struct FCFileHeader
|
||||||
|
|
||||||
ORDERINDEX NumOrders() const
|
ORDERINDEX NumOrders() const
|
||||||
{
|
{
|
||||||
return static_cast<ORDERINDEX>(sequenceSize / sizeof(FCPlaylistEntry));
|
return static_cast<ORDERINDEX>(SequenceSize() / sizeof(FCPlaylistEntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetHeaderMinimumAdditionalSize() const
|
uint32 GetHeaderMinimumAdditionalSize() const
|
||||||
{
|
{
|
||||||
return sequenceSize + (IsFC14() ? 80 : 0);
|
return SequenceSize() + (IsFC14() ? 80 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 SequenceSize() const
|
||||||
|
{
|
||||||
|
// A broken copy of cult.smod has a sequence size of 0 but the sequence data is actually in the place where it's supposed to be
|
||||||
|
if(sequenceSize > 0)
|
||||||
|
return sequenceSize;
|
||||||
|
if(const uint32 headerSize = IsFC14() ? 180 : 100; patternsOffset > headerSize)
|
||||||
|
return patternsOffset - headerSize;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -357,8 +357,8 @@ std::string MIDIMacroConfig::Macro::NormalizedString() const
|
||||||
{
|
{
|
||||||
std::string sanitizedMacro = *this;
|
std::string sanitizedMacro = *this;
|
||||||
|
|
||||||
std::string::size_type pos;
|
std::string::size_type pos = 0;
|
||||||
while((pos = sanitizedMacro.find_first_not_of("0123456789ABCDEFabchmnopsuvxyz")) != std::string::npos)
|
while((pos = sanitizedMacro.find_first_not_of("0123456789ABCDEFabchmnopsuvxyz", pos)) != std::string::npos)
|
||||||
{
|
{
|
||||||
sanitizedMacro.erase(pos, 1);
|
sanitizedMacro.erase(pos, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ OPENMPT_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
|
||||||
ModSequence::ModSequence(CSoundFile &sndFile)
|
ModSequence::ModSequence(CSoundFile &sndFile)
|
||||||
: m_sndFile(sndFile)
|
: m_sndFile{sndFile}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@ ModSequence& ModSequence::operator=(const ModSequence &other)
|
||||||
std::vector<PATTERNINDEX>::assign(other.begin(), other.end());
|
std::vector<PATTERNINDEX>::assign(other.begin(), other.end());
|
||||||
m_name = other.m_name;
|
m_name = other.m_name;
|
||||||
m_restartPos = other.m_restartPos;
|
m_restartPos = other.m_restartPos;
|
||||||
|
m_defaultTempo = other.m_defaultTempo;
|
||||||
|
m_defaultSpeed = other.m_defaultSpeed;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +43,9 @@ bool ModSequence::operator== (const ModSequence &other) const noexcept
|
||||||
{
|
{
|
||||||
return static_cast<const std::vector<PATTERNINDEX> &>(*this) == other
|
return static_cast<const std::vector<PATTERNINDEX> &>(*this) == other
|
||||||
&& m_name == other.m_name
|
&& m_name == other.m_name
|
||||||
&& m_restartPos == other.m_restartPos;
|
&& m_restartPos == other.m_restartPos
|
||||||
|
&& m_defaultTempo == other.m_defaultTempo
|
||||||
|
&& m_defaultSpeed == other.m_defaultSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,11 @@
|
||||||
//#include "mpt/crc/crc.hpp"
|
//#include "mpt/crc/crc.hpp"
|
||||||
#include "OggStream.h"
|
#include "OggStream.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#if MPT_PLATFORM_MULTITHREADED && !defined(MPT_COMPILER_QUIRK_NO_STDCPP_THREADS)
|
#ifdef MPT_WITH_FLAC
|
||||||
|
#if MPT_PLATFORM_MULTITHREADED && !defined(MPT_LIBCXX_QUIRK_NO_STD_THREAD)
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#ifdef MPT_WITH_OGG
|
#ifdef MPT_WITH_OGG
|
||||||
#if MPT_COMPILER_CLANG
|
#if MPT_COMPILER_CLANG
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
|
@ -698,7 +700,7 @@ bool CSoundFile::SaveFLACSample(SAMPLEINDEX nSample, std::ostream &f) const
|
||||||
FLAC__stream_encoder_set_metadata(encoder, metadata.data(), numBlocks);
|
FLAC__stream_encoder_set_metadata(encoder, metadata.data(), numBlocks);
|
||||||
#ifdef MODPLUG_TRACKER
|
#ifdef MODPLUG_TRACKER
|
||||||
FLAC__stream_encoder_set_compression_level(encoder, TrackerSettings::Instance().m_FLACCompressionLevel);
|
FLAC__stream_encoder_set_compression_level(encoder, TrackerSettings::Instance().m_FLACCompressionLevel);
|
||||||
#if (FLAC_API_VERSION_CURRENT >= 14) && MPT_PLATFORM_MULTITHREADED && !defined(MPT_COMPILER_QUIRK_NO_STDCPP_THREADS)
|
#if (FLAC_API_VERSION_CURRENT >= 14) && MPT_PLATFORM_MULTITHREADED && !defined(MPT_LIBCXX_QUIRK_NO_STD_THREAD)
|
||||||
uint32 threads = TrackerSettings::Instance().m_FLACMultithreading ? static_cast<uint32>(std::max(std::thread::hardware_concurrency(), static_cast<unsigned int>(1))) : static_cast<uint32>(1);
|
uint32 threads = TrackerSettings::Instance().m_FLACMultithreading ? static_cast<uint32>(std::max(std::thread::hardware_concurrency(), static_cast<unsigned int>(1))) : static_cast<uint32>(1);
|
||||||
// Work-around <https://github.com/xiph/flac/issues/823>.
|
// Work-around <https://github.com/xiph/flac/issues/823>.
|
||||||
//FLAC__stream_encoder_set_num_threads(encoder, threads);
|
//FLAC__stream_encoder_set_num_threads(encoder, threads);
|
||||||
|
|
|
@ -618,6 +618,7 @@ enum PlayBehaviour
|
||||||
kITCarryAfterNoteOff, // Envelope Carry continues to function as normal even after note-off
|
kITCarryAfterNoteOff, // Envelope Carry continues to function as normal even after note-off
|
||||||
kFT2OffsetMemoryRequiresNote, // Offset memory is only updated when offset command is next to a note
|
kFT2OffsetMemoryRequiresNote, // Offset memory is only updated when offset command is next to a note
|
||||||
kITNoteCutWithPorta, // Note Cut (SCx) resets note frequency and interacts with tone portamento with row delay
|
kITNoteCutWithPorta, // Note Cut (SCx) resets note frequency and interacts with tone portamento with row delay
|
||||||
|
kITVolColNoSlidePropagation, // Don't propagate volume command c/d parameter to regular command D memory
|
||||||
|
|
||||||
// Add new play behaviours here.
|
// Add new play behaviours here.
|
||||||
|
|
||||||
|
|
|
@ -1312,7 +1312,9 @@ std::vector<GetLengthType> CSoundFile::GetLength(enmGetLengthResetMode adjustMod
|
||||||
for(uint32 i = 0; i < numTicks; i++)
|
for(uint32 i = 0; i < numTicks; i++)
|
||||||
{
|
{
|
||||||
chn.isFirstTick = (i == 0);
|
chn.isFirstTick = (i == 0);
|
||||||
VolumeSlide(chn, vol);
|
// IT Compatibility: Volume column volume slides must not propagate their memory to the regular effect column
|
||||||
|
// Test case: VolColNoSlideMemoryPropagation.it
|
||||||
|
VolumeSlide(chn, vol, m_playBehaviour[kITVolColNoSlidePropagation]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3077,6 +3079,8 @@ bool CSoundFile::ProcessEffects()
|
||||||
// Instrument Change ?
|
// Instrument Change ?
|
||||||
if(instr)
|
if(instr)
|
||||||
{
|
{
|
||||||
|
auto [oldChnOfsL, oldChnOfsR] = GetChannelOffsets(chn, nChn);
|
||||||
|
|
||||||
const ModSample *oldSample = chn.pModSample;
|
const ModSample *oldSample = chn.pModSample;
|
||||||
//const ModInstrument *oldInstrument = chn.pModInstrument;
|
//const ModInstrument *oldInstrument = chn.pModInstrument;
|
||||||
|
|
||||||
|
@ -3101,8 +3105,8 @@ bool CSoundFile::ProcessEffects()
|
||||||
// When swapping samples without explicit note change (e.g. during portamento), avoid clicks at end of sample (as there won't be an NNA channel to fade the sample out)
|
// When swapping samples without explicit note change (e.g. during portamento), avoid clicks at end of sample (as there won't be an NNA channel to fade the sample out)
|
||||||
if(oldSample != nullptr && oldSample != chn.pModSample)
|
if(oldSample != nullptr && oldSample != chn.pModSample)
|
||||||
{
|
{
|
||||||
m_dryLOfsVol += chn.nLOfs;
|
*oldChnOfsL += chn.nLOfs;
|
||||||
m_dryROfsVol += chn.nROfs;
|
*oldChnOfsR += chn.nROfs;
|
||||||
chn.nLOfs = 0;
|
chn.nLOfs = 0;
|
||||||
chn.nROfs = 0;
|
chn.nROfs = 0;
|
||||||
}
|
}
|
||||||
|
@ -3296,7 +3300,9 @@ bool CSoundFile::ProcessEffects()
|
||||||
{
|
{
|
||||||
chn.nOldVolParam = vol;
|
chn.nOldVolParam = vol;
|
||||||
}
|
}
|
||||||
VolumeSlide(chn, static_cast<ModCommand::PARAM>(volcmd == VOLCMD_VOLSLIDEUP ? (vol << 4) : vol));
|
// IT Compatibility: Volume column volume slides must not propagate their memory to the regular effect column
|
||||||
|
// Test case: VolColNoSlideMemoryPropagation.it
|
||||||
|
VolumeSlide(chn, static_cast<ModCommand::PARAM>(volcmd == VOLCMD_VOLSLIDEUP ? (vol << 4) : vol), m_playBehaviour[kITVolColNoSlidePropagation]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VOLCMD_FINEVOLUP:
|
case VOLCMD_FINEVOLUP:
|
||||||
|
@ -4833,12 +4839,15 @@ void CSoundFile::VolumeDownETX(const PlayState &playState, ModChannel &chn, ModC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CSoundFile::VolumeSlide(ModChannel &chn, ModCommand::PARAM param) const
|
void CSoundFile::VolumeSlide(ModChannel &chn, ModCommand::PARAM param, bool volCol) const
|
||||||
{
|
{
|
||||||
if (param)
|
if(!volCol)
|
||||||
|
{
|
||||||
|
if(param)
|
||||||
chn.nOldVolumeSlide = param;
|
chn.nOldVolumeSlide = param;
|
||||||
else
|
else
|
||||||
param = chn.nOldVolumeSlide;
|
param = chn.nOldVolumeSlide;
|
||||||
|
}
|
||||||
|
|
||||||
if((GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MED | MOD_TYPE_DIGI | MOD_TYPE_STP | MOD_TYPE_DTM)))
|
if((GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MED | MOD_TYPE_DIGI | MOD_TYPE_STP | MOD_TYPE_DTM)))
|
||||||
{
|
{
|
||||||
|
@ -5689,6 +5698,8 @@ void CSoundFile::ProcessSampleOffset(ModChannel &chn, CHANNELINDEX nChn, const P
|
||||||
|
|
||||||
void CSoundFile::SampleOffset(ModChannel &chn, SmpLength param) const
|
void CSoundFile::SampleOffset(ModChannel &chn, SmpLength param) const
|
||||||
{
|
{
|
||||||
|
LimitMax(param, MAX_SAMPLE_LENGTH);
|
||||||
|
|
||||||
// ST3 compatibility: Instrument-less note recalls previous note's offset
|
// ST3 compatibility: Instrument-less note recalls previous note's offset
|
||||||
// Test case: OxxMemory.s3m
|
// Test case: OxxMemory.s3m
|
||||||
if(m_playBehaviour[kST3OffsetWithoutInstrument] || GetType() == MOD_TYPE_MED)
|
if(m_playBehaviour[kST3OffsetWithoutInstrument] || GetType() == MOD_TYPE_MED)
|
||||||
|
@ -6285,6 +6296,9 @@ void CSoundFile::SetTempo(PlayState &playState, TEMPO param, bool setFromUI) con
|
||||||
} else if(param < minTempo && !playState.m_flags[SONG_FIRSTTICK])
|
} else if(param < minTempo && !playState.m_flags[SONG_FIRSTTICK])
|
||||||
{
|
{
|
||||||
// Tempo Slide
|
// Tempo Slide
|
||||||
|
// Very old MPT versions (last confirmed version: 1.09.066) add/subtract the param only on the first tick.
|
||||||
|
// Newer MPT versions (first confirmed version: 1.09.090), add/subtract the param multiplied by 2 only on the first tick.
|
||||||
|
// In SVN r26, the behaviour was adjusted to match Impulse Tracker. This change is part of OpenMPT 1.17 RC1 but not the MPT Wild pre-beta.
|
||||||
TEMPO tempDiff(param.GetInt() & 0x0F, 0);
|
TEMPO tempDiff(param.GetInt() & 0x0F, 0);
|
||||||
if((param.GetInt() & 0xF0) == 0x10)
|
if((param.GetInt() & 0xF0) == 0x10)
|
||||||
playState.m_nMusicTempo += tempDiff;
|
playState.m_nMusicTempo += tempDiff;
|
||||||
|
|
|
@ -1228,6 +1228,7 @@ PlayBehaviourSet CSoundFile::GetSupportedPlaybackBehaviour(MODTYPE type)
|
||||||
playBehaviour.set(kITDoublePortamentoSlides);
|
playBehaviour.set(kITDoublePortamentoSlides);
|
||||||
playBehaviour.set(kITCarryAfterNoteOff);
|
playBehaviour.set(kITCarryAfterNoteOff);
|
||||||
playBehaviour.set(kITNoteCutWithPorta);
|
playBehaviour.set(kITNoteCutWithPorta);
|
||||||
|
playBehaviour.set(kITVolColNoSlidePropagation);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOD_TYPE_XM:
|
case MOD_TYPE_XM:
|
||||||
|
|
|
@ -989,6 +989,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void CreateStereoMix(int count);
|
void CreateStereoMix(int count);
|
||||||
bool MixChannel(int count, ModChannel &chn, CHANNELINDEX channel, bool doMix);
|
bool MixChannel(int count, ModChannel &chn, CHANNELINDEX channel, bool doMix);
|
||||||
|
std::pair<mixsample_t *, mixsample_t *> GetChannelOffsets(const ModChannel &chn, CHANNELINDEX channel);
|
||||||
public:
|
public:
|
||||||
bool FadeSong(uint32 msec);
|
bool FadeSong(uint32 msec);
|
||||||
private:
|
private:
|
||||||
|
@ -1109,7 +1110,7 @@ protected:
|
||||||
void FineVibrato(ModChannel &chn, uint32 param) const;
|
void FineVibrato(ModChannel &chn, uint32 param) const;
|
||||||
void AutoVolumeSlide(ModChannel &chn, ModCommand::PARAM param) const;
|
void AutoVolumeSlide(ModChannel &chn, ModCommand::PARAM param) const;
|
||||||
void VolumeDownETX(const PlayState &playState, ModChannel &chn, ModCommand::PARAM param) const;
|
void VolumeDownETX(const PlayState &playState, ModChannel &chn, ModCommand::PARAM param) const;
|
||||||
void VolumeSlide(ModChannel &chn, ModCommand::PARAM param) const;
|
void VolumeSlide(ModChannel &chn, ModCommand::PARAM param, bool volCol = false) const;
|
||||||
void PanningSlide(ModChannel &chn, ModCommand::PARAM param, bool memory = true) const;
|
void PanningSlide(ModChannel &chn, ModCommand::PARAM param, bool memory = true) const;
|
||||||
void ChannelVolSlide(ModChannel &chn, ModCommand::PARAM param) const;
|
void ChannelVolSlide(ModChannel &chn, ModCommand::PARAM param) const;
|
||||||
void ChannelVolumeDownWithDuration(ModChannel &chn, uint16 param = uint16_max) const;
|
void ChannelVolumeDownWithDuration(ModChannel &chn, uint16 param = uint16_max) const;
|
||||||
|
|
|
@ -604,6 +604,7 @@ void CSoundFile::UpgradeModule()
|
||||||
{ kITDoublePortamentoSlides, MPT_V("1.32.00.27") },
|
{ kITDoublePortamentoSlides, MPT_V("1.32.00.27") },
|
||||||
{ kITCarryAfterNoteOff, MPT_V("1.32.00.40") },
|
{ kITCarryAfterNoteOff, MPT_V("1.32.00.40") },
|
||||||
{ kITNoteCutWithPorta, MPT_V("1.32.01.02") },
|
{ kITNoteCutWithPorta, MPT_V("1.32.01.02") },
|
||||||
|
{ kITVolColNoSlidePropagation, MPT_V("1.32.02.03") },
|
||||||
};
|
};
|
||||||
|
|
||||||
for(const auto &b : behaviours)
|
for(const auto &b : behaviours)
|
||||||
|
|
|
@ -1017,13 +1017,23 @@ bool CSoundFile::ReadJ2B(FileReader &file, ModLoadingFlags loadFlags)
|
||||||
|
|
||||||
// Header is valid, now unpack the RIFF AM file using inflate
|
// Header is valid, now unpack the RIFF AM file using inflate
|
||||||
z_stream strm{};
|
z_stream strm{};
|
||||||
if(inflateInit(&strm) != Z_OK)
|
int zlib_errc = Z_OK;
|
||||||
|
zlib_errc = inflateInit(&strm);
|
||||||
|
if(zlib_errc == Z_MEM_ERROR)
|
||||||
|
{
|
||||||
|
mpt::throw_out_of_memory();
|
||||||
|
} else if(zlib_errc < Z_OK)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 remainRead = fileHeader.packedLength, remainWrite = fileHeader.unpackedLength, totalWritten = 0;
|
uint32 remainRead = fileHeader.packedLength, remainWrite = fileHeader.unpackedLength, totalWritten = 0;
|
||||||
uint32 crc = 0;
|
uint32 crc = 0;
|
||||||
std::vector<Bytef> amFileData(remainWrite);
|
std::vector<Bytef> amFileData;
|
||||||
int retVal = Z_OK;
|
int retVal = Z_OK;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
amFileData.resize(remainWrite);
|
||||||
while(remainRead && remainWrite && retVal != Z_STREAM_END)
|
while(remainRead && remainWrite && retVal != Z_STREAM_END)
|
||||||
{
|
{
|
||||||
Bytef buffer[mpt::IO::BUFFERSIZE_TINY];
|
Bytef buffer[mpt::IO::BUFFERSIZE_TINY];
|
||||||
|
@ -1037,7 +1047,19 @@ bool CSoundFile::ReadJ2B(FileReader &file, ModLoadingFlags loadFlags)
|
||||||
{
|
{
|
||||||
strm.avail_out = remainWrite;
|
strm.avail_out = remainWrite;
|
||||||
strm.next_out = amFileData.data() + totalWritten;
|
strm.next_out = amFileData.data() + totalWritten;
|
||||||
retVal = inflate(&strm, Z_NO_FLUSH);
|
zlib_errc = inflate(&strm, Z_NO_FLUSH);
|
||||||
|
if(zlib_errc == Z_BUF_ERROR)
|
||||||
|
{
|
||||||
|
// expected
|
||||||
|
} else if(zlib_errc == Z_MEM_ERROR)
|
||||||
|
{
|
||||||
|
mpt::throw_out_of_memory();
|
||||||
|
} else if(zlib_errc < Z_OK)
|
||||||
|
{
|
||||||
|
inflateEnd(&strm);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
retVal = zlib_errc;
|
||||||
uint32 written = remainWrite - strm.avail_out;
|
uint32 written = remainWrite - strm.avail_out;
|
||||||
totalWritten += written;
|
totalWritten += written;
|
||||||
remainWrite -= written;
|
remainWrite -= written;
|
||||||
|
@ -1045,6 +1067,19 @@ bool CSoundFile::ReadJ2B(FileReader &file, ModLoadingFlags loadFlags)
|
||||||
|
|
||||||
remainRead -= readSize;
|
remainRead -= readSize;
|
||||||
}
|
}
|
||||||
|
} catch(mpt::out_of_memory e)
|
||||||
|
{
|
||||||
|
inflateEnd(&strm);
|
||||||
|
mpt::rethrow_out_of_memory(e);
|
||||||
|
} catch(const std::exception &)
|
||||||
|
{
|
||||||
|
inflateEnd(&strm);
|
||||||
|
return false;
|
||||||
|
} catch(...)
|
||||||
|
{
|
||||||
|
inflateEnd(&strm);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
inflateEnd(&strm);
|
inflateEnd(&strm);
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#define MPT_ARCH_ARCH_HPP
|
#define MPT_ARCH_ARCH_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include "mpt/arch/feature_fence.hpp"
|
||||||
#include "mpt/arch/feature_flags.hpp"
|
#include "mpt/arch/feature_flags.hpp"
|
||||||
#include "mpt/arch/x86_amd64.hpp"
|
#include "mpt/arch/x86_amd64.hpp"
|
||||||
#include "mpt/base/detect.hpp"
|
#include "mpt/base/detect.hpp"
|
||||||
|
|
57
Frameworks/OpenMPT/OpenMPT/src/mpt/arch/feature_fence.hpp
Normal file
57
Frameworks/OpenMPT/OpenMPT/src/mpt/arch/feature_fence.hpp
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/* SPDX-License-Identifier: BSL-1.0 OR BSD-3-Clause */
|
||||||
|
|
||||||
|
#ifndef MPT_ARCH_FEATURE_FENCE_HPP
|
||||||
|
#define MPT_ARCH_FEATURE_FENCE_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include "mpt/base/detect.hpp"
|
||||||
|
#include "mpt/base/macros.hpp"
|
||||||
|
#include "mpt/base/namespace.hpp"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace mpt {
|
||||||
|
inline namespace MPT_INLINE_NS {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace arch {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MPT_FORCEINLINE void feature_fence_aquire() noexcept {
|
||||||
|
std::atomic_signal_fence(std::memory_order_acquire);
|
||||||
|
}
|
||||||
|
|
||||||
|
MPT_FORCEINLINE void feature_fence_release() noexcept {
|
||||||
|
std::atomic_signal_fence(std::memory_order_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
class feature_fence_guard {
|
||||||
|
public:
|
||||||
|
MPT_FORCEINLINE feature_fence_guard() noexcept {
|
||||||
|
mpt::arch::feature_fence_aquire();
|
||||||
|
}
|
||||||
|
MPT_FORCEINLINE ~feature_fence_guard() noexcept {
|
||||||
|
mpt::arch::feature_fence_release();
|
||||||
|
}
|
||||||
|
feature_fence_guard(feature_fence_guard &&) = delete;
|
||||||
|
feature_fence_guard(const feature_fence_guard &) = delete;
|
||||||
|
feature_fence_guard & operator=(feature_fence_guard &&) = delete;
|
||||||
|
feature_fence_guard & operator=(const feature_fence_guard &) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace arch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace MPT_INLINE_NS
|
||||||
|
} // namespace mpt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MPT_ARCH_FEATURE_FENCE_HPP
|
|
@ -103,9 +103,17 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if !MPT_PLATFORM_MULTITHREADED
|
||||||
|
#define MPT_LIBCXX_QUIRK_NO_STD_THREAD
|
||||||
|
#elif !MPT_COMPILER_GENERIC && MPT_OS_WINDOWS && MPT_LIBCXX_GNU && !defined(_GLIBCXX_HAS_GTHREADS)
|
||||||
|
#define MPT_LIBCXX_QUIRK_NO_STD_THREAD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if MPT_OS_WINDOWS && MPT_COMPILER_MSVC
|
#if MPT_OS_WINDOWS && MPT_COMPILER_MSVC
|
||||||
#if MPT_WINNT_AT_LEAST(MPT_WIN_VISTA)
|
#if MPT_WINNT_AT_LEAST(MPT_WIN_VISTA)
|
||||||
#define MPT_COMPILER_QUIRK_COMPLEX_STD_MUTEX
|
#define MPT_LIBCXX_QUIRK_COMPLEX_STD_MUTEX
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -348,6 +356,10 @@
|
||||||
#if MPT_LIBCXX_GNU_BEFORE(13)
|
#if MPT_LIBCXX_GNU_BEFORE(13)
|
||||||
#define MPT_LIBCXX_QUIRK_CHRONO_DATE_NO_ZONED_TIME
|
#define MPT_LIBCXX_QUIRK_CHRONO_DATE_NO_ZONED_TIME
|
||||||
#endif
|
#endif
|
||||||
|
#if MPT_LIBCXX_LLVM
|
||||||
|
// See <https://github.com/llvm/llvm-project/issues/99982>
|
||||||
|
#define MPT_LIBCXX_QUIRK_CHRONO_DATE_NO_ZONED_TIME
|
||||||
|
#endif
|
||||||
#if MPT_MSVC_AT_LEAST(2022, 6) && MPT_MSVC_BEFORE(2022, 7)
|
#if MPT_MSVC_AT_LEAST(2022, 6) && MPT_MSVC_BEFORE(2022, 7)
|
||||||
// std::chrono triggers ICE in VS2022 17.6.0, see <https://developercommunity.visualstudio.com/t/INTERNAL-COMPILER-ERROR-when-compiling-s/10366948>.
|
// std::chrono triggers ICE in VS2022 17.6.0, see <https://developercommunity.visualstudio.com/t/INTERNAL-COMPILER-ERROR-when-compiling-s/10366948>.
|
||||||
#define MPT_LIBCXX_QUIRK_CHRONO_DATE_BROKEN_ZONED_TIME
|
#define MPT_LIBCXX_QUIRK_CHRONO_DATE_BROKEN_ZONED_TIME
|
||||||
|
|
|
@ -7,10 +7,9 @@
|
||||||
|
|
||||||
#include "mpt/base/array.hpp"
|
#include "mpt/base/array.hpp"
|
||||||
#include "mpt/base/detect.hpp"
|
#include "mpt/base/detect.hpp"
|
||||||
#include "mpt/base/namespace.hpp"
|
|
||||||
|
|
||||||
#include "mpt/base/integer.hpp"
|
#include "mpt/base/integer.hpp"
|
||||||
#include "mpt/base/memory.hpp"
|
#include "mpt/base/memory.hpp"
|
||||||
|
#include "mpt/base/namespace.hpp"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "mpt/base/detect.hpp"
|
||||||
#include "mpt/base/memory.hpp"
|
#include "mpt/base/memory.hpp"
|
||||||
#include "mpt/base/namespace.hpp"
|
#include "mpt/base/namespace.hpp"
|
||||||
#include "mpt/io_read/filedata.hpp"
|
#include "mpt/io_read/filedata.hpp"
|
||||||
|
@ -12,6 +13,9 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#if MPT_GCC_AT_LEAST(12, 0, 0)
|
||||||
|
#include <cstring>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +69,15 @@ public:
|
||||||
return dst.first(0);
|
return dst.first(0);
|
||||||
}
|
}
|
||||||
pos_type avail = std::min(streamLength - pos, static_cast<pos_type>(dst.size()));
|
pos_type avail = std::min(streamLength - pos, static_cast<pos_type>(dst.size()));
|
||||||
std::copy(streamData + pos, streamData + static_cast<std::size_t>(pos + avail), dst.data());
|
const std::byte * src = streamData + pos;
|
||||||
|
#if MPT_GCC_AT_LEAST(12, 0, 0)
|
||||||
|
// work-around bogus -Warray-bounds
|
||||||
|
// work-around bogus -Wstringop-overflow
|
||||||
|
// See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121165>.
|
||||||
|
std::memcpy(dst.data(), src, avail);
|
||||||
|
#else
|
||||||
|
std::copy(src, src + avail, dst.data());
|
||||||
|
#endif
|
||||||
return dst.first(static_cast<std::size_t>(avail));
|
return dst.first(static_cast<std::size_t>(avail));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,7 @@
|
||||||
|
|
||||||
#if !MPT_PLATFORM_MULTITHREADED
|
#if !MPT_PLATFORM_MULTITHREADED
|
||||||
#define MPT_MUTEX_NONE 1
|
#define MPT_MUTEX_NONE 1
|
||||||
#elif MPT_COMPILER_GENERIC
|
#elif defined(MPT_LIBCXX_QUIRK_NO_STD_THREAD)
|
||||||
#define MPT_MUTEX_STD 1
|
|
||||||
#elif MPT_OS_WINDOWS && MPT_LIBCXX_GNU && !defined(_GLIBCXX_HAS_GTHREADS)
|
|
||||||
#define MPT_MUTEX_WIN32 1
|
#define MPT_MUTEX_WIN32 1
|
||||||
#else
|
#else
|
||||||
#define MPT_MUTEX_STD 1
|
#define MPT_MUTEX_STD 1
|
||||||
|
@ -31,7 +29,7 @@
|
||||||
|
|
||||||
#if MPT_MUTEX_STD
|
#if MPT_MUTEX_STD
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#ifdef MPT_COMPILER_QUIRK_COMPLEX_STD_MUTEX
|
#ifdef MPT_LIBCXX_QUIRK_COMPLEX_STD_MUTEX
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,7 +46,7 @@ inline namespace MPT_INLINE_NS {
|
||||||
|
|
||||||
#if MPT_MUTEX_STD
|
#if MPT_MUTEX_STD
|
||||||
|
|
||||||
#ifdef MPT_COMPILER_QUIRK_COMPLEX_STD_MUTEX
|
#ifdef MPT_LIBCXX_QUIRK_COMPLEX_STD_MUTEX
|
||||||
using mutex = std::conditional<sizeof(std::shared_mutex) < sizeof(std::mutex), std::shared_mutex, std::mutex>::type;
|
using mutex = std::conditional<sizeof(std::shared_mutex) < sizeof(std::mutex), std::shared_mutex, std::mutex>::type;
|
||||||
#else
|
#else
|
||||||
using mutex = std::mutex;
|
using mutex = std::mutex;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
|
@ -256,6 +256,7 @@
|
||||||
83BB83FD2DF2BE22002077FC /* wav.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 83BB83F72DF2BE22002077FC /* wav.hpp */; };
|
83BB83FD2DF2BE22002077FC /* wav.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 83BB83F72DF2BE22002077FC /* wav.hpp */; };
|
||||||
83BB83FE2DF2BE22002077FC /* wav_write.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 83BB83F92DF2BE22002077FC /* wav_write.hpp */; };
|
83BB83FE2DF2BE22002077FC /* wav_write.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 83BB83F92DF2BE22002077FC /* wav_write.hpp */; };
|
||||||
83BB83FF2DF2BE22002077FC /* tags.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 83BB83F62DF2BE22002077FC /* tags.hpp */; };
|
83BB83FF2DF2BE22002077FC /* tags.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 83BB83F62DF2BE22002077FC /* tags.hpp */; };
|
||||||
|
83BDCD912E418723003FC007 /* feature_fence.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 83BDCD902E418723003FC007 /* feature_fence.hpp */; };
|
||||||
83E5EFD01FFEF9D200659F0F /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E5EFCE1FFEF9D200659F0F /* config.h */; };
|
83E5EFD01FFEF9D200659F0F /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E5EFCE1FFEF9D200659F0F /* config.h */; };
|
||||||
83E5FC661FFEFA0D00659F0F /* version.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E5FC2D1FFEFA0D00659F0F /* version.h */; };
|
83E5FC661FFEFA0D00659F0F /* version.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E5FC2D1FFEFA0D00659F0F /* version.h */; };
|
||||||
83E5FC681FFEFA0D00659F0F /* stdafx.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E5FC2F1FFEFA0D00659F0F /* stdafx.h */; };
|
83E5FC681FFEFA0D00659F0F /* stdafx.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E5FC2F1FFEFA0D00659F0F /* stdafx.h */; };
|
||||||
|
@ -734,6 +735,7 @@
|
||||||
83BB83F72DF2BE22002077FC /* wav.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = wav.hpp; sourceTree = "<group>"; };
|
83BB83F72DF2BE22002077FC /* wav.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = wav.hpp; sourceTree = "<group>"; };
|
||||||
83BB83F92DF2BE22002077FC /* wav_write.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = wav_write.hpp; sourceTree = "<group>"; };
|
83BB83F92DF2BE22002077FC /* wav_write.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = wav_write.hpp; sourceTree = "<group>"; };
|
||||||
83BB83FA2DF2BE22002077FC /* wav_write.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wav_write.cpp; sourceTree = "<group>"; };
|
83BB83FA2DF2BE22002077FC /* wav_write.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wav_write.cpp; sourceTree = "<group>"; };
|
||||||
|
83BDCD902E418723003FC007 /* feature_fence.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = feature_fence.hpp; sourceTree = "<group>"; };
|
||||||
83E5EFBD1FFEF7CC00659F0F /* libOpenMPT.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libOpenMPT.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
83E5EFBD1FFEF7CC00659F0F /* libOpenMPT.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libOpenMPT.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
83E5EFCE1FFEF9D200659F0F /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = SOURCE_ROOT; };
|
83E5EFCE1FFEF9D200659F0F /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = SOURCE_ROOT; };
|
||||||
83E5EFCF1FFEF9D200659F0F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
|
83E5EFCF1FFEF9D200659F0F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
|
||||||
|
@ -1487,6 +1489,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
83649BA62A03418500CD0580 /* arch.hpp */,
|
83649BA62A03418500CD0580 /* arch.hpp */,
|
||||||
|
83BDCD902E418723003FC007 /* feature_fence.hpp */,
|
||||||
83649BA52A03418500CD0580 /* feature_flags.hpp */,
|
83649BA52A03418500CD0580 /* feature_flags.hpp */,
|
||||||
83649BA72A03418500CD0580 /* x86_amd64.hpp */,
|
83649BA72A03418500CD0580 /* x86_amd64.hpp */,
|
||||||
);
|
);
|
||||||
|
@ -2113,6 +2116,7 @@
|
||||||
83E5FCDB1FFEFA1A00659F0F /* libopenmpt_stream_callbacks_file.h in Headers */,
|
83E5FCDB1FFEFA1A00659F0F /* libopenmpt_stream_callbacks_file.h in Headers */,
|
||||||
830996BA27787E9A00857684 /* base.hpp in Headers */,
|
830996BA27787E9A00857684 /* base.hpp in Headers */,
|
||||||
83E5FDC31FFEFA8500659F0F /* MIDIEvents.h in Headers */,
|
83E5FDC31FFEFA8500659F0F /* MIDIEvents.h in Headers */,
|
||||||
|
83BDCD912E418723003FC007 /* feature_fence.hpp in Headers */,
|
||||||
83E5FDF81FFEFA8500659F0F /* Compressor.h in Headers */,
|
83E5FDF81FFEFA8500659F0F /* Compressor.h in Headers */,
|
||||||
8309970C27787E9A00857684 /* detect_compiler.hpp in Headers */,
|
8309970C27787E9A00857684 /* detect_compiler.hpp in Headers */,
|
||||||
830996C227787E9A00857684 /* simple_integer.hpp in Headers */,
|
830996C227787E9A00857684 /* simple_integer.hpp in Headers */,
|
||||||
|
|
Loading…
Reference in a new issue