Mod Archive Forums

Music Production => Players => Topic started by: DZ-Jay on March 10, 2024, 14:12:12

Title: Arpeggio processing ...
Post by: DZ-Jay on March 10, 2024, 14:12:12
I have a question about the Arpeggio (0xy) effect.

All the documentation I read on common implementations of XM (FT2, OpenMPT, MilkyTracker, etc.) state that the effect alternates between 3 semi-tones:

This makes perfect sense to me and it is how I originally implemented it.

However, I am looking at the ported FT2 code and that logic appears to be incorrect.  Unless I am completely misunderstanding something, the code works like this:

Essentially, the three offsets are read from a table of 16 entries, using the count-down timer as an index, so the values are read in reverse:

Arpeggio Table:
Code: [Select]
0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0

What all this means in practice is that the first tick of every row is skipped, and the countdown causes it to process the parameters in reverse.

Therefore, the ultimate product is the something like in the following table.  Consider a song speed of 8 ticks per row. 

Tick #TimerTbl ValueResult
0 (start of row)8 (timer recycled at zero of last row)SkippedBase
17arpTab[7] = 1Base + x param
26arpTab[6] = 0Base
35arpTab[5] = 2Base + y param
44arpTab[4] = 1Base + x param
53arpTab[3] = 0Base
62arpTab[2] = 2Base + y param
71arpTab[1] = 1Base + x param
08 (timer recycled at zero)SkippedBase
17arpTab[7] = 1Base + x param
26arpTab[6] = 0Base
............

Moreover, because the first tick on every row is skipped, when you use a speed number which is a multiple of 3, it will cause the base note to be played twice.

This is sort of weird to me, so perhaps someone with more experience can shed some light on how it should work in practice, or whether this is the expected behaviour.

    -dZ.
Title: Re: Arpeggio processing ...
Post by: DZ-Jay on March 10, 2024, 16:04:59
OK, never mind on this -- it seems to be a quirk of FT2, so I won't bother with it.

I found this in the MilkyTracker documentation, comparing the various implementations (FT2 description in red):

https://milkytracker.org/docs/MilkyTracker.html#fx0xy (https://milkytracker.org/docs/MilkyTracker.html#fx0xy)
Quote
Explanation:
Arpeggio quickly alters the note pitch between the base note (C-4) and the semitone offsets x (3 = D#4) and y (7 = G-4). Each pitch is played for the duration of 1 tick. If speed is higher than 3 (meaning there are more than 3 ticks per row), the sequence is looped.

ProTracker 2/3
Base note is played for tick 0, then the semitone offset x for tick 1, then semitone offset y for tick 2.

Fasttracker II
Base note is played for tick 0, then the semitone offset y for tick 1, then semitone offset x for tick 2.


It seems that the intention (and most common implementations) is to cycle through base, base +x, and base + y.

I do have one question, though.  Is it expected that we should skip tick zero of every row, or that we should restart counting the sequence "base, base + x, base + y" on every row?

This would make the arpeggio sound a bit irregular, depending on how many ticks there are in a row.  For instance, if the song speed is 5 ticks per row, the arpeggio would cycle like this:

Tick #semi-tone
0skipped (base)
1base
2base + x
3base + y
4base
0skipped (base)
1base
2base + x
3base + y
......

In contrast, the original way I had implemented it (and the way I thought it should work) was to process the command on every tick and always cycle through the sequence "base, base + x, base + y" for the duration of the note (or until the effect is deactivated).

For those with more experience than me, especially from the musician side of things, how do you think this effect is expected to work?

    -dZ.