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)
|
||||
HOST_FLAVOUR=OPENBSD
|
||||
endif
|
||||
ifeq ($(UNAME_S),DragonFly)
|
||||
HOST_FLAVOUR=DRAGONFLY
|
||||
endif
|
||||
ifeq ($(UNAME_S),Haiku)
|
||||
HOST_FLAVOUR=HAIKU
|
||||
endif
|
||||
|
@ -408,6 +411,8 @@ TAR_C=tar -c -N
|
|||
else
|
||||
TAR_C=tar -c -F pax -N
|
||||
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)
|
||||
TAR_C=tar -c --format pax --numeric-owner --uname "" --gname "" --uid 0 --gid 0
|
||||
else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
MPT_SVNVERSION=23497
|
||||
MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.8.1
|
||||
MPT_SVNDATE=2025-06-14T13:04:39.042416Z
|
||||
MPT_SVNVERSION=23826
|
||||
MPT_SVNURL=https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.8.2
|
||||
MPT_SVNDATE=2025-07-19T10:45:24.126020Z
|
||||
|
|
|
@ -53,6 +53,13 @@ LDLIBS_PLATFORM=-lc++ -lc
|
|||
include build/make/config-clang.mk
|
||||
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)
|
||||
|
||||
NO_PULSEAUDIO?=1
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
#pragma once
|
||||
#define OPENMPT_VERSION_SVNVERSION "23497"
|
||||
#define OPENMPT_VERSION_REVISION 23497
|
||||
#define OPENMPT_VERSION_SVNVERSION "23826"
|
||||
#define OPENMPT_VERSION_REVISION 23826
|
||||
#define OPENMPT_VERSION_DIRTY 0
|
||||
#define OPENMPT_VERSION_MIXEDREVISIONS 0
|
||||
#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.8.1"
|
||||
#define OPENMPT_VERSION_DATE "2025-06-14T13:04:39.042416Z"
|
||||
#define OPENMPT_VERSION_URL "https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.8.2"
|
||||
#define OPENMPT_VERSION_DATE "2025-07-19T10:45:24.126020Z"
|
||||
#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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
|
@ -1517,6 +1518,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
09573FAA7A79E09C30408DEA /* arch.hpp */,
|
||||
55E9D1C649E91B38CED43006 /* feature_fence.hpp */,
|
||||
1197459E05968F108A81A3DE /* feature_flags.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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
|
@ -1517,6 +1518,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
09573FAA7A79E09C30408DEA /* arch.hpp */,
|
||||
55E9D1C649E91B38CED43006 /* feature_fence.hpp */,
|
||||
1197459E05968F108A81A3DE /* feature_flags.hpp */,
|
||||
473316F00DC10E627BC33530 /* x86_amd64.hpp */,
|
||||
);
|
||||
|
|
|
@ -12,12 +12,15 @@
|
|||
|
||||
#include "openmpt/all/BuildSettings.hpp"
|
||||
|
||||
#include "mptString.h"
|
||||
#include "mpt/io/io.hpp"
|
||||
#include "mpt/io/io_stdstream.hpp"
|
||||
|
||||
#include "mptString.h"
|
||||
|
||||
#ifdef MPT_WITH_ZLIB
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
OPENMPT_NAMESPACE_BEGIN
|
||||
|
@ -25,15 +28,31 @@ OPENMPT_NAMESPACE_BEGIN
|
|||
inline void WriteGzip(std::ostream &output, std::string &outData, const mpt::ustring &fileName)
|
||||
{
|
||||
z_stream strm{};
|
||||
int zlib_errc = Z_OK;
|
||||
strm.avail_in = static_cast<uInt>(outData.size());
|
||||
strm.next_in = reinterpret_cast<Bytef *>(outData.data());
|
||||
if(deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, 15 | 16, 9, Z_DEFAULT_STRATEGY) != Z_OK)
|
||||
throw std::runtime_error{"zlib init failed"};
|
||||
zlib_errc = deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, 15 | 16, 9, Z_DEFAULT_STRATEGY);
|
||||
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{};
|
||||
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);
|
||||
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
|
||||
{
|
||||
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;
|
||||
strm.avail_out = static_cast<uInt>(buffer.size());
|
||||
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);
|
||||
} while(strm.avail_out == 0);
|
||||
} catch(mpt::out_of_memory e)
|
||||
{
|
||||
deflateEnd(&strm);
|
||||
mpt::rethrow_out_of_memory(e);
|
||||
} catch(const std::exception &)
|
||||
{
|
||||
deflateEnd(&strm);
|
||||
throw;
|
||||
} catch(...)
|
||||
{
|
||||
deflateEnd(&strm);
|
||||
throw;
|
||||
}
|
||||
deflateEnd(&strm);
|
||||
}
|
||||
|
||||
OPENMPT_NAMESPACE_END
|
||||
|
|
|
@ -42,7 +42,7 @@ OPENMPT_NAMESPACE_BEGIN
|
|||
|
||||
|
||||
#ifdef SSB_LOGGING
|
||||
#define SSB_LOG(x) MPT_LOG_GLOBAL(LogDebug, "serialization", x)
|
||||
#define SSB_LOG(x) MPT_LOG_GLOBAL(LogDebug, "serialization", (x))
|
||||
#else
|
||||
#define SSB_LOG(x) do { } while(0)
|
||||
#endif
|
||||
|
|
|
@ -15,5 +15,5 @@
|
|||
// Version definitions. The only thing that needs to be changed when changing version number.
|
||||
#define VER_MAJORMAJOR 1
|
||||
#define VER_MAJOR 32
|
||||
#define VER_MINOR 01
|
||||
#define VER_MINORMINOR 04
|
||||
#define VER_MINOR 03
|
||||
#define VER_MINORMINOR 00
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
/*! \brief libopenmpt minor version number */
|
||||
#define OPENMPT_API_VERSION_MINOR 8
|
||||
/*! \brief libopenmpt patch version number */
|
||||
#define OPENMPT_API_VERSION_PATCH 1
|
||||
#define OPENMPT_API_VERSION_PATCH 2
|
||||
/*! \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=8
|
||||
LIBOPENMPT_VERSION_PATCH=1
|
||||
LIBOPENMPT_VERSION_PATCH=2
|
||||
LIBOPENMPT_VERSION_PREREL=
|
||||
|
||||
LIBOPENMPT_LTVER_CURRENT=5
|
||||
LIBOPENMPT_LTVER_REVISION=1
|
||||
LIBOPENMPT_LTVER_REVISION=2
|
||||
LIBOPENMPT_LTVER_AGE=5
|
||||
|
|
|
@ -38,6 +38,25 @@ static const char * const license =
|
|||
#include "openmpt123_config.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_quirks.hpp"
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "mpt/base/saturate_round.hpp"
|
||||
|
||||
#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>
|
||||
#endif
|
||||
|
||||
|
@ -71,7 +71,7 @@ public:
|
|||
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_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)));
|
||||
// Work-around <https://github.com/xiph/flac/issues/823>.
|
||||
//FLAC__stream_encoder_set_num_threads( encoder, threads );
|
||||
|
|
|
@ -90,7 +90,7 @@ public:
|
|||
switch (new_mode) {
|
||||
case FILE_mode::text:
|
||||
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 );
|
||||
#else
|
||||
old_mode = _setmode( _fileno( file ), _O_TEXT );
|
||||
|
|
|
@ -102,6 +102,7 @@ void CEQ::ProcessTemplate(TMixSample *frontBuffer, TMixSample *rearBuffer, std::
|
|||
unsigned int old_csr = 0;
|
||||
if(CPU::HasFeatureSet(CPU::feature::sse) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
||||
{
|
||||
mpt::arch::feature_fence_aquire();
|
||||
old_csr = _mm_getcsr();
|
||||
_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))
|
||||
{
|
||||
_mm_setcsr(old_csr);
|
||||
mpt::arch::feature_fence_release();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ const REFLECTIONPRESET gReflectionsPreset[ENVIRONMENT_NUMREFLECTIONS] =
|
|||
// 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(
|
||||
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(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_X1 = Load64SSE(gnDCRRvb_X1);
|
||||
__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(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_X1 = Load64SSE(gnDCRRvb_X1);
|
||||
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(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 history = _mm_cvtsi32_si128(pPreDelay->History.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(CPU::HasFeatureSet(CPU::feature::sse2) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
||||
{
|
||||
mpt::arch::feature_fence_guard arch_feature_guard;
|
||||
union
|
||||
{
|
||||
__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(CPU::HasFeatureSet(CPU::feature::sse2) && CPU::HasModesEnabled(CPU::mode::xmm128sse))
|
||||
{
|
||||
mpt::arch::feature_fence_guard arch_feature_guard;
|
||||
int delayPos = pReverb->nDelayPos & RVBDLY_MASK;
|
||||
__m128i rvbOutGains = Load64SSE(pReverb->RvbOutGains);
|
||||
__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
|
||||
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;
|
||||
|
||||
if(nSamples <= 0 || nInc.IsZero() || !chn.nLength || !samplePointer)
|
||||
|
@ -227,35 +227,24 @@ struct MixLoopState
|
|||
{
|
||||
if(nPosInt >= lookaheadStart)
|
||||
{
|
||||
#if 0
|
||||
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())
|
||||
if(nInc.IsNegative())
|
||||
{
|
||||
nSmpCount = DistanceToBufferLength(SamplePosition(lookaheadStart, 0), nPos, nInv);
|
||||
} else
|
||||
chn.pCurrentSample = lookaheadPointer;
|
||||
} else if(nPosInt <= chn.nLoopEnd)
|
||||
{
|
||||
nSmpCount = DistanceToBufferLength(nPos, SamplePosition(chn.nLoopEnd, 0), nInv);
|
||||
chn.pCurrentSample = lookaheadPointer;
|
||||
} else
|
||||
{
|
||||
nSmpCount = DistanceToBufferLength(nPos, SamplePosition(chn.nLength, 0), nInv);
|
||||
}
|
||||
#endif
|
||||
chn.pCurrentSample = lookaheadPointer;
|
||||
checkDest = false;
|
||||
} else if(chn.dwFlags[CHN_WRAPPED_LOOP] && isAtLoopStart)
|
||||
{
|
||||
// We just restarted the loop, so interpolate correctly after wrapping around
|
||||
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;
|
||||
} 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)
|
||||
{
|
||||
if(chn.pCurrentSample || chn.nLOfs || chn.nROfs)
|
||||
{
|
||||
mixsample_t *pOfsR = &m_dryROfsVol;
|
||||
mixsample_t *pOfsL = &m_dryLOfsVol;
|
||||
auto [pOfsL, pOfsR] = GetChannelOffsets(chn, channel);
|
||||
|
||||
uint32 functionNdx = MixFuncTable::ResamplingModeToMixFlags(static_cast<ResamplingMode>(chn.resamplingMode));
|
||||
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);
|
||||
pbuffer = ReverbSendBuffer;
|
||||
pOfsR = &m_RvbROfsVol;
|
||||
pOfsL = &m_RvbLOfsVol;
|
||||
}
|
||||
#endif
|
||||
if(chn.dwFlags[CHN_SURROUND] && m_MixerSettings.gnChannels > 2)
|
||||
{
|
||||
pbuffer = MixRearBuffer;
|
||||
pOfsR = &m_surroundROfsVol;
|
||||
pOfsL = &m_surroundLOfsVol;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
pbuffer = mixState.pMixBuffer;
|
||||
pOfsR = &mixState.nVolDecayR;
|
||||
pOfsL = &mixState.nVolDecayL;
|
||||
if (!(mixState.dwFlags & SNDMIXPLUGINSTATE::psfMixReady))
|
||||
{
|
||||
StereoFill(pbuffer, count, *pOfsR, *pOfsL);
|
||||
|
|
|
@ -83,8 +83,9 @@ struct FCFileHeader
|
|||
return false;
|
||||
|
||||
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
|
||||
|| sequenceSize < sizeof(FCPlaylistEntry) || sequenceSize > 256 * 13
|
||||
const uint32 seqSize = SequenceSize();
|
||||
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
|
||||
|| freqSequenceSize % 64u || !freqSequenceSize || freqSequenceSize > 64 * 256 || freqSequenceOffset > MAX_FC_SIZE
|
||||
|| volSequenceSize % 64u || !volSequenceSize || volSequenceSize > 64 * 256 || volSequenceOffset > MAX_FC_SIZE
|
||||
|
@ -102,12 +103,22 @@ struct FCFileHeader
|
|||
|
||||
ORDERINDEX NumOrders() const
|
||||
{
|
||||
return static_cast<ORDERINDEX>(sequenceSize / sizeof(FCPlaylistEntry));
|
||||
return static_cast<ORDERINDEX>(SequenceSize() / sizeof(FCPlaylistEntry));
|
||||
}
|
||||
|
||||
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::size_type pos;
|
||||
while((pos = sanitizedMacro.find_first_not_of("0123456789ABCDEFabchmnopsuvxyz")) != std::string::npos)
|
||||
std::string::size_type pos = 0;
|
||||
while((pos = sanitizedMacro.find_first_not_of("0123456789ABCDEFabchmnopsuvxyz", pos)) != std::string::npos)
|
||||
{
|
||||
sanitizedMacro.erase(pos, 1);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ OPENMPT_NAMESPACE_BEGIN
|
|||
|
||||
|
||||
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());
|
||||
m_name = other.m_name;
|
||||
m_restartPos = other.m_restartPos;
|
||||
m_defaultTempo = other.m_defaultTempo;
|
||||
m_defaultSpeed = other.m_defaultSpeed;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -41,7 +43,9 @@ bool ModSequence::operator== (const ModSequence &other) const noexcept
|
|||
{
|
||||
return static_cast<const std::vector<PATTERNINDEX> &>(*this) == other
|
||||
&& 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 "OggStream.h"
|
||||
#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>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef MPT_WITH_OGG
|
||||
#if MPT_COMPILER_CLANG
|
||||
#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);
|
||||
#ifdef MODPLUG_TRACKER
|
||||
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);
|
||||
// Work-around <https://github.com/xiph/flac/issues/823>.
|
||||
//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
|
||||
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
|
||||
kITVolColNoSlidePropagation, // Don't propagate volume command c/d parameter to regular command D memory
|
||||
|
||||
// Add new play behaviours here.
|
||||
|
||||
|
|
|
@ -1312,7 +1312,9 @@ std::vector<GetLengthType> CSoundFile::GetLength(enmGetLengthResetMode adjustMod
|
|||
for(uint32 i = 0; i < numTicks; i++)
|
||||
{
|
||||
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;
|
||||
|
@ -3077,6 +3079,8 @@ bool CSoundFile::ProcessEffects()
|
|||
// Instrument Change ?
|
||||
if(instr)
|
||||
{
|
||||
auto [oldChnOfsL, oldChnOfsR] = GetChannelOffsets(chn, nChn);
|
||||
|
||||
const ModSample *oldSample = chn.pModSample;
|
||||
//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)
|
||||
if(oldSample != nullptr && oldSample != chn.pModSample)
|
||||
{
|
||||
m_dryLOfsVol += chn.nLOfs;
|
||||
m_dryROfsVol += chn.nROfs;
|
||||
*oldChnOfsL += chn.nLOfs;
|
||||
*oldChnOfsR += chn.nROfs;
|
||||
chn.nLOfs = 0;
|
||||
chn.nROfs = 0;
|
||||
}
|
||||
|
@ -3296,7 +3300,9 @@ bool CSoundFile::ProcessEffects()
|
|||
{
|
||||
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;
|
||||
|
||||
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)
|
||||
chn.nOldVolumeSlide = param;
|
||||
else
|
||||
param = chn.nOldVolumeSlide;
|
||||
if(!volCol)
|
||||
{
|
||||
if(param)
|
||||
chn.nOldVolumeSlide = param;
|
||||
else
|
||||
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)))
|
||||
{
|
||||
|
@ -5689,6 +5698,8 @@ void CSoundFile::ProcessSampleOffset(ModChannel &chn, CHANNELINDEX nChn, const P
|
|||
|
||||
void CSoundFile::SampleOffset(ModChannel &chn, SmpLength param) const
|
||||
{
|
||||
LimitMax(param, MAX_SAMPLE_LENGTH);
|
||||
|
||||
// ST3 compatibility: Instrument-less note recalls previous note's offset
|
||||
// Test case: OxxMemory.s3m
|
||||
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])
|
||||
{
|
||||
// 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);
|
||||
if((param.GetInt() & 0xF0) == 0x10)
|
||||
playState.m_nMusicTempo += tempDiff;
|
||||
|
|
|
@ -1228,6 +1228,7 @@ PlayBehaviourSet CSoundFile::GetSupportedPlaybackBehaviour(MODTYPE type)
|
|||
playBehaviour.set(kITDoublePortamentoSlides);
|
||||
playBehaviour.set(kITCarryAfterNoteOff);
|
||||
playBehaviour.set(kITNoteCutWithPorta);
|
||||
playBehaviour.set(kITVolColNoSlidePropagation);
|
||||
break;
|
||||
|
||||
case MOD_TYPE_XM:
|
||||
|
|
|
@ -989,6 +989,7 @@ public:
|
|||
private:
|
||||
void CreateStereoMix(int count);
|
||||
bool MixChannel(int count, ModChannel &chn, CHANNELINDEX channel, bool doMix);
|
||||
std::pair<mixsample_t *, mixsample_t *> GetChannelOffsets(const ModChannel &chn, CHANNELINDEX channel);
|
||||
public:
|
||||
bool FadeSong(uint32 msec);
|
||||
private:
|
||||
|
@ -1109,7 +1110,7 @@ protected:
|
|||
void FineVibrato(ModChannel &chn, uint32 param) const;
|
||||
void AutoVolumeSlide(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 ChannelVolSlide(ModChannel &chn, ModCommand::PARAM param) const;
|
||||
void ChannelVolumeDownWithDuration(ModChannel &chn, uint16 param = uint16_max) const;
|
||||
|
|
|
@ -604,6 +604,7 @@ void CSoundFile::UpgradeModule()
|
|||
{ kITDoublePortamentoSlides, MPT_V("1.32.00.27") },
|
||||
{ kITCarryAfterNoteOff, MPT_V("1.32.00.40") },
|
||||
{ kITNoteCutWithPorta, MPT_V("1.32.01.02") },
|
||||
{ kITVolColNoSlidePropagation, MPT_V("1.32.02.03") },
|
||||
};
|
||||
|
||||
for(const auto &b : behaviours)
|
||||
|
|
|
@ -1017,33 +1017,68 @@ bool CSoundFile::ReadJ2B(FileReader &file, ModLoadingFlags loadFlags)
|
|||
|
||||
// Header is valid, now unpack the RIFF AM file using inflate
|
||||
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;
|
||||
}
|
||||
|
||||
uint32 remainRead = fileHeader.packedLength, remainWrite = fileHeader.unpackedLength, totalWritten = 0;
|
||||
uint32 crc = 0;
|
||||
std::vector<Bytef> amFileData(remainWrite);
|
||||
std::vector<Bytef> amFileData;
|
||||
int retVal = Z_OK;
|
||||
while(remainRead && remainWrite && retVal != Z_STREAM_END)
|
||||
try
|
||||
{
|
||||
Bytef buffer[mpt::IO::BUFFERSIZE_TINY];
|
||||
uint32 readSize = std::min(static_cast<uint32>(sizeof(buffer)), remainRead);
|
||||
file.ReadRaw(mpt::span(buffer, readSize));
|
||||
crc = static_cast<uint32>(crc32(crc, buffer, readSize));
|
||||
|
||||
strm.avail_in = readSize;
|
||||
strm.next_in = buffer;
|
||||
do
|
||||
amFileData.resize(remainWrite);
|
||||
while(remainRead && remainWrite && retVal != Z_STREAM_END)
|
||||
{
|
||||
strm.avail_out = remainWrite;
|
||||
strm.next_out = amFileData.data() + totalWritten;
|
||||
retVal = inflate(&strm, Z_NO_FLUSH);
|
||||
uint32 written = remainWrite - strm.avail_out;
|
||||
totalWritten += written;
|
||||
remainWrite -= written;
|
||||
} while(remainWrite && strm.avail_out == 0);
|
||||
Bytef buffer[mpt::IO::BUFFERSIZE_TINY];
|
||||
uint32 readSize = std::min(static_cast<uint32>(sizeof(buffer)), remainRead);
|
||||
file.ReadRaw(mpt::span(buffer, readSize));
|
||||
crc = static_cast<uint32>(crc32(crc, buffer, readSize));
|
||||
|
||||
remainRead -= readSize;
|
||||
strm.avail_in = readSize;
|
||||
strm.next_in = buffer;
|
||||
do
|
||||
{
|
||||
strm.avail_out = remainWrite;
|
||||
strm.next_out = amFileData.data() + totalWritten;
|
||||
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;
|
||||
totalWritten += written;
|
||||
remainWrite -= written;
|
||||
} while(remainWrite && strm.avail_out == 0);
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#define MPT_ARCH_ARCH_HPP
|
||||
|
||||
|
||||
#include "mpt/arch/feature_fence.hpp"
|
||||
#include "mpt/arch/feature_flags.hpp"
|
||||
#include "mpt/arch/x86_amd64.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_WINNT_AT_LEAST(MPT_WIN_VISTA)
|
||||
#define MPT_COMPILER_QUIRK_COMPLEX_STD_MUTEX
|
||||
#define MPT_LIBCXX_QUIRK_COMPLEX_STD_MUTEX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -348,6 +356,10 @@
|
|||
#if MPT_LIBCXX_GNU_BEFORE(13)
|
||||
#define MPT_LIBCXX_QUIRK_CHRONO_DATE_NO_ZONED_TIME
|
||||
#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)
|
||||
// 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
|
||||
|
|
|
@ -7,10 +7,9 @@
|
|||
|
||||
#include "mpt/base/array.hpp"
|
||||
#include "mpt/base/detect.hpp"
|
||||
#include "mpt/base/namespace.hpp"
|
||||
|
||||
#include "mpt/base/integer.hpp"
|
||||
#include "mpt/base/memory.hpp"
|
||||
#include "mpt/base/namespace.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
|
||||
|
||||
#include "mpt/base/detect.hpp"
|
||||
#include "mpt/base/memory.hpp"
|
||||
#include "mpt/base/namespace.hpp"
|
||||
#include "mpt/io_read/filedata.hpp"
|
||||
|
@ -12,6 +13,9 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include <cstddef>
|
||||
#if MPT_GCC_AT_LEAST(12, 0, 0)
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -65,7 +69,15 @@ public:
|
|||
return dst.first(0);
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,7 @@
|
|||
|
||||
#if !MPT_PLATFORM_MULTITHREADED
|
||||
#define MPT_MUTEX_NONE 1
|
||||
#elif MPT_COMPILER_GENERIC
|
||||
#define MPT_MUTEX_STD 1
|
||||
#elif MPT_OS_WINDOWS && MPT_LIBCXX_GNU && !defined(_GLIBCXX_HAS_GTHREADS)
|
||||
#elif defined(MPT_LIBCXX_QUIRK_NO_STD_THREAD)
|
||||
#define MPT_MUTEX_WIN32 1
|
||||
#else
|
||||
#define MPT_MUTEX_STD 1
|
||||
|
@ -31,7 +29,7 @@
|
|||
|
||||
#if MPT_MUTEX_STD
|
||||
#include <mutex>
|
||||
#ifdef MPT_COMPILER_QUIRK_COMPLEX_STD_MUTEX
|
||||
#ifdef MPT_LIBCXX_QUIRK_COMPLEX_STD_MUTEX
|
||||
#include <shared_mutex>
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
@ -48,7 +46,7 @@ inline namespace MPT_INLINE_NS {
|
|||
|
||||
#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;
|
||||
#else
|
||||
using mutex = std::mutex;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <memory>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
|
|
@ -256,6 +256,7 @@
|
|||
83BB83FD2DF2BE22002077FC /* wav.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 83BB83F72DF2BE22002077FC /* wav.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 */; };
|
||||
83BDCD912E418723003FC007 /* feature_fence.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 83BDCD902E418723003FC007 /* feature_fence.hpp */; };
|
||||
83E5EFD01FFEF9D200659F0F /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E5EFCE1FFEF9D200659F0F /* config.h */; };
|
||||
83E5FC661FFEFA0D00659F0F /* version.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E5FC2D1FFEFA0D00659F0F /* version.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>"; };
|
||||
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>"; };
|
||||
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; };
|
||||
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; };
|
||||
|
@ -1487,6 +1489,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
83649BA62A03418500CD0580 /* arch.hpp */,
|
||||
83BDCD902E418723003FC007 /* feature_fence.hpp */,
|
||||
83649BA52A03418500CD0580 /* feature_flags.hpp */,
|
||||
83649BA72A03418500CD0580 /* x86_amd64.hpp */,
|
||||
);
|
||||
|
@ -2113,6 +2116,7 @@
|
|||
83E5FCDB1FFEFA1A00659F0F /* libopenmpt_stream_callbacks_file.h in Headers */,
|
||||
830996BA27787E9A00857684 /* base.hpp in Headers */,
|
||||
83E5FDC31FFEFA8500659F0F /* MIDIEvents.h in Headers */,
|
||||
83BDCD912E418723003FC007 /* feature_fence.hpp in Headers */,
|
||||
83E5FDF81FFEFA8500659F0F /* Compressor.h in Headers */,
|
||||
8309970C27787E9A00857684 /* detect_compiler.hpp in Headers */,
|
||||
830996C227787E9A00857684 /* simple_integer.hpp in Headers */,
|
||||
|
|
Loading…
Reference in a new issue