NSF(e) loop chunk idea, and "time" chunk clarification request

Discuss NSF files, FamiTracker, MML tools, or anything else related to NES music.

Moderator: Moderators

Post Reply
NewRisingSun
Posts: 1510
Joined: Thu May 19, 2005 11:30 am

NSF(e) loop chunk idea, and "time" chunk clarification request

Post by NewRisingSun »

NSF(e) provides the time and fade chunks to indicate how long a song should play or fade. These fields are filled by the NSF(e) author, who necessarily has to incorporate a preference regarding how often a song should loop before it starts to fade, and how long the fade has to be. A common convention is to play for two full loops, but that behavior not universally shared or liked, and the NSF(e) format does not dictate a convention.

An alternative method of specifying loop and fade time would be to specify the loop end point and the loop duration. It would be the listener who then could specify in the NSF player's settings dialog how many loops to play and how long to fade. This is the method that the VGM format uses.

NSF(e)'s chunked structure means that both methods could be supported. The existing "time" and "fade" chunks would remain, but two additional chunks could be added: "lopd" for "loop duration" in milliseconds, and "lope" for "loop end" in milliseconds from the start of the song when the song data starts to repeat to an earlier point. In the presence of "lopd" and "lope" chunks, a player could be set to override the "time" and "fade" chunks with the aforementioned behavior.

Opinions?

I also have a clarification request: The existing specification of "time" and "fade" in milliseconds raises a question for dual PAL/NTSC tunes where the PAL behavior does not, or not fully, compensate for the speed difference, which means that a song duration in milliseconds would be different for PAL vs. NTSC playback. Do the milliseconds refer to the NTSC or PAL duration in the case of dual-speed tunes? Of course, there is no question about that for "just NTSC" or "just PAL" files.
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: NSF(e) loop chunk idea, and "time" chunk clarification request

Post by rainwarrior »

I don't understand the reason for two different loop chunks. What is a "lopd" chunk supposed to do if there isn't a corresponding "lope" or vice versa? I think this should just be one "loop" chunk that contains the complete information for the loops. Though, I'm curious why it's loop duration+end and not either start+duration or start+end? Isn't it more usual to give a start point?


As for the clarification... there was never a specification for how we might apply times differently for multi-region NSFes. I'm not sure that Disch ever actually made any multi-region NSFe rips. Every multi-region NSFe I've worked with had equivalent timing for both, so it hasn't come up for me, personally.

If you need this, I guess I'd suggest making some sort of region-specific time chunk, like "timr" or something that starts with a region byte (suggest: the same bitfield as the "regn" chunk), and then is otherwise identical to "time". This would just override "time" if the given region is active. Maybe you'd want to use such a thing for the proposed loop chunk as well.

Would fade need the same thing? I never really understood why someone would want to specify a fade time. That seems more suitable for a player/user setting. I wouldn't imagine that even with different region timing that the fade would need to be different... but if you need it, new chunk I guess?

Alternatively, you could just not use multi-region for that case and release 2 different NSFes. That would be fully compatible with any old players.


As the format goes, if you want to add features to it, you can either add new chunks, or edit existing ones in a way that's fully backward compatible. Any new chunks that aren't flagged as mandatory will be ignored by older players.
NewRisingSun
Posts: 1510
Joined: Thu May 19, 2005 11:30 am

Re: NSF(e) loop chunk idea, and "time" chunk clarification request

Post by NewRisingSun »

rainwarrior wrote:I think this should just be one "loop" chunk that contains the complete information for the loops.
Oh yes, that is even better; there is no restriction in this format that a chunk may only contain a single piece of information, after all. :)
rainwarrior wrote:Though, I'm curious why it's loop duration+end and not either start+duration or start+end? Isn't it more usual to give a start point?
VGM has a start point+duration, since it starts to loop upon encountering the end of the song data, which is not known to the NSF player as it has no insight into the format of the song data. One could either denote end point+duration or start point+end point; I went with the duration variant since it avoids the possibility of nonsensically specifying a start point that is later than the end point.
rainwarrior wrote:As for the clarification... there was never a specification for how we might apply times differently for multi-region NSFes.
Yeah, I suspected so. I asked because the subject may have come up before in a non-public setting, or the solution may have been obvious in a way that I had not thought of.
If you need this, I guess I'd suggest making some sort of region-specific time chunk, like "timr" or something that starts with a region byte (suggest: the same bitfield as the "regn" chunk), and then is otherwise identical to "time".
That would certainly work, and yes, it would be necessary for fade as well. I am pondering an alternative to having to specify all time and fade durations a second time, by specifying some sort of region-specific factor, e.g. 1.2 for non-speed-adjusted PAL playback.

The context in which this came up is my desire have a single NSF file that covers all released regional variants of a game. For example, Mega Man 2 in its PAL version does not have the speed of its music adjusted for PAL, but it has the pitch adjusted for PAL. I would create a multi-region NSF whose INIT routine selects between two pitch tables based on the selected region, and leaves the tempo as it is, just like the game does. This would result in longer song durations in the PAL region than in the NTSC region.
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: NSF(e) loop chunk idea, and "time" chunk clarification request

Post by rainwarrior »

From my perspective, start+end is easier to understand for the user.

Usually when I've been working with this stuff, I have a render open in an audio program, and select the loop in that. Start and end are what I'm naturally working with. Duration is only understood as a calculated difference.

Generally I'd rather the metadata in these chunks be human-readable, if possible, for the sake of people trying to make tools for this stuff and for people trying to understand the data as they implement a player. The player program is good at doing calculations like duration, but the human less so.

I don't think start >= end is nonsensical? We'd also need a way to specify no-loop, and that seems a fine way to do it. Probably start = end would be a good canonical way.
Post Reply