Skip to content

Reproducing N64 OSTs accurately

Tom M edited this page Oct 23, 2022 · 10 revisions

ANMP supports playing tunes from N64 games. This page gives an introduction on two different approaches for doing that.

Emulating the game - lazyUSF

In the very beginning when people were trying to find a way to retrieve the OST of an N64 game, hackers and geeks said: Hey, let's just take the game itself, strip away everything that is not needed for playing music and create save-dumps that play back all the single tunes when fed into the "stripped ROM". This is when (mini)USF was born. Today, USF files are available for all publicly released N64 (except some 64DD exotic ones). But, since USF contains the actual game (MIPS program), you need an emulator for it to make it play. Therefore, lazyusf and lazyusf2 are provided (the first based on Project64, the latter based on mupen64plus). To make ANMP understand USF, you need to compile ANMP against lazyusf2. If you're looking for a standalone commandline program, then go for lazyusf instead (it may be buggier than lazyusf2).

Re-synthesizing the sequenced audio of games

MIDIs + SoundFonts

The sound quality output of the games itself is... well... it has room for improvement. Many games are only rendering at 22kHz. Thus the same hackers began to reverse engineer the actual format the music was stored in. It turned out (little surprising) that many games used sequenced (=MIDI-like) audio, rather than streamed audio. This means that the quality could be significantly improved if the sequence is synthesized at a higher samplerate. Unfortunately, it is extremely difficult to convince the game itself to render at higher samplerates. (That's because the samplerate was used as C macro in various places all over the source code, i.e. it was not only used for setting the RCP's AI output rate, it was also used to compute delay-lines of effects like reverb - and since it was a macro, no (direct) trace of it is left in the game due to constant folding of the compiler).

So, since we cannot do it inside the game, let's extract the sequence and re-synthesize it outside the game. To get an original music recreation, you need the soundbank as well. The one and only tool for that is Subdrag's N64 Sound Tool.

Just use Subdrag's tool to extract the sequence of any N64 game and store it as standard MIDI files. Extracting the soundbank, tweaking the soundbank's ADSR envelopes in order to get an exact reproduction of the OST is the difficult part. I've already done it for my favorite Rareware games.

For ANMP, simply put the MIDIs and the SoundFont (sf2 or dls) into a folder, rename the soundfont to the name of the folder it's in and ANMP will automatically use that soundfont for synthesizing all MIDIs in that folder. If a single MIDI A.mid needs a specific soundfont, simply name that soundfont A.sf2. So that A.sf2 will take precedence of the folders soundfont.

Under the hood, ANMP uses fluidsynth as synthesizer. Since the volume response of the SF2 synth model does not match the one of the N64 software synth, I'm using fluidsynth API to manipulating the SF2 default modulators. As of today, this affects all MIDIs, also regular GM MIDI files, which may sound different (or worse) when applying the N64 volume response curve. Additionally to the volume response, I've made some custom modifications to how MIDI files are interpreted, see the wiki. Effects, like reverb, are also a hard part to reproduce correctly, but I've found a setup that works quite acceptable, at least for Rareware games, see the section below.

Ultra64 compressed MIDI format + SoundFonts

While the previous approach works quite well, it has a major unfixable limitation: MIDI only supports 16 channels. Banjo-Tooie, however, uses up to 32 channels in a single sequence. This is why I decided to natively support Nintendo's proprietary format for sequenced audio. The same format that they used in the N64 SDK, and the same they advised developers to use for their games back then.

Fortunately, all of Rareware's games make use of this "Ultra64 Compressed MIDI format". Files that contain sequences in this format must have the extension .cmf. Except for Banjo-Tooie, where Rareware had to change the header of the CMF, but since there is no way to detect this programmatically, I just used .btmf as an extension for Banjo-Tooie sequenced format.

To obtain this "native" sequenced audio format, simply use Subdrag's tool again, this time exporting as ".bin". Note that there is no guarantee that this BIN file actually contains audio in the CMF format. In fact, many games developed at Nintendo HQ use custom formats; apparently, Nintendo's developers had a lot of time (or fun) re-inventing the wheel again.

Tuning the reverb

The following reverb settings work quite well for Rareware's N64 games, I suggest you apply the following settings to fluidsynth >= 2.1.0:

Reverb:

  • roomsize: 0.65
  • damping: 0.0
  • width: 1
  • level: 1

Alternatively:

  • roomsize: 0.8
  • damping: 0.1
  • width: 1
  • level: 0.8

Alternatively:

  • roomsize: 0.7
  • damping: 0.1
  • width: 100
  • level: 0.3

Alternatively:

  • roomsize: 0.8
  • damping: 0.4
  • width: 0
  • level: 1