From: <sv...@op...> - 2025-04-18 13:14:28
|
Author: sagamusix Date: Fri Apr 18 15:14:05 2025 New Revision: 23142 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=23142 Log: Merged revision(s) 23128-23132, 23141 from trunk/OpenMPT: [Mod] FLAC: Store a zero-length loop in WAV metadata when only a sustain loop is present, similar to how the WAV writer does it. This way, we can distinguish it from a normal sample loop. ........ [Imp] MOD: Identify modules saved with TakeTracker. ........ [Mod] MOD: The last three bytes of the Tetramed tag can vary. Check that they are present but don't verify their contents. ........ [Fix] Compile fix. ........ [Mod] Sample tab: When adjusting sample offsets after resampling, round the result and never set it to 0, as that would just recall the previous offset. Also don't do any adjustments for relative offset commands - it's an unnecessary calculation as they should stay identical. ........ [Mod] XM: Allow to use 128 channels in XM files, as MilkyTracker can write such files as well (https://bugs.openmpt.org/view.php?id=1877). ........ Modified: branches/OpenMPT-1.32/ (props changed) branches/OpenMPT-1.32/soundlib/Load_mod.cpp branches/OpenMPT-1.32/soundlib/SampleFormatFLAC.cpp branches/OpenMPT-1.32/soundlib/mod_specifications.cpp branches/OpenMPT-1.32/tracklib/SampleEdit.cpp Modified: branches/OpenMPT-1.32/soundlib/Load_mod.cpp ============================================================================== --- branches/OpenMPT-1.32/soundlib/Load_mod.cpp Fri Apr 18 15:10:05 2025 (r23141) +++ branches/OpenMPT-1.32/soundlib/Load_mod.cpp Fri Apr 18 15:14:05 2025 (r23142) @@ -697,7 +697,10 @@ file.Seek(nextSample); } } - if(isMdKd && file.ReadArray<char, 9>() == std::array<char, 9>{0x00, 0x11, 0x55, 0x33, 0x22, 0x11, 0x04, 0x01, 0x01}) + // XOR with 0xDF gives the message "TakeTrackered with version 0.9E!!!!!" + if(GetNumChannels() <= 16 && file.ReadMagic("\x8B\xBE\xB4\xBA\x8B\xAD\xBE\xBC\xB4\xBA\xAD\xBA\xBB\xFF\xA8\xB6\xAB\xB7\xFF\xA9\xBA\xAD\xAC\xB6\xB0\xB1\xFF\xEF\xF1\xE6\xBA\xFE\xFE\xFE\xFE\xFE")) + modMagicResult.madeWithTracker = UL_("TakeTracker"); + else if(isMdKd && file.ReadArray<char, 6>() == std::array<char, 6>{0x00, 0x11, 0x55, 0x33, 0x22, 0x11} && file.CanRead(3)) // 3 more bytes that differ between modules and Tetramed version, purpose unknown modMagicResult.madeWithTracker = UL_("Tetramed"); } Modified: branches/OpenMPT-1.32/soundlib/SampleFormatFLAC.cpp ============================================================================== --- branches/OpenMPT-1.32/soundlib/SampleFormatFLAC.cpp Fri Apr 18 15:10:05 2025 (r23141) +++ branches/OpenMPT-1.32/soundlib/SampleFormatFLAC.cpp Fri Apr 18 15:14:05 2025 (r23142) @@ -644,6 +644,11 @@ { chunk.loops[chunk.info.numLoops++].ConvertToWAV(sample.nLoopStart, sample.nLoopEnd, sample.uFlags[CHN_PINGPONGLOOP]); chunk.header.length += sizeof(WAVSampleLoop); + } else if(sample.uFlags[CHN_SUSTAINLOOP]) + { + // Invent zero-length loop to distinguish sustain loop from normal loop + chunk.loops[chunk.info.numLoops++].ConvertToWAV(0, 0, false); + chunk.header.length += sizeof(WAVSampleLoop); } const uint32 length = sizeof(RIFFChunk) + chunk.header.length; Modified: branches/OpenMPT-1.32/soundlib/mod_specifications.cpp ============================================================================== --- branches/OpenMPT-1.32/soundlib/mod_specifications.cpp Fri Apr 18 15:10:05 2025 (r23141) +++ branches/OpenMPT-1.32/soundlib/mod_specifications.cpp Fri Apr 18 15:14:05 2025 (r23142) @@ -176,7 +176,7 @@ 255, // Order max. 1, // Only one order list 1, // Channel min - 127, // Channel max + 128, // Channel max 32, // Min tempo 1000, // Max tempo 1, // Min Speed Modified: branches/OpenMPT-1.32/tracklib/SampleEdit.cpp ============================================================================== --- branches/OpenMPT-1.32/tracklib/SampleEdit.cpp Fri Apr 18 15:10:05 2025 (r23141) +++ branches/OpenMPT-1.32/tracklib/SampleEdit.cpp Fri Apr 18 15:14:05 2025 (r23142) @@ -1019,15 +1019,19 @@ { sndFile.Patterns.ForEachModCommand([&](ModCommand &m) { - if(m.command != CMD_OFFSET && m.command != CMD_REVERSEOFFSET && m.command != CMD_OFFSETPERCENTAGE) + if(m.command != CMD_OFFSET && m.command != CMD_REVERSEOFFSET) + return; + // Percentage offset is unaffected + if(m.volcmd == VOLCMD_OFFSET && m.vol == 0) + return; + // Recall last parameter + if(m.param == 0) return; if(sndFile.GetSampleIndex(m.note, m.instr) != sampleIndex) return; SmpLength point = m.param * 256u; - if(m.command == CMD_OFFSETPERCENTAGE || (m.volcmd == VOLCMD_OFFSET && m.vol == 0)) - point = Util::muldivr_unsigned(point, oldLength, 65536); - else if(m.volcmd == VOLCMD_OFFSET && m.vol <= std::size(oldCues)) + if(m.volcmd == VOLCMD_OFFSET && m.vol <= oldCues.size()) point += oldCues[m.vol - 1]; if(point >= oldLength) @@ -1038,16 +1042,19 @@ point = start + Util::muldivr_unsigned(point - start, newRate, oldRate); LimitMax(point, newTotalLength); - if(m.command == CMD_OFFSETPERCENTAGE || (m.volcmd == VOLCMD_OFFSET && m.vol == 0)) - point = Util::muldivr_unsigned(point, 65536, newTotalLength); - else if(m.volcmd == VOLCMD_OFFSET && m.vol <= std::size(smp.cues)) + if(m.volcmd == VOLCMD_OFFSET && m.vol <= smp.cues.size()) point -= smp.cues[m.vol - 1]; + + ModCommand::PARAM newParam = std::max(mpt::saturate_cast<ModCommand::PARAM>((point + 128u) / 256u), ModCommand::PARAM(1)); + if(m.param == newParam) + return; + if(!patternUndoCreated) { patternUndoCreated = true; preparePatternUndoFunc(); } - m.param = mpt::saturate_cast<ModCommand::PARAM>(point / 256u); + m.param = newParam; }); } |