SGI Audio Tools

Introduction
TODO

Prerequisites
This article assumes you're familiar with the following terms/concepts: If you're a bit unfamiliar, a quick search, tutorial, or Wikipedia skim should suffice.
 * Audio samples
 * Sample rate
 * MIDI
 * Linear predictive coding
 * AIFF format
 * the PATH environment variable (for program quick access)

This article assumes you have the SGI Audio Tools as part of the Nintendo 64 SDK. The programs in particular you're going to need are:

This article also assumes that you're using the aforementioned programs in a Windows 95-like environment. An emulator, such as Oracle VirtualBox works fine too.

The n64decomp project has decompiled  and   here. It's possible to build those two particular programs yourself and run them in the environment of your choice, which might make your life a little easier!

A good warm-up for this article might be to compile and run the  NuSystem sample, as it's more or less a "hello world" that plays the sort of audio files we're looking to generate. Keep note of the Makefile including the audio library and the spec file adding the,  , and   files to the ROM. If you're able to compile/run, even in an emulator, you'll be in a good place to test/debug/iterate an issues that pop up in your program.

Converting Your MIDI File(s)
MIDI files are generally either Type 0 or Type 1. The former specifies all of the notes in a single "track" while the latter has multiple tracks, typically for each instrument. The SGI tools require MIDI files to be in Type 0 and provides the  tool to convert to it.

Programs such as MuseScore likely export in Type 1, so it's usually a good idea to convert to Type 0 before continuing.



For each of your original MIDI files, run the following:

is the name of the converted file in this example.

Compressing Your MIDI File(s)
Once your MIDI files have been converted to Type 0, we'll be converting them to a compressed sequence format specialized for embedded playback on the Nintendo 64.

The NuSystem library is written to use compressed MIDI files for songs. If you inspect the library, you'll notice that it uses a  for storing/playing songs. It is possible to use uncompressed Type 0 MIDI, but you'll need to look into editing/rebuilding NuSystem or your own audio code with Nintendo's core audio library.



For each of your converted MIDI files, run the following:

You'll now have various  files for each of your songs.

Compiling Your MIDI File(s)
Now that we've compressed each MIDI file, its time to compile them into one "song bank". This will be added to your ROM and loaded in at runtime. To do this, we'll be using the  tool.

Run the following command with each of your  files as parameters.



The ordering is important here! Keep note of the order of each parameter, as when you're selecting your songs in your game's source code, you'll be indexing them as they're ordered here (eg:  will be , second_song_compressed.cmf will be  , etc.).

Note the lack of space between the  flag and the output file name. This seems to be intended. 🤷

Converting samples with SoX
SoX bills itself as the Swiss Army knife of sound processing programs. Its uses include (but aren't limited to) converting audio between formats, providing effects, and even recording. Given that SoX is an open-source tool, it's well worth including into any game developer's setup.

The  and   tools require audio samples to be in AIFF or AIFC. If the samples you're using are in a different format, such as WAV, you can use SoX to batch-convert your samples. It's also a good idea to resample each effect to the same sample rate, such as 32000Hz. If you're generating your instrument bank file via a script, you can hardcode the sample rate which will let you spend less time coding/debugging.

If we want to convert an arbitrary WAV file to AIFF with a sample rate of 32000 and in mono we can enter:

This article assumes that the reader is converting their files to AIFF with SoX.

Creating a code book for each file
You'll want to create a code book for each AIFF sample you want to use in your song. To do this, you'll run the  command on each of your samples and save the output of that program to a file.

For clarity, we'll be suffix-ing each code book with  but it's not necessary to do.

On each of your samples, run the following:

It's worth noting that by default  will print to. The  operator for writing to a file should work both on Unix-like and Windows here.

Compressing each sample
Once we've created our code book(s), we'll want to convert our AIFF samples to Nintendo's compressed AIFC formats. To do that, we'll be using.

On each of your samples, run the following:

The following  file(s) will be compiled in to make a sound bank.

Before we Begin
This is likely the most tricky and confusing parts of the SGI Audio Tools, so be sure to take a break if you're finding yourself frustrated. Take comfort in that what you're feeling is pretty normal, and that others have been in the same spot.

Section 18.1.12 of the Nintendo 64 Programming Manual is a pretty comfortable overview of what each section of an instrument bank file does. It's not "correct" in certain areas though, and copy/pasting the shown examples won't always work with. A particular example is that the manual says to reference each instrument in your  section with   when in fact you'll need to use   instead.

If you're looking for a reference of a working instrument bank, it's best to check the example banks at  included with the SDK. They'll run through  fine and help clarify things for you.

The Instrument Bank File
An instrument bank file usually has the file extension of. In it are one or more of each of the following:
 * section(s), indicating an ADSR
 * section(s), indicating the range of "piano keys" a sound occupies, as well as other data
 * section(s), indicating a sampled sound and the  and   it uses
 * section(s), indicating a "MIDI instrument" with a volume, pan, and various  s
 * A single  section, indicating the sample rate, and which  s correspond to which MIDI instrument numbers in your sequences

A very simple example
TODO

Finishing up
Once we've completed the steps above, we should now have the following:
 * A  that consists of our converted/compressed MIDI sequences
 * and  files for our samples

We'll be including the above files into our ROM's spec file, then requesting the audio library to load and play them.