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:**` 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 #** | **Timer** | **Tbl Value** | **Result** |

0 (start of row) | 8 (timer recycled at zero of last row) | Skipped | Base |

1 | 7 | arpTab[7] = 1 | Base + x param |

2 | 6 | arpTab[6] = 0 | Base |

3 | 5 | arpTab[5] = 2 | Base + y param |

4 | 4 | arpTab[4] = 1 | Base + x param |

5 | 3 | arpTab[3] = 0 | Base |

6 | 2 | arpTab[2] = 2 | Base + y param |

7 | 1 | arpTab[1] = 1 | Base + x param |

0 | 8 (timer recycled at zero) | Skipped | Base |

1 | 7 | arpTab[7] = 1 | Base + x param |

2 | 6 | arpTab[6] = 0 | Base |

... | ... | ... | ... |

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.