From: <sv...@op...> - 2024-05-31 19:35:23
|
Author: sagamusix Date: Fri May 31 21:35:16 2024 New Revision: 20887 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=20887 Log: [Fix] FTM: Don't import as IT, as that will always cause lone instrument numbers to retrigger stopped samples. Instead we import as MOD with linear pitch slides (as weird as it may sound ;). [Fix] Apply frequency frequency limit to instrument scripts. They are evaluted after the regular period limits are applied. Modified: trunk/OpenMPT/soundlib/InstrumentSynth.cpp trunk/OpenMPT/soundlib/Load_ftm.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp Modified: trunk/OpenMPT/soundlib/InstrumentSynth.cpp ============================================================================== --- trunk/OpenMPT/soundlib/InstrumentSynth.cpp Fri May 31 20:40:32 2024 (r20886) +++ trunk/OpenMPT/soundlib/InstrumentSynth.cpp Fri May 31 21:35:16 2024 (r20887) @@ -30,6 +30,7 @@ int16 m_volumeAdd = int16_min; uint16 m_panning = 2048; int16 m_linearPitchFactor = 0; + int16 m_periodFreqSlide = 0; int16 m_periodAdd = 0; uint16 m_loopCount = 0; bool m_condition = false; @@ -110,10 +111,11 @@ } -static int32 TranslateFTMPitch(uint16 pitch, const ModChannel &chn, const CSoundFile &sndFile) +static int32 TranslateFTMPitch(uint16 pitch, ModChannel &chn, const CSoundFile &sndFile) { int32 period = sndFile.GetPeriodFromNote(NOTE_MIDDLEC - 12 + pitch / 16, chn.nFineTune, chn.nC5Speed); - return ApplyLinearPitchSlide(period, pitch % 16, sndFile.PeriodsAreFrequencies()); + sndFile.DoFreqSlide(chn, period, (pitch % 16) * 4); + return period; } @@ -211,6 +213,7 @@ if(events.empty()) return; + const CHANNELINDEX origChannel = channel; channel = FTMRealChannel(channel, sndFile); ModChannel *chn = &playState.Chn[channel]; @@ -283,11 +286,9 @@ if(jumpCount++ > 10) break; } - if(m_ftmWorkTrack) - { - channel = FTMRealChannel(channel, sndFile); - chn = &playState.Chn[channel]; - } + + channel = FTMRealChannel(origChannel, sndFile); + chn = &playState.Chn[channel]; } } } @@ -373,7 +374,7 @@ case 0x70: m_ftmLFO[2].depth = static_cast<uint8>(value / 64); break; case 0x80: m_ftmLFO[3].depth = static_cast<uint8>(value / 64); break; case 0xA0: m_volumeAdd = mpt::saturate_cast<int16>(value * 4); break; - case 0xF0: m_linearPitchFactor = static_cast<int16>(value / 32); break; + case 0xF0: m_periodFreqSlide = static_cast<int16>(value / 8); break; } uint16 newPos = lfo.position + lfo.speed; @@ -411,10 +412,20 @@ const bool periodsAreFrequencies = sndFile.PeriodsAreFrequencies(); if(m_linearPitchFactor != 0) period = ApplyLinearPitchSlide(period, m_linearPitchFactor, periodsAreFrequencies); + if(m_periodFreqSlide != 0) + sndFile.DoFreqSlide(chn, period, m_periodFreqSlide); if(periodsAreFrequencies) period -= m_periodAdd; else period += m_periodAdd; + + if((m_linearPitchFactor || m_periodFreqSlide || m_periodAdd) && !sndFile.PeriodsAreFrequencies()) + { + if(period < sndFile.m_nMinPeriod) + period = sndFile.m_nMinPeriod; + else if(period > sndFile.m_nMaxPeriod && sndFile.m_playBehaviour[kApplyUpperPeriodLimit]) + period = sndFile.m_nMaxPeriod; + } if(period < 1) period = 1; @@ -618,8 +629,9 @@ case Event::Type::FTM_SetCondition: { - const int32 threshold = (event.u8 < 3) ? TranslateFTMPitch(event.u16, chn, sndFile) : event.u16; - const int32 compare = (event.u8 < 3) ? chn.nPeriod : chn.nGlobalVol; + MPT_ASSERT(!sndFile.PeriodsAreFrequencies()); + const int32 threshold = (event.u8 < 3) ? int32_max - TranslateFTMPitch(event.u16, chn, sndFile) : event.u16; + const int32 compare = (event.u8 < 3) ? int32_max - chn.nPeriod : chn.nGlobalVol; switch(event.u8 % 3u) { case 0: m_condition = (compare == threshold); break; @@ -665,7 +677,7 @@ case Event::Type::FTM_AddPitch: if(event.i16) { - chn.nPeriod = ApplyLinearPitchSlide(chn.nPeriod, event.i16 * 2, sndFile.PeriodsAreFrequencies()); + sndFile.DoFreqSlide(chn, chn.nPeriod, event.i16 * 8); const int32 limit = TranslateFTMPitch((event.i16 < 0) ? 0 : 0x21E, chn, sndFile); if((event.i16 > 0) == sndFile.PeriodsAreFrequencies()) chn.nPeriod = std::min(chn.nPeriod, limit); Modified: trunk/OpenMPT/soundlib/Load_ftm.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_ftm.cpp Fri May 31 20:40:32 2024 (r20886) +++ trunk/OpenMPT/soundlib/Load_ftm.cpp Fri May 31 21:35:16 2024 (r20887) @@ -102,7 +102,7 @@ else if(loadFlags == onlyVerifyHeader) return true; - InitializeGlobals(MOD_TYPE_IT); + InitializeGlobals(MOD_TYPE_MOD); m_nChannels = 8; InitializeChannels(); for(CHANNELINDEX chn = 0; chn < 8; chn++) @@ -113,7 +113,7 @@ m_SongFlags.set(SONG_LINEARSLIDES | SONG_ISAMIGA | SONG_IMPORTED); m_playBehaviour.set(kContinueSampleWithoutInstr); m_playBehaviour.set(kST3NoMutedChannels); - m_playBehaviour.reset(kITInitialNoteMemory); + m_playBehaviour.set(kApplyUpperPeriodLimit); Order().SetDefaultSpeed(fileHeader.ticksPerRow); Order().SetDefaultTempo(TEMPO(1766278.163 / fileHeader.tempo)); m_nDefaultRowsPerMeasure = fileHeader.rowsPerMeasure; @@ -122,8 +122,8 @@ else m_nDefaultRowsPerBeat = m_nDefaultRowsPerMeasure / 4; m_nDefaultGlobalVolume = Util::muldivr_unsigned(fileHeader.globalVolume, MAX_GLOBAL_VOLUME, 63); - m_nMinPeriod = 113 * 4; - m_nMaxPeriod = 856 * 4; + m_nMinPeriod = 3208; + m_nMaxPeriod = 5172; const bool moduleWithSamples = (fileHeader.flags & 0x01); m_modFormat.formatName = U_("Face The Music"); Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp Fri May 31 20:40:32 2024 (r20886) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp Fri May 31 21:35:16 2024 (r20887) @@ -6115,28 +6115,33 @@ } else if(GetType() == MOD_TYPE_FAR) { period += (amount * 36318 / 1024); - } else if(m_SongFlags[SONG_LINEARSLIDES] && GetType() != MOD_TYPE_XM) + } else if(m_SongFlags[SONG_LINEARSLIDES] && !(GetType() & (MOD_TYPE_XM | MOD_TYPE_MOD))) { // IT Linear slides const auto oldPeriod = period; - uint32 n = std::abs(amount); - LimitMax(n, 255u * 4u); + uint32 absAmount = std::abs(amount); // Note: IT ignores the lower 2 bits when abs(mount) > 16 (it either uses the fine *or* the regular table, not both) // This means that vibratos are slightly less accurate in this range than they could be. // Other code paths will *either* have an amount that's a multiple of 4 *or* it's less than 16. - if(amount > 0) + if(absAmount < 16) { - if(n < 16) - period = Util::muldivr(period, GetFineLinearSlideUpTable(this, n), 65536); + if(amount > 0) + period = Util::muldivr(period, GetFineLinearSlideUpTable(this, absAmount), 65536); else - period = Util::muldivr(period, GetLinearSlideUpTable(this, n / 4u), 65536); + period = Util::muldivr(period, GetFineLinearSlideDownTable(this, absAmount), 65536); } else { - if(n < 16) - period = Util::muldivr(period, GetFineLinearSlideDownTable(this, n), 65536); - else - period = Util::muldivr(period, GetLinearSlideDownTable(this, n / 4u), 65536); + absAmount /= 4u; + while(absAmount > 0) + { + const uint32 n = std::min(absAmount, static_cast<uint32>(std::size(LinearSlideUpTable) - 1)); + if(amount > 0) + period = Util::muldivr(period, GetLinearSlideUpTable(this, n), 65536); + else + period = Util::muldivr(period, GetLinearSlideDownTable(this, n), 65536); + absAmount -= n; + } } if(period == oldPeriod) @@ -6524,7 +6529,7 @@ return Util::muldiv_unsigned(8363, (FreqS3MTable[note % 12u] << 5), nC5Speed << (note / 12u)); //8363 * freq[note%12] / nC5Speed * 2^(5-note/12) } - } else if(GetType() & (MOD_TYPE_XM | MOD_TYPE_MTM)) + } else if((GetType() & (MOD_TYPE_XM | MOD_TYPE_MTM)) || m_SongFlags[SONG_LINEARSLIDES]) { if (note < 12) note = 12; note -= 12; @@ -6582,7 +6587,7 @@ uint32 CSoundFile::GetFreqFromPeriod(uint32 period, uint32 c5speed, int32 nPeriodFrac) const { if (!period) return 0; - if (GetType() & (MOD_TYPE_XM | MOD_TYPE_MTM)) + if ((GetType() & (MOD_TYPE_XM | MOD_TYPE_MTM)) || (m_SongFlags[SONG_LINEARSLIDES] && UseFinetuneAndTranspose())) { if(m_playBehaviour[kFT2Periods]) { |