From: <sv...@op...> - 2024-06-14 21:12:11
|
Author: sagamusix Date: Fri Jun 14 23:11:55 2024 New Revision: 21028 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=21028 Log: Merged revision(s) 21023, 21025-21027 from trunk/OpenMPT: [Fix] XM: oggmod doesn't know what stereo samples are. As it is difficult (if possible at all) to reconstruct the waveform of the right channel, we restrict importing of those samples as mono samples instead of not importing them at all (which is what happened until now). The stereo sample path remains present as in theory someone could write a bugfixed oggmod tool that writes proper stereo samples. ........ [Imp] DTM: Detect Digital Tracker 2.3, which is the only version writing the ProTracker-like pattern format. ........ [Fix] AMF: When running out of sample slots, file reading became be misaligned because the sample name was not skipped. ........ [Imp] IT: Detect itwriter (https://github.com/chr15m/itwriter/). ........ Modified: branches/OpenMPT-1.31/ (props changed) branches/OpenMPT-1.31/soundlib/Load_ams.cpp branches/OpenMPT-1.31/soundlib/Load_dtm.cpp branches/OpenMPT-1.31/soundlib/Load_it.cpp branches/OpenMPT-1.31/soundlib/Load_xm.cpp Modified: branches/OpenMPT-1.31/soundlib/Load_ams.cpp ============================================================================== --- branches/OpenMPT-1.31/soundlib/Load_ams.cpp Fri Jun 14 22:20:17 2024 (r21027) +++ branches/OpenMPT-1.31/soundlib/Load_ams.cpp Fri Jun 14 23:11:55 2024 (r21028) @@ -826,12 +826,12 @@ } uint8 numSamples = file.ReadUint8(); - uint8 sampleAssignment[120]; - MemsetZero(sampleAssignment); // Only really needed for v2.0, where the lowest and highest octave aren't cleared. + std::array<uint8, 120> sampleAssignment; + sampleAssignment.fill(0); // Only really needed for v2.0, where the lowest and highest octave aren't cleared. if(numSamples == 0 - || (fileHeader.versionLow > 0 && !file.ReadArray(sampleAssignment)) // v2.01+: 120 Notes - || (fileHeader.versionLow == 0 && !file.ReadRaw(mpt::span(sampleAssignment + 12, 96)).size())) // v2.0: 96 Notes + || (fileHeader.versionLow > 0 && !file.ReadArray(sampleAssignment)) // v2.01+: 120 Notes + || (fileHeader.versionLow == 0 && !file.ReadRaw(mpt::as_span(sampleAssignment).subspan(12, 96)).size())) // v2.0: 96 Notes { continue; } @@ -878,18 +878,17 @@ // Sample headers - we will have to read them even for shadow samples, and we will have to load them several times, // as it is possible that shadow samples use different sample settings like base frequency or panning. const SAMPLEINDEX firstSmp = GetNumSamples() + 1; + std::string sampleName; for(SAMPLEINDEX smp = 0; smp < numSamples; smp++) { - if(firstSmp + smp >= MAX_SAMPLES) - { - file.Skip(sizeof(AMS2SampleHeader)); - break; - } - file.ReadSizedString<uint8le, mpt::String::spacePadded>(m_szNames[firstSmp + smp]); - + file.ReadSizedString<uint8le, mpt::String::spacePadded>(sampleName); AMS2SampleHeader sampleHeader; file.ReadStruct(sampleHeader); + if(firstSmp + smp >= MAX_SAMPLES) + continue; + sampleHeader.ConvertToMPT(Samples[firstSmp + smp]); + m_szNames[firstSmp + smp] = sampleName; uint16 settings = (instrHeader.shadowInstr & instrIndexMask) | ((smp << sampleIndexShift) & sampleIndexMask) Modified: branches/OpenMPT-1.31/soundlib/Load_dtm.cpp ============================================================================== --- branches/OpenMPT-1.31/soundlib/Load_dtm.cpp Fri Jun 14 22:20:17 2024 (r21027) +++ branches/OpenMPT-1.31/soundlib/Load_dtm.cpp Fri Jun 14 23:11:55 2024 (r21028) @@ -576,6 +576,9 @@ if(patternFormat == DTM_206_PATTERN_FORMAT) { tracker = U_("Digital Home Studio"); + } else if(patternFormat == DTM_PT_PATTERN_FORMAT) + { + tracker = U_("Digital Tracker 2.3"); } else if(FileReader chunk = chunks.GetChunk(DTMChunk::idVERS)) { uint32 version = chunk.ReadUint32BE(); Modified: branches/OpenMPT-1.31/soundlib/Load_it.cpp ============================================================================== --- branches/OpenMPT-1.31/soundlib/Load_it.cpp Fri Jun 14 22:20:17 2024 (r21027) +++ branches/OpenMPT-1.31/soundlib/Load_it.cpp Fri Jun 14 23:11:55 2024 (r21028) @@ -1320,7 +1320,12 @@ madeWithTracker = MPT_UFORMAT("ITMCK {}.{}.{}")((fileHeader.cwtv >> 8) & 0x0F, (fileHeader.cwtv >> 4) & 0x0F, fileHeader.cwtv & 0x0F); break; case 0xD: - madeWithTracker = U_("spc2it"); + if(fileHeader.cwtv == 0xDAEB) + madeWithTracker = U_("spc2it"); + else if(fileHeader.cwtv == 0xD1CE) + madeWithTracker = U_("itwriter"); + else + madeWithTracker = U_("Unknown"); break; } } Modified: branches/OpenMPT-1.31/soundlib/Load_xm.cpp ============================================================================== --- branches/OpenMPT-1.31/soundlib/Load_xm.cpp Fri Jun 14 22:20:17 2024 (r21027) +++ branches/OpenMPT-1.31/soundlib/Load_xm.cpp Fri Jun 14 23:11:55 2024 (r21028) @@ -480,6 +480,13 @@ { decodedSamples = ret; LimitMax(decodedSamples, mpt::saturate_cast<long>(sample.nLength - offset)); + if(offset == 0 && channels == 1 && sample.GetNumChannels() == 2) + { + // oggmod doesn't know what stereo samples are, so it treats them as mono samples, but doesn't clear the unknown stereo flag. + // We just take the left channel in this case, as it is difficult (if possible at all) to properly reconstruct the waveform of the right channel. + // Due to XM's delta-encoding and Vorbis being a lossless codec, samples could distort easily even when the delta encoding was off by a very small amount. + sample.uFlags.reset(CHN_STEREO); + } if(decodedSamples > 0 && channels == sample.GetNumChannels()) { if(sample.uFlags[CHN_16BIT]) |