View Issue Details
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0001519||OpenMPT||File Format Support||public||2021-11-21 02:21||2021-11-26 17:39|
|Reporter||teimoso||Assigned To||Saga Musix|
|Product Version||OpenMPT 1.30.00.* (old testing)|
|Target Version||OpenMPT 1.30.01.00 / libopenmpt 0.6.0 (current stable)||Fixed in Version||OpenMPT 1.30.01.00 / libopenmpt 0.6.0 (current stable)|
|Summary||0001519: OPL Export: vgm/vgz files don't loop if Bxx/Cxx command goes to 1st pattern, 1st row of song|
"Song" refers to the only song in a module file as well as one of multiple subsongs in a module file.
A song exported via "Export OPL Register Dump..." to the
|Steps To Reproduce|
A module file and matching set of
The included MPTM file demonstrates the issue and two workarounds across three subsongs. I don't know if exporting from an S3M file also exhibits the problem.
Subsong 1: One pattern, loop to 1st pattern & 1st row; bad export
The first subsong is a "standard" loop. It's a 24-row pattern, and
Subsong 2: Two patterns, loop to 2nd pattern & 1st row; okay export
The second subsong is similar, but has two patterns: the first is an empty 1-row pattern; the second is a 24-row pattern, and a
Subsong 3: One pattern, loop to 1st pattern & 2nd row; okay export
The third subsong is similar to the first, but is a 25-row pattern; it has an additional, empty row at the start, and has
|Tags||No tags attached.|
|Has the bug occurred in previous versions?|
|Tested code revision (in case you know it)||r15998|
vgm-loop-sample.zip (2,042 bytes)
Yes, this was a deliberate design decision because there isn't really a way for the engine to know right now if a song looped back to the first pattern, first row becuase it "legitimately" reach the end of the song or if there's a loop going back. Rather than having all the songs that are not even supposed to loop have a bogus loop (which I expect to be the majority of songs), I decided that it's easier for the people that need their full song to loop change the exported VGM file instead.
Thinking about it again, we could probably query the
I've also noticed incorrect sounding playback after exported files loop, like notes not being released or instruments' timbre/volume/pitch changing; is that expected? They're loops exported by OpenMPT, not manually edited ones.
That may be a side effect of OpenMPT only writing a diff of registers (otherwise the exported files would be much bigger). I guess this could be worked around by emitting the complete current register state at the loop start.
r16003 writes the loop data now even if a song loops back to its first position if the break-to-row flag was set.
I will look what I can do about the register state at the loop point, but it might not be quite as simple.
r16004 contains an experimental change that dumps the complete register state on loop. I really don't know if that's better than the previous situation because you just replace one sort of artifact with another, like with the attached song.
oplLoop2.zip (285 bytes)
In case it's helpful, here's a MPTM file with exported
vgm-loop-sample2.zip (1,964 bytes)
Yes, those would be fixed by r16004, because all channels will be reset to exactly the same state they were in at the first iteration of the loop. This is a compromise - as mentioned, it will cause some artifacts in the module I attached that weren't there previously, but there is no perfect way to handle this because VGM loops don't work like MOD loops where you can have an instrument keep playing across the loop boundary and then start modulating it (e.g. fade it out) after the loop start, unless this fade-out was already there on the first iteration of the loop.
Okay, it doesn't quite fix the first subsong because there simply is no pre-existing register state on channels 2-4... This is more compelex to solve.
I think I have a workaround for the first subsong. One not-so-nice thing about it is that it now increases the size of any looped VGM by 702 bytes for a full register dump.
r16006 now writes the current state of all registers at loop start - to be precise, only those registers that are ever used in the song at all. So if the song only uses one channel, the register dump for the remaining 17 channels is omitted.
Meant to respond yesterday, sorry. Using r16007 (auto-update is very convenient)...
Thanks for looking into this.
Yes, that's the "you can't have your cake and eat it too" scenario: OpenMPT can either let the user take care of resetting all registers on loop start so that notes lingering from the loop end can keep playing (which is how it was before), or it can make sure that all registers are always in the same state at loop start as they are on the first run of the loop (the new behaviour). This is simply a limitation of how loops work in VGM. Either of the two scenarios can work but not both at the same time. The only remaining alternative would be to only reset the registers of each channel once there is a new note being hit on that channel, but that would make the code considerably more complex for very little gain (and you could still break it in various ways, such as executing a pitch slide at the start of the loop with different notes right before the loop start and right before the loop end - the pitch slide would always use the same pitch as the note before the loop start). I'd rather teach users to make sure that there's no instrument change across the loop point (or at least the instrument change has to be consistent before the loop start and before the loop end).
|2021-11-21 02:21||teimoso||New Issue|
|2021-11-21 02:22||teimoso||Note Added: 0004904|
|2021-11-21 02:22||teimoso||File Added: vgm-loop-sample.zip|
|2021-11-21 09:56||teimoso||Steps to Reproduce Updated|
|2021-11-21 09:56||teimoso||Additional Information Updated|
|2021-11-21 11:21||Saga Musix||Note Added: 0004905|
|2021-11-21 11:30||Saga Musix||Note Added: 0004906|
|2021-11-21 11:31||teimoso||Note Added: 0004907|
|2021-11-21 11:41||Saga Musix||Note Added: 0004908|
|2021-11-21 11:45||Saga Musix||Note Added: 0004909|
|2021-11-21 11:55||Saga Musix||Note Added: 0004910|
|2021-11-21 11:55||Saga Musix||File Added: oplLoop2.zip|
|2021-11-21 11:55||Saga Musix||Assigned To||=> Saga Musix|
|2021-11-21 11:55||Saga Musix||Status||new => feedback|
|2021-11-21 12:00||teimoso||Note Added: 0004911|
|2021-11-21 12:00||teimoso||File Added: vgm-loop-sample2.zip|
|2021-11-21 12:00||teimoso||Status||feedback => assigned|
|2021-11-21 12:04||Saga Musix||Note Added: 0004912|
|2021-11-21 12:04||Saga Musix||Status||assigned => feedback|
|2021-11-21 12:14||Saga Musix||Note Added: 0004913|
|2021-11-21 12:47||Saga Musix||Note Added: 0004914|
|2021-11-21 14:29||Saga Musix||Note Added: 0004915|
|2021-11-22 18:24||Saga Musix||Note Added: 0004917|
|2021-11-22 20:11||teimoso||Note Added: 0004919|
|2021-11-22 20:11||teimoso||Status||feedback => assigned|
|2021-11-22 20:25||Saga Musix||Status||assigned => feedback|
|2021-11-22 20:25||Saga Musix||Note Added: 0004920|
|2021-11-22 20:26||Saga Musix||Note Edited: 0004920|
|2021-11-26 17:39||Saga Musix||Status||feedback => resolved|
|2021-11-26 17:39||Saga Musix||Resolution||open => fixed|
|2021-11-26 17:39||Saga Musix||Fixed in Version||=> OpenMPT 1.30.01.00 / libopenmpt 0.6.0 (current stable)|
|2021-11-26 17:39||Saga Musix||Target Version||=> OpenMPT 1.30.01.00 / libopenmpt 0.6.0 (current stable)|