-
Notifications
You must be signed in to change notification settings - Fork 24
Looping
Before you can understand looping, you need to understand sections. (This is a different concept than the "sections" of a sequence corresponding to data for the sequence header, different channels, or different tracks.) A section is a grouping of time within a sequence that the playback engine can jump to the start of. Many sequences in popular N64 games--e.g. 0x05 Water Theme
in SM64 or 0x5F Gerudo Valley
in OoT have them. Select the sequence header and look for a bunch of Absolute Chn Ptr (or, rarely, Relative Chn Ptr) commands all grouped together. The address of the first of these commands is the beginning of the section. In between the groups of pointers there will always be at least one Timestamp command, plus usually a few other things like Tempo. If you can get the sequence header playback head to jump to the address of the first pointer command, the music will immediately start playing that section, and of course it will go on to later sections once the timestamp(s) for that section have elapsed. Thus, customizing looping behavior is a matter of setting up commands which cause the sequence to jump to one of these sections at the right time.
By default (if the Create command to loop whole sequence
option is checked), when you import a MIDI file, SEQ64 adds a Branch Abs Always command after the end of the last section, pointing to the address of the first section. Thus, when playback gets to this point, the song will start over from the beginning. If you don't want the song to loop, simply delete this command. If you want it to loop but you want it to skip the intro section, change the address parameter of the Branch Abs Always command to the address of the first Absolute Chn Ptr command in the section you want it to loop back to.
Some sequences in Ocarina of Time have complicated "programs" written in the "programming language" included in the sequence file format, which read data from a signaling buffer in memory and jump to particular sections when the song is first started. They also include commands to save back the current position within the song--the last section heard--to the same signaling area, so that later the song can be restarted from here.
So, the only thing left is to tell SEQ64 where you want section boundaries in your MIDI file. You do this using Meta (text) events of type 6 (Marker
type), where the text is Section X
(X is the section number--actually, the value of X is ignored, the markers are simply sorted by time). So, if you want to make a song with an intro and a loop, add a marker at the loop begin time with text "Section 1", and then SEQ64 will arrange the data into two sections at import time, one containing all the music up until your marker and one with all the music afterwards. Then, just change the Branch Abs Always command to point to the second section, rather than the first.
These commands allow repeated data--notes or anything else--to take up less space in the ROM. The syntax is a Loop Start
command with the number of times the data repeats, and then the data, and then a Loop End
command. The playback head for that section (header/channel/track) reads the data through that many times, as if several copies of it had been written out sequentially. The timing is also repeated, of course: if you have one measure of 4 quarter notes and then set them up to loop 4 times, that will take a total of 4 measures.
When importing a MIDI, if the Use Loops
option is enabled, SEQ64 automatically scans the imported sequence data for repeated commands, and turns them into loops to save space. Together with calls--which allow new sections to be made and then called from multiple places like a subroutine--these provide significant compression and space savings in imported MIDIs. These commands are actually supported by all games that use this sequence file format, but none of the sequences in these games actually use them (evidently Nintendo's own MIDI import tool didn't support them). I discovered them through translating the routines in OoT which read the sequence data from assembler to C. Thus, SEQ64 can actually take existing sequences in these games, export them to MIDI, and then import them and have them be slightly smaller than they originally were, without losing any data.
While you can put Loop Start
and Loop End
commands around a section in your header track and it should work (set the number of repeats to 0xFF to repeat forever), the method described above is the recommended way to have your sequence loop.