From: <sv...@op...> - 2024-04-08 21:41:08
|
Author: sagamusix Date: Mon Apr 8 23:40:51 2024 New Revision: 20538 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=20538 Log: [Mod] M15: The heuristics in r20524 were a bit too loose, also identifying some GMC files as SoundTracker modules. Tighten the song title check again to previous values, but ignore it if a sufficent amount of sample headers has "real-looking" sample names (starting with a disk name like st-01:...). Modified: trunk/OpenMPT/soundlib/Load_mod.cpp Modified: trunk/OpenMPT/soundlib/Load_mod.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_mod.cpp Mon Apr 8 21:27:35 2024 (r20537) +++ trunk/OpenMPT/soundlib/Load_mod.cpp Mon Apr 8 23:40:51 2024 (r20538) @@ -322,6 +322,11 @@ + ((loopStart > length * 2) ? 1 : 0); } + bool HasDiskName() const + { + return (!memcmp(name, "st-", 3) || !memcmp(name, "ST-", 3)) && name[5] == ':'; + } + // Suggested threshold for rejecting invalid files based on cumulated score returned by GetInvalidByteScore static constexpr uint32 INVALID_BYTE_THRESHOLD = 40; @@ -1410,15 +1415,13 @@ // However, there are quite a few SoundTracker modules in the wild with random // characters. To still be able to distguish them from other formats, we just reject // files with *too* many bogus characters. Arbitrary threshold: 48 bogus characters in total - // or more than 11 invalid characters just in the title alone (just enough to make scramble_2.mod load). - uint32 invalidChars = CountInvalidChars(fileHeaders.songname); - if(invalidChars > 11) - { - return false; - } + // or more than 5 invalid characters just in the title alone + uint32 invalidCharsInTitle = CountInvalidChars(fileHeaders.songname); + uint32 invalidChars = invalidCharsInTitle; SmpLength totalSampleLen = 0; uint8 allVolumes = 0; + uint8 diskNameCount = 0; for(SAMPLEINDEX smp = 0; smp < 15; smp++) { @@ -1429,6 +1432,8 @@ // schmokk.mod has a non-zero value here but it should not be treated as finetune if(sampleHeader.finetune != 0) invalidChars += 16; + if(sampleHeader.HasDiskName()) + diskNameCount++; // Sanity checks - invalid character count adjusted for ata.mod (MD5 937b79b54026fa73a1a4d3597c26eace, SHA1 3322ca62258adb9e0ae8e9afe6e0c29d39add874) if(invalidChars > 48 @@ -1442,6 +1447,12 @@ allVolumes |= sampleHeader.volume; } + // scramble_2.mod has a lot of garbage in the song title, but it has lots of sample names starting with st-01, so we consider those to be more important than the garbage bytes. + if(invalidCharsInTitle > 5 && diskNameCount < 4) + { + return false; + } + // Reject any files with no (or only silent) samples at all, as this might just be a random binary file (e.g. ID3 tags with tons of padding) if(totalSampleLen == 0 || allVolumes == 0) { @@ -1548,7 +1559,7 @@ totalSampleLen += mptSmp.nLength; - if(m_szNames[smp][0] && ((memcmp(m_szNames[smp].buf, "st-", 3) && memcmp(m_szNames[smp].buf, "ST-", 3)) || m_szNames[smp][5] != ':')) + if(m_szNames[smp][0] && sampleHeader.HasDiskName()) { // Ultimate Soundtracker 1.8 and D.O.C. SoundTracker IX always have sample names containing disk names. hasDiskNames = false; |