diff --git a/Frameworks/OpenMPT/OpenMPT/common/CompilerDetect.h b/Frameworks/OpenMPT/OpenMPT/common/CompilerDetect.h index 78c180116..2d858bb7c 100644 --- a/Frameworks/OpenMPT/OpenMPT/common/CompilerDetect.h +++ b/Frameworks/OpenMPT/OpenMPT/common/CompilerDetect.h @@ -61,7 +61,9 @@ #elif defined(_MSC_VER) #define MPT_COMPILER_MSVC 1 -#if (_MSC_VER >= 1912) +#if (_MSC_VER >= 1913) +#define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2017,6) +#elif (_MSC_VER >= 1912) #define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2017,5) #elif (_MSC_VER >= 1911) #define MPT_COMPILER_MSVC_VERSION MPT_COMPILER_MAKE_VERSION2(2017,3) diff --git a/Frameworks/OpenMPT/OpenMPT/common/Logging.cpp b/Frameworks/OpenMPT/OpenMPT/common/Logging.cpp index 7d2158e7c..5fcc59d81 100644 --- a/Frameworks/OpenMPT/OpenMPT/common/Logging.cpp +++ b/Frameworks/OpenMPT/OpenMPT/common/Logging.cpp @@ -255,6 +255,7 @@ static std::atomic NextIndex(0); static uint32 ThreadIdGUI = 0; static uint32 ThreadIdAudio = 0; static uint32 ThreadIdNotify = 0; +static uint32 ThreadIdWatchdir = 0; void Enable(std::size_t numEntries) { @@ -379,6 +380,9 @@ bool Dump(const mpt::PathString &filename) } else if(entry.ThreadId == ThreadIdNotify) { f << " --Notify "; + } else if(entry.ThreadId == ThreadIdWatchdir) + { + f << " WatchDir "; } else { f << " " << mpt::fmt::hex0<8>(entry.ThreadId) << " "; @@ -406,9 +410,33 @@ void SetThreadId(mpt::log::Trace::ThreadKind kind, uint32 id) case ThreadKindNotify: ThreadIdNotify = id; break; + case ThreadKindWatchdir: + ThreadIdWatchdir = id; + break; } } +uint32 GetThreadId(mpt::log::Trace::ThreadKind kind) +{ + uint32 result = 0; + switch(kind) + { + case ThreadKindGUI: + result = ThreadIdGUI; + break; + case ThreadKindAudio: + result = ThreadIdAudio; + break; + case ThreadKindNotify: + result = ThreadIdNotify; + break; + case ThreadKindWatchdir: + result = ThreadIdWatchdir; + break; + } + return result; +} + #endif // MPT_OS_WINDOWS } // namespace Trace diff --git a/Frameworks/OpenMPT/OpenMPT/common/Logging.h b/Frameworks/OpenMPT/OpenMPT/common/Logging.h index 9c96f9270..86abd6da7 100644 --- a/Frameworks/OpenMPT/OpenMPT/common/Logging.h +++ b/Frameworks/OpenMPT/OpenMPT/common/Logging.h @@ -235,12 +235,14 @@ enum ThreadKind { ThreadKindGUI, ThreadKindAudio, ThreadKindNotify, + ThreadKindWatchdir, }; void Enable(std::size_t numEntries); void Disable(); void SetThreadId(mpt::log::Trace::ThreadKind kind, uint32 id); +uint32 GetThreadId(mpt::log::Trace::ThreadKind kind); void Seal(); bool Dump(const mpt::PathString &filename); diff --git a/Frameworks/OpenMPT/OpenMPT/common/mptRandom.cpp b/Frameworks/OpenMPT/OpenMPT/common/mptRandom.cpp index 5689a4ead..f074bbab9 100644 --- a/Frameworks/OpenMPT/OpenMPT/common/mptRandom.cpp +++ b/Frameworks/OpenMPT/OpenMPT/common/mptRandom.cpp @@ -305,7 +305,7 @@ mpt::random_device & global_random_device() mpt::thread_safe_prng & global_prng() { - static mpt::thread_safe_prng g_best_prng(global_random_device()); + static mpt::thread_safe_prng g_best_prng(mpt::make_prng(global_random_device())); return g_best_prng; } diff --git a/Frameworks/OpenMPT/OpenMPT/common/versionNumber.h b/Frameworks/OpenMPT/OpenMPT/common/versionNumber.h index 7912a0230..e44e344a7 100644 --- a/Frameworks/OpenMPT/OpenMPT/common/versionNumber.h +++ b/Frameworks/OpenMPT/OpenMPT/common/versionNumber.h @@ -18,7 +18,7 @@ OPENMPT_NAMESPACE_BEGIN //Version definitions. The only thing that needs to be changed when changing version number. #define VER_MAJORMAJOR 1 #define VER_MAJOR 27 -#define VER_MINOR 07 +#define VER_MINOR 08 #define VER_MINORMINOR 02 //Version string. For example "1.17.02.28" diff --git a/Frameworks/OpenMPT/OpenMPT/libopenmpt/dox/changelog.md b/Frameworks/OpenMPT/OpenMPT/libopenmpt/dox/changelog.md index 6ec40f7e6..e3c1626bd 100644 --- a/Frameworks/OpenMPT/OpenMPT/libopenmpt/dox/changelog.md +++ b/Frameworks/OpenMPT/OpenMPT/libopenmpt/dox/changelog.md @@ -5,6 +5,17 @@ Changelog {#changelog} For fully detailed change log, please see the source repository directly. This is just a high-level summary. +### libopenmpt 0.3.10 (2018-06-17) + + * [**Bug**] Internal mixer state was not initialized properly when initially + rendering in 44100kHz stereo format. + * [**Bug**] AMF: Undefined behaviour in loader code could lead to files + playing silent. + + * Switching between instruments with portamento did not update the NNA + settings for the new instrument. + * FAR: Properly import volume commands. + ### libopenmpt 0.3.9 (2018-04-29) * [**Sec**] Possible write near address 0 in out-of-memory situations when diff --git a/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_impl.cpp b/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_impl.cpp index 3dc621b5f..1e953f77c 100644 --- a/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_impl.cpp +++ b/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_impl.cpp @@ -415,11 +415,14 @@ void module_impl::apply_mixer_settings( std::int32_t samplerate, int channels ) mixersettings.SetVolumeRampUpMicroseconds( volrampin_us ); mixersettings.SetVolumeRampDownMicroseconds( volrampout_us ); m_sndFile->SetMixerSettings( mixersettings ); + } else if ( !m_mixer_initialized ) { + m_sndFile->InitPlayer( true ); } if ( samplerate_changed ) { m_sndFile->SuspendPlugins(); m_sndFile->ResumePlugins(); } + m_mixer_initialized = true; } void module_impl::apply_libopenmpt_defaults() { set_render_param( module::RENDER_STEREOSEPARATION_PERCENT, 100 ); @@ -447,6 +450,7 @@ bool module_impl::has_subsongs_inited() const { void module_impl::ctor( const std::map< std::string, std::string > & ctls ) { m_sndFile = mpt::make_unique(); m_loaded = false; + m_mixer_initialized = false; m_Dither = mpt::make_unique(mpt::global_prng()); m_LogForwarder = mpt::make_unique( *m_Log ); m_sndFile->SetCustomLog( m_LogForwarder.get() ); diff --git a/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_impl.hpp b/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_impl.hpp index 0cf6569c1..bec492ba0 100644 --- a/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_impl.hpp +++ b/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_impl.hpp @@ -87,6 +87,7 @@ protected: double m_currentPositionSeconds; std::unique_ptr m_sndFile; bool m_loaded; + bool m_mixer_initialized; std::unique_ptr m_Dither; subsongs_type m_subsongs; float m_Gain; diff --git a/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_version.h b/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_version.h index bc19d8ad8..ef6234a40 100644 --- a/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_version.h +++ b/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_version.h @@ -19,7 +19,7 @@ /*! \brief libopenmpt minor version number */ #define OPENMPT_API_VERSION_MINOR 3 /*! \brief libopenmpt patch version number */ -#define OPENMPT_API_VERSION_PATCH 9 +#define OPENMPT_API_VERSION_PATCH 10 /*! \brief libopenmpt pre-release tag */ #define OPENMPT_API_VERSION_PREREL "" /*! \brief libopenmpt pre-release flag */ diff --git a/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_version.mk b/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_version.mk index c3cf17391..299e7e059 100644 --- a/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_version.mk +++ b/Frameworks/OpenMPT/OpenMPT/libopenmpt/libopenmpt_version.mk @@ -1,8 +1,8 @@ LIBOPENMPT_VERSION_MAJOR=0 LIBOPENMPT_VERSION_MINOR=3 -LIBOPENMPT_VERSION_PATCH=9 +LIBOPENMPT_VERSION_PATCH=10 LIBOPENMPT_VERSION_PREREL= LIBOPENMPT_LTVER_CURRENT=1 -LIBOPENMPT_LTVER_REVISION=9 +LIBOPENMPT_LTVER_REVISION=10 LIBOPENMPT_LTVER_AGE=1 diff --git a/Frameworks/OpenMPT/OpenMPT/openmpt123/openmpt123.cpp b/Frameworks/OpenMPT/OpenMPT/openmpt123/openmpt123.cpp index c4d216006..5d9d82d7e 100644 --- a/Frameworks/OpenMPT/OpenMPT/openmpt123/openmpt123.cpp +++ b/Frameworks/OpenMPT/OpenMPT/openmpt123/openmpt123.cpp @@ -888,10 +888,16 @@ static const char * const channel_tags[4][4] = { }; static std::string channel_to_string( int channels, int channel, const meter_channel & meter, bool tiny = false ) { - float db = 20.0f * std::log10( meter.peak ); - float db_hold = 20.0f * std::log10( meter.hold ); - int val = static_cast( db + 48.0f ); - int hold_pos = static_cast( db_hold + 48.0f ); + int val = std::numeric_limits::min(); + int hold_pos = std::numeric_limits::min(); + if ( meter.peak > 0.0f ) { + float db = 20.0f * std::log10( meter.peak ); + val = static_cast( db + 48.0f ); + } + if ( meter.hold > 0.0f ) { + float db_hold = 20.0f * std::log10( meter.hold ); + hold_pos = static_cast( db_hold + 48.0f ); + } if ( val < 0 ) { val = 0; } @@ -911,13 +917,13 @@ static std::string channel_to_string( int channels, int channel, const meter_cha headroom = 0; } if ( tiny ) { - if ( meter.clip != 0.0f || db >= 0.0f ) { + if ( meter.clip != 0.0f || meter.peak >= 1.0f ) { return "#"; - } else if ( db > -6.0f ) { + } else if ( meter.peak > std::pow( 10.0f, -6.0f / 20.0f ) ) { return "O"; - } else if ( db > -12.0f ) { + } else if ( meter.peak > std::pow( 10.0f, -12.0f / 20.0f ) ) { return "o"; - } else if ( db > -18.0f ) { + } else if ( meter.peak > std::pow( 10.0f, -18.0f / 20.0f ) ) { return "."; } else { return " "; diff --git a/Frameworks/OpenMPT/OpenMPT/sounddsp/Reverb.cpp b/Frameworks/OpenMPT/OpenMPT/sounddsp/Reverb.cpp index 89f24831b..ce7817fd9 100644 --- a/Frameworks/OpenMPT/OpenMPT/sounddsp/Reverb.cpp +++ b/Frameworks/OpenMPT/OpenMPT/sounddsp/Reverb.cpp @@ -64,6 +64,8 @@ CReverbSettings::CReverbSettings() CReverb::CReverb() { + m_currentPreset = nullptr; + // Shared reverb state InitMixBuffer(MixReverbBuffer, static_cast(mpt::size(MixReverbBuffer))); gnRvbROfsVol = 0; @@ -326,18 +328,17 @@ void CReverb::Shutdown() void CReverb::Initialize(bool bReset, uint32 MixingFreq) { if (m_Settings.m_nReverbType >= NUM_REVERBTYPES) m_Settings.m_nReverbType = 0; - static SNDMIX_REVERB_PROPERTIES *spCurrentPreset = nullptr; - SNDMIX_REVERB_PROPERTIES *pRvbPreset = &gRvbPresets[m_Settings.m_nReverbType].Preset; + const SNDMIX_REVERB_PROPERTIES *rvbPreset = &gRvbPresets[m_Settings.m_nReverbType].Preset; - if ((pRvbPreset != spCurrentPreset) || (bReset)) + if ((rvbPreset != m_currentPreset) || (bReset)) { // Reverb output frequency is half of the dry output rate float flOutputFrequency = (float)MixingFreq; EnvironmentReverb rvb; // Reset reverb parameters - spCurrentPreset = pRvbPreset; - I3dl2_to_Generic(pRvbPreset, &rvb, flOutputFrequency, + m_currentPreset = rvbPreset; + I3dl2_to_Generic(rvbPreset, &rvb, flOutputFrequency, RVBMINREFDELAY, RVBMAXREFDELAY, RVBMINRVBDELAY, RVBMAXRVBDELAY, ( RVBDIF1L_LEN + RVBDIF1R_LEN diff --git a/Frameworks/OpenMPT/OpenMPT/sounddsp/Reverb.h b/Frameworks/OpenMPT/OpenMPT/sounddsp/Reverb.h index d018a9d7e..1b4c08da6 100644 --- a/Frameworks/OpenMPT/OpenMPT/sounddsp/Reverb.h +++ b/Frameworks/OpenMPT/OpenMPT/sounddsp/Reverb.h @@ -59,6 +59,8 @@ struct SWRvbRefDelay LR16 RefOut[SNDMIX_REVERB_DELAY_MASK + 1]; // stereo output of reflections }; +struct SNDMIX_REVERB_PROPERTIES; + // Late reverberation // Tank diffusers lengths @@ -145,6 +147,7 @@ public: mixsample_t gnRvbROfsVol, gnRvbLOfsVol; private: + const SNDMIX_REVERB_PROPERTIES *m_currentPreset; uint32 gnReverbSend; diff --git a/Frameworks/OpenMPT/OpenMPT/soundlib/Load_amf.cpp b/Frameworks/OpenMPT/OpenMPT/soundlib/Load_amf.cpp index 53c1f27da..9760d22fc 100644 --- a/Frameworks/OpenMPT/OpenMPT/soundlib/Load_amf.cpp +++ b/Frameworks/OpenMPT/OpenMPT/soundlib/Load_amf.cpp @@ -574,8 +574,9 @@ bool CSoundFile::ReadAMF_DSMI(FileReader &file, ModLoadingFlags loadFlags) for(uint16 i = 0; i < trackCount; i++) { // Track size is a 24-Bit value describing the number of byte triplets in this track. - uint32 trackSize = file.ReadUint16LE() | (file.ReadUint8() << 16); - trackData[i] = file.ReadChunk(trackSize * 3); + uint8 trackSize[3]; + file.ReadArray(trackSize); + trackData[i] = file.ReadChunk((trackSize[0] | (trackSize[1] << 8) | (trackSize[2] << 16)) * 3); } if(loadFlags & loadSampleData) diff --git a/Frameworks/OpenMPT/OpenMPT/soundlib/Load_far.cpp b/Frameworks/OpenMPT/OpenMPT/soundlib/Load_far.cpp index b6e4b3d5f..d7425a188 100644 --- a/Frameworks/OpenMPT/OpenMPT/soundlib/Load_far.cpp +++ b/Frameworks/OpenMPT/OpenMPT/soundlib/Load_far.cpp @@ -234,7 +234,7 @@ bool CSoundFile::ReadFAR(FileReader &file, ModLoadingFlags loadFlags) continue; } - // Read break row and unused value + // Read break row and unused value (used to be pattern tempo) ROWINDEX breakRow = patternChunk.ReadUint8(); patternChunk.Skip(1); if(breakRow > 0 && breakRow < numRows - 2) @@ -262,10 +262,10 @@ bool CSoundFile::ReadFAR(FileReader &file, ModLoadingFlags loadFlags) m.instr = data[1] + 1; } - if(data[2] & 0x0F) + if(m.note != NOTE_NONE || data[2] > 0) { m.volcmd = VOLCMD_VOLUME; - m.vol = (data[2] & 0x0F) << 2; + m.vol = (Clamp(data[2], uint8(1), uint8(16)) - 1u) * 4u; } m.param = data[3] & 0x0F; diff --git a/Frameworks/OpenMPT/OpenMPT/soundlib/Load_mid.cpp b/Frameworks/OpenMPT/OpenMPT/soundlib/Load_mid.cpp index 0ffeecade..d94fb8cfc 100644 --- a/Frameworks/OpenMPT/OpenMPT/soundlib/Load_mid.cpp +++ b/Frameworks/OpenMPT/OpenMPT/soundlib/Load_mid.cpp @@ -1083,7 +1083,7 @@ bool CSoundFile::ReadMID(FileReader &file, ModLoadingFlags loadFlags) chn = 9; else if(chn < 10) chn--; - drumChns.set(chn, xg[7] != 0); + drumChns.set(chn, sysex.ReadUint8() != 0); } } } diff --git a/Frameworks/OpenMPT/OpenMPT/soundlib/Load_psm.cpp b/Frameworks/OpenMPT/OpenMPT/soundlib/Load_psm.cpp index 31d68a0b5..e284f7fdd 100644 --- a/Frameworks/OpenMPT/OpenMPT/soundlib/Load_psm.cpp +++ b/Frameworks/OpenMPT/OpenMPT/soundlib/Load_psm.cpp @@ -435,11 +435,15 @@ bool CSoundFile::ReadPSM(FileReader &file, ModLoadingFlags loadFlags) // Output of PLAY.EXE: "SMapTabl from pos 0 to pos -1 starting at 0 and adding 1 to it each time" // It appears that this maps e.g. what is "I0" in the file to sample 1. // If we were being fancy, we could implement this, but in practice it won't matter. - if (subChunk.ReadUint8() != 0x00 || subChunk.ReadUint8() != 0xFF || // "0 to -1" (does not seem to do anything) - subChunk.ReadUint8() != 0x00 || subChunk.ReadUint8() != 0x00 || // "at 0" (actually this appears to be the adding part - changing this to 0x01 0x00 offsets all samples by 1) - subChunk.ReadUint8() != 0x01 || subChunk.ReadUint8() != 0x00) // "adding 1" (does not seem to do anything) { - return false; + uint8 mapTable[6]; + if(!subChunk.ReadArray(mapTable) + || mapTable[0] != 0x00 || mapTable[1] != 0xFF // "0 to -1" (does not seem to do anything) + || mapTable[2] != 0x00 || mapTable[3] != 0x00 // "at 0" (actually this appears to be the adding part - changing this to 0x01 0x00 offsets all samples by 1) + || mapTable[4] != 0x01 || mapTable[5] != 0x00) // "adding 1" (does not seem to do anything) + { + return false; + } } break; diff --git a/Frameworks/OpenMPT/OpenMPT/soundlib/Load_s3m.cpp b/Frameworks/OpenMPT/OpenMPT/soundlib/Load_s3m.cpp index 563f48f72..07c329965 100644 --- a/Frameworks/OpenMPT/OpenMPT/soundlib/Load_s3m.cpp +++ b/Frameworks/OpenMPT/OpenMPT/soundlib/Load_s3m.cpp @@ -439,7 +439,7 @@ bool CSoundFile::ReadS3M(FileReader &file, ModLoadingFlags loadFlags) if(hasAdlibPatches) { - AddToLog("This track uses Adlib instruments, which are not supported by OpenMPT."); + AddToLog("This track uses Adlib instruments, which are not supported by this version of OpenMPT."); } diff --git a/Frameworks/OpenMPT/OpenMPT/soundlib/SampleFormatMediaFoundation.cpp b/Frameworks/OpenMPT/OpenMPT/soundlib/SampleFormatMediaFoundation.cpp index ad1e0765a..b97d053a6 100644 --- a/Frameworks/OpenMPT/OpenMPT/soundlib/SampleFormatMediaFoundation.cpp +++ b/Frameworks/OpenMPT/OpenMPT/soundlib/SampleFormatMediaFoundation.cpp @@ -454,6 +454,12 @@ bool CSoundFile::ReadMediaFoundationSample(SAMPLEINDEX sample, FileReader &file, result = true; + if(!mo3Decode) + { + Samples[sample].Convert(MOD_TYPE_IT, GetType()); + Samples[sample].PrecomputeLoops(*this, false); + } + fail: mptMFSafeRelease(&buffer); diff --git a/Frameworks/OpenMPT/OpenMPT/soundlib/SampleFormats.cpp b/Frameworks/OpenMPT/OpenMPT/soundlib/SampleFormats.cpp index 40abe0fa3..29fe7a58c 100644 --- a/Frameworks/OpenMPT/OpenMPT/soundlib/SampleFormats.cpp +++ b/Frameworks/OpenMPT/OpenMPT/soundlib/SampleFormats.cpp @@ -254,7 +254,7 @@ bool CSoundFile::ReadInstrumentFromSong(INSTRUMENTINDEX targetInstr, const CSoun } #ifdef MODPLUG_TRACKER - if(!strcmp(pIns->filename, "") && srcSong.GetpModDoc() != nullptr) + if(!strcmp(pIns->filename, "") && srcSong.GetpModDoc() != nullptr && &srcSong != this) { mpt::String::Copy(pIns->filename, srcSong.GetpModDoc()->GetPathNameMpt().GetFullFileName().ToLocale()); } @@ -307,7 +307,7 @@ bool CSoundFile::ReadSampleFromSong(SAMPLEINDEX targetSample, const CSoundFile & } #ifdef MODPLUG_TRACKER - if(!strcmp(targetSmp.filename, "") && srcSong.GetpModDoc() != nullptr) + if(!strcmp(targetSmp.filename, "") && srcSong.GetpModDoc() != nullptr && &srcSong != this) { mpt::String::Copy(targetSmp.filename, mpt::ToCharset(GetCharsetInternal(), srcSong.GetpModDoc()->GetTitle())); } @@ -446,7 +446,11 @@ bool CSoundFile::ReadWAVSample(SAMPLEINDEX nSample, FileReader &file, bool mayNo } else if(wavFile.GetSampleFormat() == WAVFormatChunk::fmtMP3) { // MP3 in WAV - return ReadMP3Sample(nSample, sampleChunk, true) || ReadMediaFoundationSample(nSample, sampleChunk, true); + bool loadedMP3 = ReadMP3Sample(nSample, sampleChunk, true) || ReadMediaFoundationSample(nSample, sampleChunk, true); + if(!loadedMP3) + { + return false; + } } else if(!wavFile.IsExtensibleFormat() && wavFile.MayBeCoolEdit16_8() && wavFile.GetSampleFormat() == WAVFormatChunk::fmtPCM && wavFile.GetBitsPerSample() == 32 && wavFile.GetBlockAlign() == wavFile.GetNumChannels() * 4) { // Syntrillium Cool Edit hack to store IEEE 32bit floating point diff --git a/Frameworks/OpenMPT/OpenMPT/soundlib/Snd_fx.cpp b/Frameworks/OpenMPT/OpenMPT/soundlib/Snd_fx.cpp index 09a47abd9..e22d043c9 100644 --- a/Frameworks/OpenMPT/OpenMPT/soundlib/Snd_fx.cpp +++ b/Frameworks/OpenMPT/OpenMPT/soundlib/Snd_fx.cpp @@ -1416,7 +1416,7 @@ void CSoundFile::InstrumentChange(ModChannel *pChn, uint32 instr, bool bPorta, b pChn->nNewIns = 0; // IT Compatiblity: NNA is reset on every note change, not every instrument change (fixes s7xinsnum.it). - if (pIns && ((!m_playBehaviour[kITNNAReset] && pSmp) || pIns->nMixPlug)) + if (pIns && ((!m_playBehaviour[kITNNAReset] && pSmp) || pIns->nMixPlug || instrumentChanged)) pChn->nNNA = pIns->nNNA; // Update volume @@ -2778,7 +2778,7 @@ bool CSoundFile::ProcessEffects() InstrumentChange(pChn, pChn->nNewIns, bPorta, false, !(GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))); pChn->nNewIns = 0; } - NoteChange(pChn, note, bPorta, !(GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))); + NoteChange(pChn, note, bPorta, !(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2))); if ((bPorta) && (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)) && (instr)) { pChn->dwFlags.set(CHN_FASTVOLRAMP);