*.AMS Velvet Studio pattern decoding
Comparing the algorithm with the one in Open Cubic Player and with Velvet Studio https://github.com/Patosc/VelvetStudio/blob/master/Code/AMS_LOAD.ASM line 402 a minor detail seems to be missing
First byte in a row with value 0xff is special - meaning that the row is empty.
This is not documented the format documentation of Velvet Studio. Please test this against real Velvet Studio module files (can be found on https://modland.com/pub/modules/Velvet%20Studio/ )
The same fix needs to be applied to the other AMS loader in the same file (see e.g. target em.ams). And for the sake of consistency, the ModPlug code base uses uppercase hex literals.
For me, many of the ams files from modland don't play already, with or without this - their durations reported something close to 0...
As discussed before in another issue or PR, ModPlug's AMS loader is had many deficiencies (including memory safety issues which I believe have been addressed in the meantime); it's one reason why I completely rewrote it for OpenMPT.
The same fix needs to be applied to the other AMS loader in the same file (see e.g.
target em.ams). And for the sake of consistency, the ModPlug code base uses uppercase hex literals.
You seem to be correct, I will update PR later tonight or tomorrow
I updated that Extreme's Tracker parser uses the same 0xff == no data on row.
I also tried to fix Velvet Studio parser with known good logic from Open Cubic Player. Please note that I have not compile-tested the code since I do not use libmodplug - only used it as code-reference.
Velvet Studio files that uses multiple commands on the same channel/row coordinate will not playback correctly due to libmodplug only supports one command per channel/row location (unless I have missed something)
unless I have missed something
That's mostly correct, there is also the "volume column" which supports a smaller set of effects (like in S3M/IT/XM). OpenMPT, based on the same code, solves this problem by juggling around commands between those two columns, but all of the supporting code for that is completely missing in libmodplug, so probably not worth doing here.
I pulled this into my fork, and also ported to the libmodplug version embedded in SDL_sound. Let's see how it goes.