jombo23 / N64-Tools

N64 Tools
The Unlicense
239 stars 113 forks source link

Loop unrolling behavior with Goldeneye 007 #49

Open mmontag opened 1 year ago

mmontag commented 1 year ago

Hi, I am curious about the intended behavior when exporting MIDI songs containing looped segments. Is there a way to control this behavior? It appears some loops are not unrolled:

so I wrote some MIDI event stream transform to handle CC 102 and 103; however...

You can try this link to see them in player context GoldenEye 007 (SF2) - GoldenEye 007 (U) 0000000B 00420B2C.mid (subject to change).

@L-Spiro - if you've succeeded in interpreting these exports, do you have any hints?

L-Spiro commented 1 year ago

Some loops appear to be unrolled by the MIDI exporter automatically and the others are for looping the tracks. You can’t tell which is which from the MIDI export alone, so you have to write something to load the accompanying debug data and extract the required information from there, and it’s complicated.

You have to find the 255 loops inside the MIDI files: https://github.com/L-Spiro/Nintendo-Synthy-4/blob/main/NS4/Src/MIDI/NS4MidiFile.cpp#L736 And in order to make use of them you have to keep track of the event times for every event you find in the debug file: https://github.com/L-Spiro/Nintendo-Synthy-4/blob/main/NS4/Src/MIDI/NS4MidiFile.cpp#L727

Once I find a “Count 255 LoopCount 255 OffsetBeginning XXX” line I go into quite the algorithm in order to find the loop point that matches it. The logic there is very picky because there are cases where there are 2 loop-point events in a row and a few other special cases that threw off all previous logic I coded. This is the only reliable way to pair them. When you find a match you can just delete every other loop point, as they will complicate any further parsing you do of the MIDI data.

mmontag commented 1 year ago

Okay, this looks complicated indeed, but very helpful. I guess the debug text is critical. So the "255 loops" are the ones for looping the tracks (infinite)? Other (finite) loops are unrolled by the N64 Tool, but not those? Thank you!

mmontag commented 1 year ago

For my purposes, I will write a script to clean up the MIDI output of the tools, using the debug output as @L-Spiro described. However, I don't think that's a great situation, and the issue still stands as a bug.

I think we should fix the problem in source, which means (if I understand correctly?) omitting CC 102 and 103 for all of the unrolled loops - and leaving only the outer track loop markers.

As I understand it, 99% of the time, these outer loop markers will be at the same tick for all tracks, except for a handful of songs with atmospheric effects where track desynchronization is intentional. So, that is the reason for using proprietary per-track loop points instead of conventional MIDI loop markers. Hmm...

Is it possible to build this stuff in Visual Studio 2022 Community edition?

L-Spiro commented 1 year ago

I think we should fix the problem in source, which means (if I understand correctly?) omitting CC 102 and 103 for all of the unrolled loops - and leaving only the outer track loop markers.

This would be ideal.

As I understand it, 99% of the time, these outer loop markers will be at the same tick for all tracks, except for a handful of songs with atmospheric effects where track desynchronization is intentional. So, that is the reason for using proprietary per-track loop points instead of conventional MIDI loop markers. Hmm...

Not really “just a handful.” Both Graeme Norgate and Grant Kirkhope often took advantage of the per-track looping to auto-loop short percussion segments (bongos/congas usually, other times hats and various). See Archives tracks 4, 15, and 16. Graeme would periodically straddle his loop points so that they all have the same duration but a few tracks would start maybe 2 bars later (adding variety to those tracks at the end). And there is even a simple mistake by Grant in Control where he set the loops on a few tracks off by 1 (68.4.4.118 instead of on 69.1.1.0). So I would strongly recommend against basing any assumptions off the alignments of the loops across tracks.

Is it possible to build this stuff in Visual Studio 2022 Community edition?

No, only Visual Studio 2008 as far as I know. I committed a How to Build.txt along with updated build settings that make most of the information in said file obsolete, but it still lists prerequisites.

mmontag commented 1 year ago

per-track looping to auto-loop short percussion segments (bongos/congas usually, other times hats and various)

Ah, you're right. I was writing under the assumption that N64-Tools would always unroll those, but it doesn't. (And shouldn't...?)

L-Spiro commented 1 year ago

Ah, you're right. I was writing under the assumption that N64-Tools would always unroll those, but it doesn't. (And shouldn't...?)

It shouldn’t. Those are the magical 255 loops.

SubDrag commented 1 year ago

It will work for Visual studio community 2022. If you are compiling for a later visual studio (Beyond Visual Studio 2008 SP1) for N64 Midi Tool or N64 Sound Tool, all you need to do is update targetver.h, such as replacing it entirely, like below in all of those files. You also may need to remove vld.lib (visual leak detector) from some Linker->Input if you don't have it installed or it's not working for that version of Visual studio. I do not believe N64 Soundbank Tool works in later versions due to DirectMusic.

pragma once

ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.

define WINVER 0x0603 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.

endif

ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.

define _WIN32_WINNT 0x0603 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.

endif