View Issue Details

IDProjectCategoryView StatusLast Update
0000749OpenMPTFile Format Supportpublic2024-04-02 20:45
ReporterRevenant Assigned ToSaga Musix  
PrioritynormalSeverityminorReproducibilityN/A
Status resolvedResolutionfixed 
Product VersionOpenMPT 1.25.04.00 / libopenmpt 0.2-beta16 (upgrade first) 
Target VersionOpenMPT 1.26.01.00 / libopenmpt 0.2-beta17 (upgrade first)Fixed in VersionOpenMPT 1.26.01.00 / libopenmpt 0.2-beta17 (upgrade first) 
Summary0000749: Specific detection of NoiseTracker modules
Description

I've been going through the ModLand collection with the latest 0.2.5787-beta16 and have noticed some "broken" NoiseTracker modules that should probably be specifically detected. The following should be correct, from what I can tell:

"M.K." with restartPos 0x78: Soundtracker v2.3 (or 2.4?) / NoiseTracker v1.0
"M.K." with valid restartPos: NoiseTracker v1.1 to 2.0

Other 4-channel magics like "M&K!" (Mahoney & Kaktus?) also apply.

Anyway, modules detected this way should have slightly different effect behavior:

Dxx - value should be ignored, same as other Soundtracker 2.x versions (I attached a couple of NT 1.x modules which play incorrectly in the current version, there are probably several others in the wild)
Fxx - values >= 0x20 not supported (nor >=0x10 in Soundtracker 2.x). Probably not important.

I'm not sure, but I assume the 31-sample Soundtracker versions also still have 120 as the default tempo (vs. 125 in NoiseTracker 1.0?) I don't know of a good way to tell the two apart though.

TagsNo tags attached.
Attached Files
protracker-examples.zip (173,723 bytes)
hmnt_examples.zip (350,943 bytes)
hmnt_finetune2.patch (2,127 bytes)   
diff --git OpenMPT/soundlib/Load_mod.cpp OpenMPT/soundlib/Load_mod.cpp
index 33c791a..0d2a93e 100644
--- OpenMPT/soundlib/Load_mod.cpp
+++ OpenMPT/soundlib/Load_mod.cpp
@@ -489,12 +489,12 @@ bool CSoundFile::ReadMod(FileReader &file, ModLoadingFlags loadFlags)
 	// Check MOD Magic
 	if(IsMagic(magic, "M.K.")		// ProTracker and compatible
 		|| IsMagic(magic, "M!K!")	// ProTracker (64+ patterns)
-		|| IsMagic(magic, "FEST")	// jobbig.mod by Mahoney
 		|| IsMagic(magic, "NSMS")	// kingdomofpleasure.mod by bee hunter
 		|| IsMagic(magic, "LARD"))	// judgement_day_gvine.mod by 4-mat
 	{
 		m_nChannels = 4;
 	} else if(IsMagic(magic, "M&K!")
+		|| IsMagic(magic, "FEST")	// "His Master's Noise" musicdisk
 		|| IsMagic(magic, "N.T."))
 	{
 		m_nChannels = 4;
@@ -550,6 +550,8 @@ bool CSoundFile::ReadMod(FileReader &file, ModLoadingFlags loadFlags)
 	const bool isFLT8 = IsMagic(magic, "FLT8") || IsMagic(magic, "EXO8");
 	// Only apply VBlank tests to M.K. (ProTracker) modules.
 	const bool isMdKd = IsMagic(magic, "M.K.");
+	// Adjust finetune values for modules saved with "His Master's Noisetracker"
+	const bool isHMNT = IsMagic(magic, "M&K!") || IsMagic(magic, "FEST");
 
 	// Reading song title
 	file.Seek(0);
@@ -563,6 +565,11 @@ bool CSoundFile::ReadMod(FileReader &file, ModLoadingFlags loadFlags)
 		MODSampleHeader sampleHeader;
 		ReadSample(file, sampleHeader, Samples[smp], m_szNames[smp]);
 
+		if (isHMNT)
+		{
+			Samples[smp].nFineTune = (int)(-(signed char)((sampleHeader.finetune)<<3));
+		}
+
 		totalSampleLen += Samples[smp].nLength;
 	}
 
@@ -641,7 +648,7 @@ bool CSoundFile::ReadMod(FileReader &file, ModLoadingFlags loadFlags)
 	//   In this case, the parameter of Dxx commands needs to be ignored.
 	// - Use the same code to find notes that would be out-of-range on Amiga.
 	// - Detect 7-bit panning.
-	bool isNoiseTracker = IsMagic(magic, "M&K!") || IsMagic(magic, "N.T.");
+	bool isNoiseTracker = IsMagic(magic, "M&K!") || IsMagic(magic, "N.T.") || IsMagic(magic, "FEST");
 	bool onlyAmigaNotes = true;
 	bool fix7BitPanning = false;
 	uint8 maxPanning = 0;	// For detecting 8xx-as-sync
hmnt_finetune2.patch (2,127 bytes)   
Dxx_fix.patch (823 bytes)   
diff --git OpenMPT/soundlib/Load_mod.cpp OpenMPT/soundlib/Load_mod.cpp
index 26e12a2..9ec936c 100644
--- OpenMPT/soundlib/Load_mod.cpp
+++ OpenMPT/soundlib/Load_mod.cpp
@@ -694,6 +694,8 @@ bool CSoundFile::ReadMod(FileReader &file, ModLoadingFlags loadFlags)
 		isNoiseTracker = isMdKd;
 		for(PATTERNINDEX pat = 0; pat < numPatterns; pat++)
 		{
+			uint16 patternBreaks = 0;
+
 			for(uint32 i = 0; i < 256; i++)
 			{
 				ModCommand m;
@@ -704,7 +706,8 @@ bool CSoundFile::ReadMod(FileReader &file, ModLoadingFlags loadFlags)
 				}
 				if((m.command > 0x06 && m.command < 0x0A)
 					|| (m.command == 0x0E && m.param > 0x01)
-					|| (m.command == 0x0F && m.param > 0x1F))
+					|| (m.command == 0x0F && m.param > 0x1F)
+					|| (m.command == 0x0D && ++patternBreaks > 1))
 				{
 					isNoiseTracker = false;
 				}
Dxx_fix.patch (823 bytes)   
Has the bug occurred in previous versions?
Tested code revision (in case you know it)

Relationships

related to 0001765 resolvedSaga Musix Upon loading a MOD file, all Dxx command details are lost 

Activities

Saga Musix

Saga Musix

2016-02-15 17:12

administrator   ~0002254

Fixed in r5935, should be up in a little while on https://buildbot.openmpt.org/builds/
NoiseTracker detection can never be perfect, so hopefully it won't break any non-NT modules.

Revenant

Revenant

2016-02-16 00:01

reporter   ~0002255

Last edited: 2016-02-16 00:02

Sounds good so far (in hindsight I should have also included 2-3song23.mod from the same musicdisk since the problem was much more obvious with that one, but it plays correctly now as well). Thanks for the fast fix!

I'm wary of labelling M.K. mods with repstart 0x7F as ScreamTracker files though, since virtually 99% of ProTracker 2/3 mods fit that description as well.

Conversely, I think it's probably a good idea to set m_madeWithTracker to "NoiseTracker" any time isNoiseTracker is true, since as far as I can tell, some/most publicly released versions of NT still used "M.K." (except for possibly His Master's Noisetracker which is a different story anyway).

Saga Musix

Saga Musix

2016-02-16 08:35

administrator   ~0002256

I'm wary of labelling M.K. mods with repstart 0x7F as ScreamTracker files though, since virtually 99% of ProTracker 2/3 mods fit that description as well.

I haven't ever seen that, got an example where you know it was written in with ProTracker? xmp uses the same heuristic.

Conversely, I think it's probably a good idea to set m_madeWithTracker to "NoiseTracker" any time isNoiseTracker is true, since as far as I can tell, some/most publicly released versions of NT still used "M.K." (except for possibly His Master's Noisetracker which is a different story anyway).
No, isNoiseTracker applies to any simple enough ProTracker (or even OpenMPT) module as well, so I'd rather leave it blank.

Revenant

Revenant

2016-02-16 14:53

reporter   ~0002258

Last edited: 2016-02-16 14:53

The ScreamTracker heuristic seems to affect a pretty large majority of the ModLand "ProTracker" collection (which also includes other .mod varieties, of course), but I attached a few examples from UnExoticA which are direct Amiga game rips and not likely to have ever been touched by any other trackers.

It seems like xmp only applies the same heuristic when a few other possible ProTracker heuristics fail, rather than almost all the time.

Saga Musix

Saga Musix

2016-02-16 22:19

administrator   ~0002261

Alright, I have relaxed the ST3 heuristic a bit in r5938.

Revenant

Revenant

2016-02-19 00:14

reporter   ~0002263

Last edited: 2016-02-19 03:04

Cool, looks good to me now.

One more related thing - currently a lot of the NoiseTracker tunes from the musicdisk "His Master's Noise" use finetune values that differ from the usual 4-bit scale. These were saved with a customized version of NoiseTracker that uses its own magic values, so I wrote a patch that detects them and converts the finetune correctly (and I uploaded a few examples where the difference is pretty obvious, though there are many more modules by Mahoney and others that are also affected).

The same NoiseTracker version also supports an unusual alternate instrument format (sort of like the synth editor in OctaMED, maybe?) and the 7xx "mega arpeggio" command, but I wouldn't really consider those a priority since they aren't very widely used anyway.

(edit: please ignore the first patch I attached, it was accidentally saved with the wrong encoding and I'm apparently not able to delete attachments)

Saga Musix

Saga Musix

2016-02-19 18:00

administrator   ~0002264

Patch applied in r5940, thanks!

Revenant

Revenant

2016-03-18 05:25

reporter   ~0002291

If I may revisit this one a bit, I've written another small patch that should make the NoiseTracker Dxx detection behave a little better. Namely, the loader now assumes a module is not made in NoiseTracker if there are more than one pattern break in the same pattern (because it only really makes sense to do this if the command allows breaking to any row). This fixes "brainless 3" by Radix and probably some other weird modules too.

Saga Musix

Saga Musix

2016-03-18 18:55

administrator   ~0002295

Applied in r6142.

Issue History

Date Modified Username Field Change
2016-02-15 08:06 Revenant New Issue
2016-02-15 08:06 Revenant File Added: noisetracker-examples.zip
2016-02-15 08:10 Revenant Description Updated
2016-02-15 17:07 Saga Musix Assigned To => Saga Musix
2016-02-15 17:07 Saga Musix Status new => assigned
2016-02-15 17:12 Saga Musix Note Added: 0002254
2016-02-15 17:12 Saga Musix Status assigned => feedback
2016-02-15 17:12 Saga Musix Target Version => OpenMPT 1.26.00.* (old testing)
2016-02-16 00:01 Revenant Note Added: 0002255
2016-02-16 00:01 Revenant Status feedback => assigned
2016-02-16 00:02 Revenant Note Edited: 0002255
2016-02-16 08:35 Saga Musix Note Added: 0002256
2016-02-16 14:53 Revenant File Added: protracker-examples.zip
2016-02-16 14:53 Revenant Note Added: 0002258
2016-02-16 14:53 Revenant Note Edited: 0002258
2016-02-16 22:19 Saga Musix Note Added: 0002261
2016-02-19 00:05 Revenant File Added: hmnt_finetune.patch
2016-02-19 00:07 Revenant File Added: hmnt_examples.zip
2016-02-19 00:14 Revenant Note Added: 0002263
2016-02-19 03:03 Revenant File Added: hmnt_finetune2.patch
2016-02-19 03:04 Revenant Note Edited: 0002263
2016-02-19 17:42 Saga Musix File Deleted: hmnt_finetune.patch
2016-02-19 18:00 Saga Musix Note Added: 0002264
2016-02-19 18:00 Saga Musix Status assigned => feedback
2016-02-20 16:30 Saga Musix Product Version => OpenMPT 1.25.04.00 / libopenmpt 0.2-beta16 (upgrade first)
2016-02-20 16:30 Saga Musix Fixed in Version => OpenMPT 1.26.01.00 / libopenmpt 0.2-beta17 (upgrade first)
2016-02-20 16:30 Saga Musix Target Version OpenMPT 1.26.00.* (old testing) => OpenMPT 1.26.01.00 / libopenmpt 0.2-beta17 (upgrade first)
2016-02-20 16:30 Saga Musix Status feedback => resolved
2016-02-20 16:30 Saga Musix Resolution open => fixed
2016-03-18 05:25 Revenant Note Added: 0002291
2016-03-18 05:25 Revenant Status resolved => feedback
2016-03-18 05:25 Revenant Resolution fixed => reopened
2016-03-18 05:25 Revenant File Added: Dxx_fix.patch
2016-03-18 13:06 Saga Musix Status feedback => assigned
2016-03-18 18:55 Saga Musix Note Added: 0002295
2016-03-18 18:55 Saga Musix Status assigned => resolved
2016-03-18 18:55 Saga Musix Resolution reopened => fixed
2024-04-02 20:45 Saga Musix Relationship added related to 0001765