sezero / mikmod

Mikmod Sound System (mirror of git repo at https://sf.net/projects/mikmod/)
http://mikmod.sourceforge.net/
69 stars 21 forks source link

.MED secondary tempo (9xx) command is bugged. #17

Closed AliceLR closed 3 years ago

AliceLR commented 3 years ago

Creating an issue for this one so my research doesn't clutter the (eventual) PR.

This bug occurs with .MED files that use the .MOD secondary tempo command 9xx in tempo mode, and appears to be caused by this line of code: https://github.com/sezero/mikmod/blob/master/libmikmod/loaders/load_med.c#L223

      case 0x9:
        if (bpmtempos) {
            if (!dat)
                dat = of.initspeed;
            UniEffect(UNI_S3MEFFECTA, dat);
        } else {
            if (dat <= 0x20) {
                if (!dat)
                    dat = of.initspeed;
                else
                    dat /= 4; /* This line. */
                UniPTEffect(0xf, dat);
            } else
                UniEffect(UNI_MEDSPEED, ((UWORD)dat * 125) / (33 * 4));
        }
        break;

The OctaMED documentation suggests that this should convert directly to/from the .MOD speed command and, considering MikMod's tempo conversion, it seems that there is no reason to divide this value by 4. https://modland.com/pub/documents/format_documentation/Music%20Editor%20v3.2%20(.med).txt

This change dates back to MikMod 3.1, where it appeared in the form of a speeddivisor variable that was always equal to 4 during tempo mode. This variable is applied to the 9xx command and the speed case of the Fxx command in different ways!

- Lots of bug fixes in MED loader. Should now play modules at correct speed, but
  still not perfect
                case 0x9:
                        if(dat<=0x20) {
                                if(!dat) currentspeed=of.initspeed;
                                else {
                                        if(bpmtempos) currentspeed=dat*4/speeddivisor;
                                        else currentspeed=dat/speeddivisor;
                                }
                                UniPTEffect(0xf,currentspeed);
                        } else ...
                case 0xf:
                        switch(dat) {
...
                                default:
                                        if(dat<=10) {
                                                currentspeed=dat*4/speeddivisor;
                                                UniPTEffect(0xf,currentspeed);
                                        } else
...

By 3.1.5 this variable was completely removed, just leaving a fixed division by 4 in the 9xx command and not in the Fxx command. This looks like an oversight that never got caught to me, but there might some reason I'm missing for this being there.

Removing that line makes these example .MEDs play at the same speeds that xmp plays them at. I don't have OctaMED set up to test with right now.

alain.med.zip wizardry.med.zip yellybeansong.med.zip

Since this division by 4 was presumably added for a reason (even if it might have been a mistake), I'm going to exhaustively test (with OctaMED, xmp, and MikMod) every .MED MMD0 and MMD1 file I can find that uses this to make sure removing the bugged line doesn't cause any breakage.

edit: maybe that was too optimistic, there are 379 MMD0 files and 816 MMD1 files that use 9xx with values <= 0x20...

AliceLR commented 3 years ago

As far as the removal of that division by 4, I've tested a few tracks and I'm fairly confident that 1) nothing relies on that division by 4, and pretty much every tempo mode track that uses 9xx relies on it NOT dividing by 4; 2) that change doesn't negatively affect tracks that didn't have a buggy 9xx before (either in BPM mode or by luck of the command translating to ProTracker F00 and being ignored).

Tested playback times vs. OctaMEDPlayer v0.903. OctaMEDPlayer times come from measuring a stereo mix recording in Audacity (~ means ambiguous loop so it's a weak estimate), xmp/MikMod times are as reported by their respective players. (!) means there was another bug for that particular file. All files ending in .mmd0 and .mmd1 are just files from the OctaMed MMD0/1 folders on modland.com since I didn't feel like linking them all directly ;-(

edit: also, xmp's accuracy for OctaMED files is impressive enough that I'm probably not going to bother with the OctaMEDPlayer timing step in future testing unless something seems suspicious.

File Type OctaMEDPlayer xmp MikMod MikMod (patch) Notes
wizardry.med MMD0/Tempo 1:28'77 1:28 0:12 1:28
alain.med MMD0/Tempo 2:52'99 2:52'5 0:29 2:53 [1] out of tune.
yellybeansong.med MMD0/Tempo ~4:04'27 4:03'4 0:41 4:04 Portamento inaccuracy?
Dean Evans/terminator 2 - puzzle.mmd0 MMD0/Tempo ~1:19'33 1:19'9 1:20 1:20 902 -> PT F00 ignored prior to patch.
Faroul/sad song.mmd0 MMD0/Tempo ~2:11'55 2:10'5 0:24 2:10
HJE/high speed.mmd0 MMD0/Tempo ~0:43'5 0:42'0 0:08 0:43
James Pimentel-Pinto/amiganuts power.mmd0 MMD0/Tempo ~1:55 1:54'7 0:19 1:55
Kevin Stannard/lunar-c-title.mmd0 MMD0/Tempo ~1:08.5 1:07'9 1:08 1:08 903 -> PT F00 ignored prior to patch. [1] chords out of tune.
- unknown/red herring.mmd0 MMD0/BPM 3:54.22 3:54'1 3:54 3:54
Basehead/high velocity.mmd0 (sequence 0) MMD0/BPM ~1:39'53 1:39'3 ????? (!) 1:40+ (!) [1] out of tune. Reaches the end of the first sequence at the correct time.
Dodge/agony title tune remixed.mmd0 MMD0/BPM 4:51'72 4:51'7 4:51 4:51
Dodge/rollin & bollin.mmd0 MMD0/BPM 5:27'70 5:27'6 5:27 5:27
Orpheus/electrosound 64.mmd0 MMD0/BPM >1:55 1:55'4 3:16 (!) 3:16 (!) [2] MikMod plays at half speed.
- unknown/5th beathoven.mmd1 MMD1/Tempo 1:01'67 1:01'3 0:10 1:01 906 -> PT F01
- unknown/gotterfunken.mmd1 MMD1/Tempo 3:59'82 3:58'8 0:43 3:58 906/905 -> PT F01. [1] out of tune.
Andy Baxter/cheryl heaven.mmd1 MMD1/Tempo 2:13'61 2:12'9 0:33 2:13 908 -> PT F02
Andy Soar/blood net - combat.mmd1 MMD1/Tempo 1:47'88 1:47'4 0:17 1:47 906 -> PT F01
Blair Zuppicich/roadkill - end.mmd1 MMD1/Tempo ~1:00 1:00'6 ? (!) ? (!) [3] MikMod gets stuck in a loop (1B02 -> B02).
Blockhead/spaceship.mmd1 MMD1/Tempo ~2:18'50 2:18'0 0:30 2:18 909 -> PT F02
Brooker/(brooker) #01.mmd1 MMD1/Tempo ~3:05'59 3:05'3 1:01 2:22 (!) [3] Patch is closer to correct; affected by 1Fxx -> Fxx.
Caramel/liver paste.mmd1 MMD1/Tempo ~2:41'54 2:40'9 1:02 2:41 90A -> PT F02
Chris the Highlander/afraid.mmd1 MMD1/Tempo 1:50'47 1:48'6 0:15 1:27 (!) [3] Patch correct aside from 16xx -> 6xx at the end.
Cobalt/drum sampler (sunsa del luya).mmd1 MMD1/Tempo ~2:26'05 2:25'8 0:24 2:25 906 -> PT F01
Cosmiq/heavy stuff.mmd1 MMD1/Tempo 1:43'15 1:42'6 0:25 1:42 904 -> PT F01
Dean Evans/jurassic park - music1.mmd1 MMD1/Tempo ~1:30 1:29'6 0:14 1:33 907 -> PT F01 (silent loop at end probably is the cause of the slightly different times)
Dimitrios Charalampidis/black waltz.mmd1 MMD1/Tempo ~1:32'15 1:32'0 0:20 1:32 906 -> PT F01
Dr. Tomastik/charless.mmd1 MMD1/Tempo 1:32'55 1:32'0 0:16 1:32 906 -> PT F01
- unknown/alien breed ii.mmd1 MMD1/BPM 3:53'3 3:53'1 ? (!) ? (!) [3] MikMod gets stuck in a loop (1B01 -> B01).
- unknown/digi-t-ice.mmd1 MMD1/BPM 1:37'27 1:37'2 1:37 1:37 [1] Out of tune.
- unknown/fair.mmd1 MMD1/BPM 0:44'81 0:44'6 0:44 0:44
Appi-Ukko/happovaiva.mmd1 MMD1/BPM 1:27'66 1:27'4 0:55 (!) 0:55 (!) [3] 1Bxx -> Bxx; 16xx -> 6xx; 1EEF -> EEF
C-Frog/soft vision.mmd1 MMD1/BPM ~2:24 2:21'7 1:48 (!) 1:48 (!) [3] 19xx -> 9xx and probably others.
Chroust/pentium.mmd1 MMD1/BPM 2:18'26 2:18'0 2:18 2:18
Cybarite/dark obsession title.mmd1 MMD1/BPM ~2:21 2:20'6 5:10 (!) 5:10 (!) [3] 1F30 -> F30 causes it to play slow starting from order 2.
Darkman/mindphaser.mmd1 MMD1/BPM 1:59'08 1:58'9 1:59 1:59
Debol/debol'97-msx3+.mmd1 MMD1/BPM 1:24'53 1:24'4 1:24 1:24
DJ Hotcakes/double dragon.mmd1 MMD1/BPM 2:26'64 2:28'4 >3:00 (!) ? (!) [3] 19xx -> 9xx
Dreamland Fantasy/china girl.mmd1 MMD1/BPM 2:59'25 2:59'0 2:07 (!) 2:07 [3] 1F03 -> F03; other bugs?...
Dreamland Fantasy/discovery.mmd1 MMD1/BPM 1:42'41 1:42'2 1:42 1:42
Dreamland Fantasy/doctor who.mmd1 MMD1/BPM 0:30'72 0:30'6 0:46 0:46 Difference is just due to MikMod playing past the loop (not a bug).
Flash (PL)/daj mi te noc.mmd1 MMD1/BPM 1:49'33 1:49'2 >3:00 (!) ? (!) [3] 19xx -> 9xx; 1F40 -> F40

New bugs found during testing:

[1] Seems to be a tuning bug in both MMD0 and MMD1 .MEDs caused by the MED loader not handling either the song or instrument transpose values (this needs verification). I'm not familiar enough with MikMod to tell how hard this would be to implement.

[2] The speed of BPM mode modules sometimes starts as or changes to something very wrong. From examining electrosound 64.med (and currently no other modules) this appears to be because of the loader factoring the GCD of beat rows (10) and initial speed (4) out of both the initial BPM (60) and speed (resulting in 60*10/4/2=75 tempo and 4/2=2 speed). The 9xx command is then immediately used to set the original speed of 4 (for an effective halving of overall speed). Haven't checked other modules for this yet. Considering high speed.med reached 909 tempo with no issue I'm skeptical that this GCD algorithm does anything useful (speed can never be set >255; the UWORD range should be adequate for sane BPM/beat row combos, but maybe tempo was a UBYTE when the algorithm was added). Another bug that could be caused by this factoring is, if the divisor were consistently applied to speeds provided by a 9xx command and those speeds were not a multiple of the GCD, the resulting speed would be truncated. Tentatively suggesting that the entire GCD thing be removed, but it needs more analysis and testing. (Also, the beat rows value may need to be provided to EffectCvt() and Fxx might need to switch to using UNI_MEDSPEED for BPM mode.)

[3] OctaMED 4.00 commands unimplemented:

I'd like to investigate bug 2 further and include a patch for it with this patch if possible. I'll submit a separate patch for the unimplemented OctaMED 4 commands (are there any compatibility concerns when adding new UNIMOD commands I should be aware of before implementing those?).

Until then, the working patch for this issue is simply:

diff --git a/libmikmod/loaders/load_med.c b/libmikmod/loaders/load_med.c
index 84cfb1f..1caebaa 100644
--- a/libmikmod/loaders/load_med.c
+++ b/libmikmod/loaders/load_med.c
@@ -219,8 +219,6 @@ static void EffectCvt(UBYTE eff, UBYTE dat)
            if (dat <= 0x20) {
                if (!dat)
                    dat = of.initspeed;
-               else
-                   dat /= 4;
                UniPTEffect(0xf, dat);
            } else
                UniEffect(UNI_MEDSPEED, ((UWORD)dat * 125) / (33 * 4));
AliceLR commented 3 years ago

I did some more testing for BPM mode speed bugs. This took longer than I expected because, as it turns out, getting OctaMED timing correct is a total nightmare. I think I've pretty much corrected it, though. I'm splitting this over a few comments because there are several tables.

"Patch 2" is the revised patch that fixes some BPM mode speed issues, the compatibility tempos, and other edge cases. [1][2][3] refer to bugs listed in the previous post; [2*] is a special case of [2] relating to the Fxx command that wasn't mentioned in the previous post. Specifically, the GCD logic when (rows per beat!=4) seems to have been added to compensate for the 9xx and Fxx commands providing BPM values in BPM mode that need to be converted, and seems to have accidentally worked in enough cases that it stuck. The correct thing to do is to multiply the BPM values provided to 9xx/Fxx by (rows per beat/4) to get a PT-compatible tempo. The rows per beat value can't be changed so this conversion can/should just happen at load time.

Another issue with the GCD division of speed that I didn't mention before is that it also breaks any command that relies on executing every tick (e.g. 1xx, Axx...).

File Type xmp (OctaMEDPlayer) MikMod (patch 1) MikMod (patch 2) Notes
Dirtie/weather.mmd0 MMD0/BPM/4t 2:23'8 2:24 2:24 Beat rows=5, speed=6, GCD=1
Fog/beavis & butthead.mmd0 MMD0/BPM/4t 2:55'0 2:55 2:55 Beat rows=8, speed=6, GCD=2
Orpheus/electrosound 64.mmd0 MMD0/BPM/4t 1:55'4 3:16 [2][5] 1:38 Beat rows=10, speed=4, GCD=2 (9xx, F02)
- unknown/amiga skank.mmd1 MMD1/BPM/4t 3:08'7 LONG [2][2*][3][4] 3:08 Beat rows=6, speed=6, GCD=6 (9xx, Fxx, F(03-20), 19xx)
- unknown/dance.mmd1 MMD1/BPM/4t 1:41'4 1:41 1:41 Beat rows=5, speed=6, GCD=1
- unknown/hardcorevibes.mmd1 MMD1/BPM/4t 2:45'0 2:45 2:45 Beat rows=8, speed=6, GCD=2
- unknown/its a skull.mmd1 MMD1/BPM/4t 3:34'9 3:35 3:35 Beat rows=5, speed=7, GCD=1
- unknown/three phantoms.mmd1 MMD1/BPM/4t 0:59'0 2:55 [1][2][3] 0:59 Beat rows=5, speed=5, GCD=5 (9xx, 1Bxx)
Alexander Zutt/new dimension.mmd1 MMD1/BPM/4t didn't load (5:32'50) 5:11 5:32 Beat rows=5, speed=5, GCD=5
Carl Bramley/the end.mmd1 MMD1/BPM/4t 4:59'2 4:59 [1][2][3] 4:59 Beat rows=8, speed=6, GCD=2 (9xx, 19xx, 1Bxx)
Digi/research e.p.mmd1 MMD1/BPM/4t 2:37'3 2:37 2:37 Beat rows=8, speed=6, GCD=2
Echo/hard scoop.mmd1 MMD1/BPM/4t 8:35'2 LONG [2][3] 8:35 Beat rows=8, speed=8, GCD=8 (9xx, 19xx, 1Bxx)
Emix Lemsman/terror of thunderdome (master mix).mmd1 MMD1/BPM/4t 9:41'5 9:53 [3][4] 9:41 Beat rows=4, speed=4, GCD=n/a (Fxx, F(03-20), 19xx) [4]: occurs in final pattern.
Hologen/bubbles.mmd1 MMD1/BPM/4t 3:55'4 3:50 3:54 Beat rows=6, speed=6, GCD=6
Jam Thrash/do your stuff.mmd1 MMD1/BPM/4t 5:46'2 LONG [1][3][4] 5:44 Beat rows=4, speed=6, GCD=n/a (Fxx, F(03-20), 19xx)
Jimbim/phanta1.mmd1 MMD1/BPM/4t 4:02'0 3:42 [1][3] 3:42 Beat rows=8, speed=6, GCD=2 (Fxx, 16xx) [3]: missing loops shortened this track a little.
Morgoth/coop-Turin/epitaph.mmd1 MMD1/BPM/4t 4:25'7 5:32 [2*][4] 4:25 Beat rows=15, speed=6, GCD=3 (Fxx)
Phia/2 demo 4 u.mmd1 MMD1/BPM/4t 3:48'3 7:36 [2][3] 3:48 Beat rows=8, speed=12, GCD=4 (9xx, Fxx, 19xx)
Psiberpunk/coop-DJ Spark-E/happy bubbles.mmd1 MMD1/BPM/4t 5:21'6 LONG [2][3] 5:21 Beat rows=8, speed=6, GCD=2 (9xx, 19xx)
Samuel/inspiration - cutre mix.mmd1 MMD1/BPM/4t 3:02'3 LONG [4] 3:02 Beat rows=20, speed=6, GCD=2 (Fxx, F(03-20))
Sheffra/vertigo.mmd1 MMD1/BPM/4t 5:59'2 5:49 [3][5] 5:51 Beat rows=4, speed=3, GCD=n/a (9xx, Fxx, F(01-02), 19xx, 1Bxx)
Spoochy/denoman.mmd1 MMD1/BPM/4t 3:48'9 LONG [2][3] 3:49 Beat rows=8, speed=4, GCD=4 (9xx, 19xx)
Spoochy/nadia i love you 4 ever!!.mmd1 MMD1/BPM/4t 3:14'5 3:09 [2*] 3:09 Beat rows=8, speed=6, GCD=2 (Fxx)
Spots/amiga pop.mmd1 MMD1/BPM/4t 11:40'8 LONG [2][2*] 11:40 Beat rows=8, speed=12, GCD=4 (9xx, Fxx)
Tarmslyng/more power.mmd1 MMD1/BPM/4t 2:16'3 4:32 [2][2*] 2:16 Beat rows=8, speed=6, GCD=2 (9xx, Fxx)
The Raven/wild and lonely.mmd1 MDD1/BPM/4t 4:26'5 LONG [2] 4:25 Beat rows=15, speed=5, GCD=5 (9xx)

New bugs: [3] Not a new bug but: I hacked out effects with values over 0xF before timing several of these just so there would at least be (somewhat) useful timings for these. [4] Fxx with a param between 01 and 20 is supposed to set the BPM in BPM mode but instead this set the speed (bug is usage of PT Fxx instead of UNI_MEDSPEED in two places; trivial fix and was required anyway as part of fixing [2]). Only a few tracks use Fxx in the affected range in BPM mode. [5] Fxx with a param between 01 and 02 in BPM mode has a weird bug in OctaMED where it sets the tempo to ~33, ignoring rows per beat. I found this in at least two tracks. Neither xmp nor OctaMEDPlayer check for this, which is probably fair, but it was a trivial fix.

NOTES:

AliceLR commented 3 years ago

Fxx for values between 01 and 0A in tempo mode was also implemented wrong: in OctaMED 2.00 and 4.00, I verified that the 1) these are treated as primary tempo and not secondary tempo (speed), 2) OctaMED internally maps these to other primary tempos, and 3) secondary tempo works with these tempos the same way that it works with regular tempos (i.e. these can just be translated with a lookup table independent of speed). I had to manually match most of these speeds because OctaMED doesn't communicate their translations and some of the values from the table in the OctaMED 1.12 documentation are inaccurate or absent. These speeds are roughly equivalent to (195 + (speed/2))/speed. Surprisingly, xmp gets this wrong.

Compat Tempo Approximate Tempo (MED 1.12 documentation table value)
1 195 (212)
2 97 (106)
3 65 (64)
4 49 (53)
5 39 (47)
6 32 (32)
7 28 (27)
8 24 (n/a)
9 22 (n/a)
10 20 (n/a)

Some tracks that relied on tempos in this range (I stopped testing with xmp at some point since its buggy handling of these tempos seems to break its timing):

File Type OctaMED 4 xmp MikMod (patch 1) MikMod (patch 2) Notes
- unknown/bund.mmd0 MMD0/Tempo/4t 2:52 4:38'6 2:54 2:54 Tempo=6
- unknown/transition.mmd0 MMD0/Tempo/4t 3:37 4:01'7 3:53 3:37 Tempo=7 at the very end.
BAD/flee.mmd0 MMD0/Tempo/4t ~5:21 5:12'8 5:39 5:20
Chris Link/soul crystal - cyberfunk.mmd0 MMD0/Tempo/4t ~0:55 2:02'5 0:47 0:55 Tempo=6
Jester/1990 - goodbyesong.mmd0 MMD0/Tempo/4t 2:12 2:39'1 1:41 2:11 Tempo=6
Chris Link/sky city - spheres.mmd1 MMD1/Tempo/4t ~1:07 1:20'3? (lie) 1:37 1:08
Chris the Highlander/life.mmd1 MMD1/Tempo/4t ~2:08 ? 2:08 2:08 Tempo=6
Master Yoda/three views of a secret.mmd1 MMD1/Tempo/4t 1:36 ? 1:35 1:36 Tempo=8 at the very end.
Nitron/ihaaah.mmd1 MMD1/Tempo/4t 4:05 ? 6:13 4:09 Tempo=6
Quarterback/a bold rave.mmd1 MMD1/Tempo/4t 2:17 ? 3:23 2:17 Tempo=5
Redd Kaa/and you don't stop.mmd1 MMD1/Tempo/4t 3:59 ? 2:53 4:04 Tempo=8
Room 237/phone tap.mmd1 MMD1/Tempo/4t 3:30 ? 5:12 3:30 Tempo=5

Another minor thing is that usage of 9xx with values >0x20 is not supposed to work according to the docs. OpenMPT and libxmp filter these out when they're encountered. MikMod's weird handling of this seems to be another thing shared with libmodplug. What OctaMEDPlayer does here is treats these values as speeds always. OctaMED 2.00 treats these as (speed & 0x1F). Since OctaMED 2.00 and later OctaMEDPlayer versions handle these inconsistently I think they should be treated as UB and the "best" handling for these is to just ignore them (like OpenMPT and libxmp). There are not many tracks that use these.

AliceLR commented 3 years ago

On top of all of this, some tracks STILL didn't play correctly, so I cheated and looked at what libxmp does. Turns out MEDs in 8 channel mode use a completely different primary tempo system with a different lookup table than the one above. I just ported this behavior directly over to MikMod.

Some tracks I tested with the 8 channel mode flag set ("(e)"=the xmp duration estimate):

File Type OctaMED 4 xmp MikMod (patch 1) MikMod (patch 2) Notes
- unknown/anvil.mmd0 MMD0/Tempo/8t 1:58 1:56'9 1:27 1:57
Jason Honingford/trend.mmd0 MMD0/Tempo/8t ~2:30 2:29'3 1:55 2:30
Teijo Kinnunen/kinnunen 2.mmd0 MMD0/Tempo/8t 3:26 3:24'5 2:41 3:25
- unknown/arligentia2.mmd1 MMD1/Tempo/8t 3:03 3:01 (e) 2:00 3:02
- unknown/ghost busters quit.mmd1 MMD1/Tempo/8t 2:16 2:08 (e) 1:45 2:15
- unknown/michael.mmd1 MMD1/Tempo/8t 3:45 3:47 (e) 2:04 3:47 Tempo=9
- unknown/overdose1 - preview.mmd1 MMD1/Tempo/8t 1:52 1:51 (e) 1:13 1:51 Tempo=8
Alex Van Starrex/octasongs.mmd1 MMD1/Tempo/8t 9:48 9:45 (e) 5:55 9:47 Tempo=43(!)
Czar/tores mix.mmd1 MMD1/Tempo/4t 0:08 0:07'9 0:45 0:08 Tempo=1
Matthias Kaulartz/knighthood.mmd1 MMD1/Tempo/8t 3:47 3:41 (e) 2:54 3:42 F(>0A)(!)
Sparky/never again.mmd1 MMD1/Tempo/8t 3:52 3:44 (e) 4:06 3:44 Tempo=7
Toady/secret of mana.mmd1 MMD1/Tempo/8t 0:43 0:44'7 0:28 0:43 Tempo=9
Dr. Fiss/nikolaus (7''version).mmd1 MMD1/BPM/6t 3:06 3:05'0 3:00 3:06 BPM=101
Ludwig/techfunk.mmd1 MMD1/BPM/8t 5:45 5:42'5 LONG 5:44 BPM=48
Mixer/superaxel.mmd1 MMD1/BPM/8t 11:00 11:04'7 LONG 11:06 BPM=9

Additionally, in the track superaxel.med, I found another bug that affects MEDs containing blocks with fewer tracks than the total song track count (the pattern loaders just needed to skip the unused tracks).

AliceLR commented 3 years ago

What a mess! PR incoming soon.

Addendum: since testing for this issue took forever, I gathered some data on the number of .MEDs using various features that aren't implemented in MikMod right now (aside from OctaMED 4 effects since I'm fixing that soon). None of these being missing is news, but actual counts of affected modules might be useful. (Values are approximate.) (FWIW I don't think MMD2/MMD3 support is worth the effort until after most of the rest of these have been addressed.)

Feature MMD0 MMD1 Total
Instrument transpose 199 541 740
Synth/Hybrid instruments 155 196 351
Hold/Decay 44 82 126
Song transpose 23 60 83
Multiple songs 6 68 74
IFFOct instruments 34 38 72
MMD2/MMD3 (161 MMD2)+(636 MMD3)=797