Mod Archive Forums Mod Archive Forums
Advanced search  

News:

Please note: Your main modarchive.org account will not work here, you must create a forum account to post on the forums.

Pages: [1]   Go Down

Author Topic: Arpeggio processing ...  (Read 193 times)

0 Members and 1 Guest are viewing this topic.

DZ-Jay

  • New User
  • Offline Offline
  • Posts: 42
  • I [heart] Intellivision.
    • View Profile
    • Carol Vs. Ghost
Arpeggio processing ...
« 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:
  • Base note
  • Base note + x param
  • Base note + y param

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:
  • The effect is processed only on non-zero ticks.
  • It uses the song timer (i.e., the tick counter -- which counts down on every tick from the song speed until zero) to determine the semi-tone offset to use:  a value that cycles through 0, 1, and 2.
  • Those values are used like this:
    • 0: Base note
    • 1: Base note + x param
    • 2: Base note + y param

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.
Logged
P. Machinery:
   Another hope feeds another dream...
   Another truth installed by the machine.

   -- Propaganda

DZ-Jay

  • New User
  • Offline Offline
  • Posts: 42
  • I [heart] Intellivision.
    • View Profile
    • Carol Vs. Ghost
Re: Arpeggio processing ...
« Reply #1 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
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.
Logged
P. Machinery:
   Another hope feeds another dream...
   Another truth installed by the machine.

   -- Propaganda
Pages: [1]   Go Up