Development: Test Cases/XM

From OpenMPT Wiki
Jump to: navigation, search

This test suite is a collection of XM modules that were created while discovering playback bugs in OpenMPT. It is meant to be an easy way to check for regressions when code is changed, or to verify your own player’s routines if you are concerned about playback compatibility. The tests are designed in a way so that it is easy to figure out if your player is working correctly. In most test cases, your own player’s output can be heard on the left channel, while Fasttracker 2’s output is heard on the right channel. This way, it is easy to find out whether everything works as intended or if there are any discrepancies without having to read any long test descriptions. When it is impossible to do such a cross-verification, a more detailed description of the test can usually be found in the sample, instrument or comment text.

Bit-exact output is not the goal of this test suite, correct playback is, so slight deviations from Fasttracker 2’s output (e.g. different resampling algorithms, pop reduction, etc.) are acceptable. Some tests will only sound correct on the first run. Unless stated otherwise, it is not important that the test output sounds identical when looping the module.

Most test cases are documented (more or less) in OpenMPT’s source code with a reference to the filename of the test case. I am sorry that many tests do not have proper descriptions − I have started this documentation years after I have fixed some of these issues and can thus not remember all the details anymore. If you are stuck with one of the tests, you may have a look at specific source code revisions that are provided with most tests to see what was changed in the code to make it work correctly.

Last but not least, please keep in mind that some descriptions might be wrong or too general. Sometimes, the description might be correct in the given test case, but changing the test case might invalidate the description. If you know better than me, please correct the texts, and please ask me if you need more information one of the test cases. The documentation is not always optimal because the test cases have been written long before I have created this site.

Another thing to keep in mind is that Fasttracker 2 does not reset various channel memory variables when restarting a module or loading a new one. Thus, when comparing against the output of Fasttracker 2, you should only ever consider the first play of the first module loaded into Fasttracker 2. Quit and restart Fasttracker 2 between tests.

3xxins.xm

Current status: OpenMPT passes this test since revision ???.
Download: 3xxins.xm
Description: If a tone portamento effect is encountered, the instrument number next to it is always interpreted as the instrument number of the currently playing instrument. This test shows how the instrument envelope is reset when such an event is encountered.

3xx-no-old-samp.xm

Current status: OpenMPT passes this test since revision 362.
Download: 3xx-no-old-samp.xm
Description: Two tests in one: An offset effect that points beyond the sample end should stop playback on this channel. The note must not be picked up by further portamento effects.

Arpeggio.xm

Current status: OpenMPT passes this test since revision 2546.
Download: Arpeggio.xm
Description: Arpeggio behavior is very weird with more than 16 ticks per row. This comes from the fact that Fasttracker 2 uses a LUT for computing the arpeggio note (instead of doing something like tick%3 or similar). The LUT only has 16 entries, so when there are more than 16 ticks, it reads beyond array boundaries. The vibrato table happens to be stored right after arpeggio table. The tables look like this in memory:

ArpTab: 0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0
VibTab: 0,24,49,74,97,120,141,161,180,197,...

All values except for the first in the vibrato table are greater than 1, so they trigger the third arpeggio note. Keep in mind that Fasttracker 2 counts downwards, so the table has to be read from back to front, i.e. at 16 ticks per row, the 16th entry in the LUT is the first to be read. This is also the reason why Arpeggio is played “backwards” in Fasttracker 2.

ArpeggioClamp.xm

Current status: OpenMPT passes this test since revision 318 (?) + 8822.
Download: ArpeggioClamp.xm
Description: Arpeggio parameters are clamped differently than the base note. The upper limit is XM note 96 with a finetune of ±0.

ArpSlide.xm

Current status: OpenMPT passes this test since revision 4556.
Download: ArpSlide.xm
Description: Like in some other trackers (e.g. Impulse Tracker), arpeggio notes are supposed to be relative to the current note frequency, i.e. the arpeggio should still sound as intended after executing a portamento. However, this is not quite as simple as in Impulse Tracker, since the base note is first rounded (up or down) to the neares semitone and then the arpeggiated note is added.

delay1.xm

Current status: OpenMPT passes this test since revision 450 (?).
Download: delay1.xm
Description: A fun test for rogue note delays that outputs a nice drum beat if played correctly. Combinations of note delays with and without instrument number are tested. The following tests are more “testable”.

delay2.xm

Current status: OpenMPT passes this test since revision 450 (?).
Download: delay2.xm
Description: Rogue note delay test. It seems that internally, Fasttracker 2 always acts like the last played note is next to a note delay (EDx with x > 0) if there is no note. Doing exactly this is probably the easiest way to pass this test. This also explains Fasttracker 2’s behaviour if there is an instrument number next to such a rogue note delay, which is shown in this test. Both channels should play exactly the same combination of snare and bass sounds.

delay3.xm

Current status: OpenMPT passes this test since revision 1095 (?).
Download: delay3.xm
Description: Just when you thought that you have got it right, you step into the next pitfall. Here you can see that the rogue note delay behaviour is only found with EDx effects with x > 0. An ED0 effect should just be ignored and not retrigger any notes.

DelayCombination.xm

Current status: OpenMPT passes this test since revision 1331.
Download: DelayCombination.xm
Description: Naturally, Fasttracker 2 ignores notes next to an out-of-range note delay. However, to check whether the delay is out of range, it is simply compared against the current song speed, not taking any pattern delays into account. No notes should be triggered in this test case, even though the second row is technically longer than six ticks.

delaycut.xm

Current status: OpenMPT passes this test since revision ???.
Download: delaycut.xm
Description: Even more idiosyncrasies with the EDx command, this time in combination with note offs.

E90.xm

Current status: OpenMPT passes this test since revision 3541.
Download: E90.xm
Description: The E90 effect does not use any effect memory. Instead, it retriggers the note on the first tick.

EnvLoops.xm

Current status: OpenMPT currently fails this test.
Download: EnvLoops.xm
Description: In this test, all possible combinations of the envelope sustain point and envelope loops are tested, and you can see their behaviour on note-off. If the sustain point is at the loop end and the sustain loop has been released, don't loop anymore. Probably the most important thing for this test is that in Fasttracker 2 (and Impulse Tracker), envelope position is incremented before the point is evaluated, not afterwards, so when no ticks have been processed yet, the envelope position should be invalid. This test was passed from revision 1213 to 1512, however in favour of fixing EnvOff.xm, the old code was restored, so now the last test case in this module no longer works correctly.

EnvOff.xm

Current status: OpenMPT passes this test since revision 1513.
Download: EnvOff.xm
Description: Fixing EnvLoops.xm made OpenMPT cut off envelopes one tick to early in some cases, so modules sounded kind of "dry".

envretrig.xm

Current status: OpenMPT passes this test since revision ???.
Download: envretrig.xm
Description: Note delays retrigger envelopes.

finetune.xm

Current status: OpenMPT passes this test since revision 1283.
Download: finetune.xm
Description: A test for the E5x finetune command. Behaviour is very different from the MOD format - first off, E50 is the lowest finetuning and E5F is the highest. E5x is only applied if there is a real note next to the command (this simplifies a few things).

Finetune-Precision.xm

Current status: OpenMPT passes this test since revision 3668.
Download: Finetune-Precision.xm
Description: The lower three bits of the sample finetune should be ignored to achieve the same precision as Fasttracker 2.

FineVol-LinkMem.xm

Current status: OpenMPT passes this test since revision 1354.
Download: FineVol-LinkMem.xm
Description: EAx and EBx memory should not be shared. If effect memory is applied correctly, the module should stay silent.

FreqWraparound.xm

Current status: OpenMPT passes this test since revision 2139, 3770.
Download: FreqWraparound.xm
Description: Here is a really mind-boggling test case.

  • Fasttracker 2 limits the period when sliding up (the period limits appears to be 1...31999 - fine periods, not Amiga periods).
  • It does not limit the period when sliding down. It slides to infinity, or more precisely, happily wraps around at 65536 (it is a 16-Bit value).
  • Periods are apparently upside-down in Fasttracker 2 (so they follow the same direction as frequency). This leads to some funny wraparound behaviour once the frequency goes so low that the shift operator in Fasttracker′s period to frequency LUT conversion becomes negative.

FT2PanLaw.xm

Current status: OpenMPT passes this test since revision 3638.
Download: FT2PanLaw.xm
Description: Contrary to most other trackers, Fasttracker 2 uses the square root pan law (not to be confused with the sin/cos equal power pan law). This is how it works:

  • Create a LUT with 257 entries: round(65536 * sqrt(n / 256)) for n = 0...256
  • Compute channel panning, range is 0...255
  • Left channel volume is volume * LUT[256 - pan]
  • Right channel volume is volume * LUT[pan]

Note that there is no such thing as “100% right panning”, as the LUT will never return 0 for the left channel.

In this context, it is also worth noting that volume-column panning is simply multiplied by 16, i.e. PF is equivalent to 8F0, not 8FF.

Samples 2 and 3 contain the output of FT2 (left and right channel respectively), so you can use these to compare your code against.

Glissando.xm

Current status: OpenMPT passes this test since revision 4556.
Download: Glissando.xm
Description: Enabling glissando should round (up or down) the result of a tone portamento to the next semitone. Normal portamento up and down effects are not affected by this.

GlobalVolume.xm

Current status: OpenMPT currently fails this test.
Download: GlobalVolume.xm
Description: Since global volume appears to be applied during pattern parsing time, global volume changes are not applied to channels that are left of the global volume command until the second tick of the row. Effectively this means that every note on a row could have a different global volume. Since global volume is applied on the complete mix buffer rather than individual notes, this behaviour cannot be fixed in OpenMPT for now.

key_off.xm

Current status: OpenMPT passes this test since revision 300.
Download: key_off.xm
Description: Key off at tick 0 (K00) is very dodgy command. If there is a note next to it, the note is ignored. If there is a volume column command or instrument next to it and the current instrument has no volume envelope, the note is faded out instead of being cut.

keyoff+instr.xm

Current status: OpenMPT passes this test since revision 1095.
Download: keyoff+instr.xm
Description: Apparently, any note number in a pattern causes instruments to recall their original sample settings (volume, panning, ...) - no matter if there's a Note Off next to it or whatever. In the first pattern, the panning of the both channels should always be opposed.

KeyOff2.xm

Current status: OpenMPT passes this test since revision 1163.
Download: KeyOff2.xm
Description: More K00 fun! You should ignore any note or instrument data next to a K00 effect. Probably the best thing to do is to wipe them from your internal channel memory in such a situation.

lowest.xm

Current status: OpenMPT currently fails this test.
Download: lowest.xm
Description: Fasttracker 2 does weird things if the calculated note (pattern note + sample transpose) is lower than the lowest possible note. Note the high DC offset on the first two rows of Fasttracker 2’s output, it seems like it is playing the first sample “very” slowly.

NoteLimit.xm

Current status: OpenMPT passes this test since revision 1163.
Download: NoteLimit.xm
Description: I think one of the first things Fasttracker 2 does when parsing a pattern cell is calculating the “real” note (i.e. pattern note + sample transpose), and if this “real” note falls out of its note range, it is ignored completely (wiped from its internal channel memory). The instrument number next it, however, is not affected and remains in the memory.

NoteLimit2.xm

Current status: OpenMPT passes this test since revision 1225.
Download: NoteLimit2.xm
Description: This test is an addendum to the previous test (note-limit.xm) because I forgot that you first have to check if there is an instrument change happening before calculating the “real” note. I always took the previous transpose value when doing this check, so when switching from one instrument (with a high transpose value) to another one, it was possible that valid notes would get rejected.

NoteOff.xm

Current status: OpenMPT passes this test since revision 673-836.
Download: NoteOff.xm
Description: I think the essence of this test was that a note-off note does not stop the sample, it just mutes it...

NoteOff2.xm

Current status: OpenMPT passes this test since revision ???.
Download: NoteOff2.xm
Description: Various combinations of note-off notes and other things. One of my earliest tests...

NoteOffFadeNoEnv.xm

Current status: OpenMPT passes this test since revision 7461.
Download: NoteOffFadeNoEnv.xm
Description: When an instrument has no volume envelope, a note-off instantly sets the instrument volume to 0. If the note-off is not delayed (i.e. no EDx effect next to it), the fade-out flag is set in addition. The left and right channel of this module should sound identical.

NoteOffInstrChange.xm

Current status: OpenMPT passes this test since revision 7461.
Download: NoteOffInstrChange.xm
Description: A lone instrument number after a note-off should reset the note-off status of the instrument. The left and right channel of this module should sound identical.

NoteOffVolume.xm

Current status: OpenMPT passes this test since revision 1995.
Download: NoteOffVolume.xm
Description: If an instrument has no volume envelope, a note-off command should cut the sample completely - unless there is a volume command next it. This applies to both volume commands (volume and effect column).

OffDelay.xm

Current status: OpenMPT passes this test since revision 1095.
Download: OffDelay.xm
Description: Note Delays combined with anything else are a lot of fun! Note Off combined with a Note Delay will cause envelopes to retrigger! And that is actually all it does if there is an envelope. No fade out, no nothing.

OffsetRange.xm

Current status: OpenMPT passes this test since revision 362.
Download: OffsetRange.xm
Description: Test to verify the exact behaviour for out-of-range offset commands. Only the first sample should be played, because it is the only sample that is longer than 256 samples.

PanMemory.xm

Current status: OpenMPT passes this test since revision 1994.
Download: PanMemory.xm
Description: All notes in this test should be panned hard right.

PanMemory2.xm

Current status: OpenMPT passes this test since revision 1994.
Download: PanMemory2.xm
Description: A more thorough check than PanMemory.xm. Both channels should be panned identically and the module should thus stay silent.

PanOff.xm

Current status: OpenMPT passes this test since revision 2252.
Download: PanOff.xm
Description: Another chapter of weird FT2 bugs: Note-Off + Note Delay + Volume Column Panning = Panning effect is ignored.

PanSlideMem.xm

Current status: OpenMPT passes this test since revision 1431.
Download: PanSlideMem.xm
Description: As the panning slide commands in the volume column don't have memory, they should also not interfere with the effect memory of the Pxy command.

PanSlideZero.xm

Current status: OpenMPT passes this test since revision 1313.
Download: PanSlideZero.xm
Description: The panning slide commands in the volume column are not supposed to have an effect memory. So it is all natural that the pan slide right command with parameter 0 does nothing. However, the pan slide left command resets the panning to 0 (hard left) on all ticks but the first when using 0 as parameter. The first tick of this test should be panned centre, the following ticks of the first row should be panned hard left, the complete second row should be panned centre. The first tick of the third row should be panned centre, the following ticks should be panned to 5 (of 64) because the volume column is evaluated first (so the panning is first set to 0 on every tick, then 5 is added), and on the last row the first tick should be centre and then 5 should be added on every following tick.

pathead.xm

Current status: OpenMPT passes this test since revision ???.
Download: pathead.xm
Description: Header size fields in XM files should be respected in all cases, even if they are too small or too big. In this case, the pattern header is not the usual 9 bytes, and the pattern header size indicates this. You have to skip as many bytes as this field says before starting to read the pattern.

PatLoop-Break.xm

Current status: OpenMPT passes this test since revision 1186.
Download: PatLoop-Break.xm
Description: This is a nice test for E6x + Dxx behaviour. First make sure that E6x is played correctly by your player. A position jump should not clear the pattern loop memory (just like in Impulse Tracker).

PatLoop-Infinite.xm

Current status: OpenMPT passes this test since revision 0.
Download: PatLoop-Infinite.xm
Description: A simple test for infinite pattern loop behaviour. Even ModPlug Tracker 1.16 passes this.

PatLoop-Jumps.xm

Current status: OpenMPT passes this test since revision 1186.
Download: PatLoop-Jumps.xm
Description: This is similar to PatLoop-Break.xm.

PatLoop-Nested.xm

Current status: OpenMPT currently fails this test.
Download: PatLoop-Nested.xm
Description: I am not sure if OpenMPT plays this correctly, because FT2 seems to play this differently every time. However, the core pattern loop logic in OpenMPT should be correct.

PatLoop-Overflow.xm

Current status: OpenMPT currently fails this test.
Download: PatLoop-Overflow.xm
Description: This test fails because OpenMPT will ignore the invalid E60 restart position. After having played pattern 0, it should continue on pattern 1, row 3, but such a row does not exist so it simply continues on the first row and a computer voice says “fail”. Fasttracker 2 jumps to this non-existent row and then returns to the first pattern, saying “success”.

PatLoop-Various.xm

Current status: OpenMPT passes this test since revision 1186.
Download: PatLoop-Various.xm
Description: This is similar to PatLoop-Break.xm. You should hear a bit of quiet noise and then finally a computer voice saying "Success". If it says "Fail", something is wrong with pattern loop and pattern break behaviour.

PatLoop-Weird.xm

Current status: OpenMPT passes this test since revision 1186.
Download: PatLoop-Weird.xm
Description: This is similar to PatLoop-Break.xm. The voice should say "1 4 2" and then repeat "3 4 2" forever.

PatternDelay-NoteDelay.xm

Current status: OpenMPT passes this test since revision 7793.
Download: PatternDelay-NoteDelay.xm
Description: Just like in IT and S3M, a note delay next to a row delay is retriggered on every row repetition.

PatternDelays.xm

Current status: OpenMPT passes this test since revision 0.
Download: PatternDelays.xm
Description: If there are multiple pattern delays (EEx), only the one on the rightmost channel is considered (even if the EEx parameter is 0). Even ModPlug Tracker 1.16 passes this. The second pattern is not very important, it only tests the command X ModPlug Tracker extension, which adds fine pattern delays (like in the IT format) to XM files.

PatternDelaysRetrig.xm

Current status: OpenMPT passes this test since revision 0.
Download: PatternDelaysRetrig.xm
Description: Only the very first tick of a row should be considered as the “first tick”, even if the row is repeated multiple times using the pattern delay (EEx) command (i.e. multiples of the song speed should not be considered as the first tick). This is shown in this test by using the extra-fine portamento commands, which are only executed on the first tick.

Pickup.xm

Current status: OpenMPT passes this test since revision 1513.
Download: Pickup.xm
Description: This seems to be related to EnvOff.xm. Sound output should never go completely silent between the notes.

PortaDelay.xm

Current status: OpenMPT passes this test since revision 3665 + 3667.
Download: PortaDelay.xm
Description: I wish I didn't know about this test case, because it's absolutely mind-boggling.

  • If there is a portamento next to a note delay, it is executed (as per VolColDelay.xm: not on the first tick and not on the delayed tick), but its parameter is not updated (old parameter is used).
  • As the portamento is not applied on the delayed tick, the note next to the delay effect is set, but the portamento target stays the same as before.

porta-delay.xm

Current status: OpenMPT passes this test since revision 1098.
Download: porta-delay.xm
Description: If there is a portamento command next to a note delay, the portamento command is ignored completely. See PortaDelay.xm.

PortaJustStoppedNote.xm

Current status: OpenMPT passes this test since revision 6193.
Download: PortaJustStoppedNote.xm
Description: 3xx-no-old-samp.xm already tests the general case of portamento picking up a stopped note (the new note should not be played), but there is an edge case when the note just stopped on the previous tick. In this case, OpenMPT did previously behave differently and still execute the portamento effect.

Porta-LinkMem.xm

Current status: OpenMPT passes this test since revision 1354, 7803.
Download: Porta-LinkMem.xm
Description: 1xx, 2xx, E1x, E2x, X1x and X2x memory should not be shared. Both channels should sound identical if effect memory is applied correctly.

porta-offset.xm

Current status: OpenMPT passes this test since revision 1102.
Download: porta-offset.xm
Description: If there is a portamento command next to an offset command, the offset command is ignored completely. In particular, the offset parameter is not memorized.

Porta-Pickup.xm

Current status: OpenMPT passes this test since revision 1187.
Download: Porta-Pickup.xm
Description: An instrument number should not reset the current portamento target. The portamento target is valid until a new target is specified by combining a note and a portamento effect.

retrig.xm

Current status: OpenMPT passes this test since revision 1923.
Download: retrig.xm
Description: Fasttracker 2’s retrigger commands are especially dodgy. For example, the first tick is skipped if a volume command is next to the retrigger command, and the retrigger count is reset to 1 if there is an instrument or note next to the command. Not sure when the speed 6 patterns were fixed, but the speed 4 issue was resolved in revision 1923.

RetrigFade.xm

Current status: OpenMPT passes this test since revision 7794.
Download: RetrigFade.xm
Description: A note-off with an instrument number starts to fade out instruments. An instrument number next to a retrigger effect resets the fade-out. Combine the two on the same row, and the latter is no longer true: Note-off with instrument number and retrigger keeps fading out.

RetrigTick0.xm

Current status: OpenMPT passes this test since revision 1929.
Download: RetrigTick0.xm
Description: Another dedicated test for tick 0 retrig checks: All combinations of instrument, note, note-off, etc...

SampleChange.xm

Current status: OpenMPT currently fails this test.
Download: SampleChange.xm
Description: Fasttracker 2 seems to switch the sample on row 13, but the instrument settings (including the fade-out settings of the previous instrument) are kept.

SetEnvPos.xm

Current status: OpenMPT passes this test since revision 3585.
Download: SetEnvPos.xm
Description: When using the Lxx effect, Fasttracker 2 only sets the panning envelope position if the volume envelope’s sustain flag is set.

TonePortamentoMemory.xm

Current status: OpenMPT passes this test since revision 1312.
Download: TonePortamentoMemory.xm
Description: Tone portamento is actually the only volume column command with an effect memory (as it is shared with the other effect column). Another nice bug demonstrated in this module is the combination of both portamento commands (Mx and 3xx) in the same cell: The 3xx parameter is ignored completely, and the Mx parameter is doubled, i.e. M2 3FF is the same as M4 000.

TremoloVibrato.xm

Current status: OpenMPT passes this test since revision 7802.
Download: TremoloVibrato.xm
Description: Due to sloppy copy&paste, the tremolo "ramp down" waveform is influenced by the vibrato position: If the vibrato position has passed the first half of the LFO cycle, the ramp down waveform is inverted.

TremoloWaveforms.xm

Current status: OpenMPT passes this test since revision 7802.
Download: TremoloWaveforms.xm
Description: In particular the “ramp down” is difficult to get right, which is tested in detail in TremoloVibrato.xm

Tremor.xm

Current status: OpenMPT passes this test since revision 1316.
Download: Tremor.xm
Description: The tremor counter is not updated on the first tick, and the counter is only ever reset after a phase switch (from on to off or vice versa), so the best technique to implement tremor is to count down to zero and memorize the curren phase (on / off), and when you reach zero, switch to the other phase by reading the current tremor parameter. Keep in mind that T00 recalls the tremor effect memory, but the phase length is always incremented by one, i.e. T12 means “on for two ticks, off for three”.

TremorInstr.xm

Current status: OpenMPT passes this test since revision 1996.
Download: TremorInstr.xm
Description: Instrument numbers reset tremor count.

TremorRecover.xm

Current status: OpenMPT currently fails this test.
Download: TremorRecover.xm
Description: Even if a tremor effect muted the sample on a previous row, volume commands should be able to override this effect. Instrument numbers should reset the tremor effect as well. Currently, OpenMPT only supports the latter.

VibratoCombinations.xm

Current status: OpenMPT currently fails this test.
Download: VibratoCombinations.xm
Description: Volume column vibrato should not reset the note frequency, while effect column vibrato does it (like any other tracker).

VibratoDouble.xm

Current status: OpenMPT passes this test since revision 7804.
Download: VibratoDouble.xm
Description: If there is a vibrato depth command in the volume column and some kind of vibrato command in the effect column (4xx / 6xx), the vibrato waveform is advanced at double speed. The effect effect column’s parameter has precedence if it is not 0.

VibratoWaveforms.xm

Current status: OpenMPT passes this test since revision 1214.
Download: VibratoWaveforms.xm
Description: Fasttracker 2 tries to be inconsistent where possible, so you have to duplicate a lot of code or add conditions to behave exactly like Fasttracker. Yeah! Okay, seriously: Generally the vibrato and tremolo tables are identical to those that ProTracker uses, but the vibrato’s “ramp down” table is upside down. You will have to negate its sign for it to work as intended.

VolColDelay.xm

Current status: OpenMPT passes this test since revision 3664 + 3666.
Download: VolColDelay.xm
Description: If there's a note delay, slide commands in the volume column are not executed on the first tick and, if there's an instrument number next to it, also not on the delayed tick. This effectively breaks fine volume slides.

In total, OpenMPT passes 64 out of 72 tests.