Skip to content

Instantly share code, notes, and snippets.

@owlisnotacat1
Last active May 31, 2025 09:17
Show Gist options
  • Save owlisnotacat1/e5445c154b46a9d7804b139800dfffbe to your computer and use it in GitHub Desktop.
Save owlisnotacat1/e5445c154b46a9d7804b139800dfffbe to your computer and use it in GitHub Desktop.

Creating a Custom Instrument Bank

For This tutorial I will be using Seq64 V1 which can be found here

If you plan on using a vanilla bank instead of a custom one skip to the end of the tutorial and follow those steps.

Things you will learn how to do:

  • make a custom instrument bank for OoTR
  • make a custom instrument sample for OoTR
  • make a .ootrs file

What Everything Does In Seq64

Screenshot 2023-04-28 180331

When you open seq64 it will look like this, what you want to do is select "Rom" in the top left corner and open an OoT 1.0 Decompressed rom.

After you load the rom You will want to load the Rom Desc, to do this select the "RomDesc" option in the topleft and open "oot_v1.0_info.xml" from the root of the Seq64 folder.

Now Seq 64 will look like this.

Screenshot 2023-04-28 181032

Now you will load a pre-existing bank from audio bank index. Depending on if you want to use a percussion set or not you will want to load a specific bank preset, usually this will be bank 0x03 Main orchestra, but you can use other banks percussion sets.

Something to take note of is that the banks for jabu jabu and spirit temple have their own unique audio table so if you want to use the percussion from these sets use these preset XMLs I made here.

Screenshot 2023-04-28 232355

After you load a bank (in this case i used 0x03 main orchestra) you will see some options such as:

  • abindexentry
  • abheader
  • abbank
  • abdrumlist
  • sfxlist
  • instruments
  • drums
  • sfx
  • envelopes
  • samples
  • aladpcmbooks
  • aladpcmloops

These all contain vital information for the bank to work properly except for:

  • abindexentry
  • abheader
  • absfxlist

The first two are determined at the rom import and the 3rd one is for actor sfx so not usefull in this case.

AB Bank

Screenshot 2023-04-28 233358

Inside abbank you will find:

  • drumptr (this is useless)
  • sfxptr (this is also useless)
  • instlist

Instlist is the important one here, this is where you set what instrument plays from what midi program.

Screenshot 2023-04-28 234247

Above you can see that piano is set to 13, thats the program number you would set a midi channel to if you wanted it to play the piano. You set the instruments here by selecting any number in the inst list and setting the index pointer to the proper instrument.

abdrumlist

Screenshot 2023-04-28 234532

Abdrumlist contains the data for the percussion sets which is set to play from program 127 in midi. The drumlist contains 64 entrys in total spanning from key 21 to 84 on the standard midi piano with entry 0 being key 21 and entry 63 being key 84. Here you set the index pointer to the corresponding data in "drums" usually you dont need to change anything in abdrumlist.

instruments

Screenshot 2023-04-28 235212

Here is where you string together all the data necessary for an instrument.

Screenshot 2023-04-28 235343

Here you will find some options titled:

  • unknown1
  • splitpoint1
  • splitpoint2
  • releaserate
  • envelope
  • splits

Unkown 1 will always be 00, splitpoint 1 and 2 are where you set where the instrument changes from one sample to the next. The math for this is the last key of the range you want the instrument to be -21 then set that to the appropriate splitpoint. Splitpoint one sets the change from absound1 to absound 2 and splitpoint 2 sets the change from absound 2 to absound 3 which you can find in "splits. Release rate is where you set how long the sound continues after the note has been released. You can use this desmos graph to visualise the release rate X axis being the release rate in seconds and Y being the release rate value in seq64(shoutout to darkychao from the MMR Discord server for the making this graph). The lower the value the longer the note plays after its been released. Envelope is where you set the volume modulation envelope found in "envelopes" in the root of the bank file. splits are where you set the samples and the tuning for the instrument. You can use up to 3 samples for one instrument.

Screenshot 2023-04-29 000420

The first "absound" is absound 1.

Screenshot 2023-04-29 000707

Inside one of the ABSound entrys will look like this.

"Sample" is where you set the pointer to the sample that the instrument will use as an sound to play (In this case it is set to strings low).

Tuning is where you tune the sample so the pitch is correct. In order to calculate the tunung we first need to get some numbers to calculate with. First you want to know what key the sample is tuned to, then you want to find the frequency of that key. You can find the frequency of your key using this, then you want to find the sample rate of the sample you are using. You can do this with audacity which can be found here.

Screenshot 2023-04-29 001700

You want to open your wav file and you will see in the bottom right corner "Project Rate (Hz)" below is where you will find the sample rate of your wav file (In my case the sample rate is 44100) take note of this number for the tuning math.

now that we have found the frequency of our sample which will be X in the equation and the sample rate which will be Y in the equation we can do some math. The equation for the tuning is {523.25/X * (32000/Y) = the tuning}.

In my case the sample was tuned to key 72, so the frequency was 1046.50 and my sample rate was 44100, so my tuning using the math above should be 0.362811.

drums

Screenshot 2023-04-29 002918

Drums looks very similar to abdrumlist but is different there are still 64 entrys in drums similarly to abdrumlist

Screenshot 2023-04-29 003100

Inside you will find:

  • unknown1
  • unknown2
  • unknown3
  • unknown4
  • drumsound
  • envelope

Drum entrys are similar to instrument entrys but are slightly different. Unknown1 is where you set the release rate, unknown 2 is where you set the panning of the note lower values being left higher right. Unknown 3 and 4 are always set to 0. Drumsound is where you set the tuning and the sample used for the note. The tuning for this is slightly different than instruments here the tuning is the key that you want the sample to be / by the key that the sample is tuned to * (32000/sample rate). Similar to the tuning for instruments but the only thing changed is that the "523.25" is changed to the key you want the drum to play at. Envelope is where you set the volume modulation envelope similar to instruments.

Screenshot 2023-04-29 003846

This is whats inside of one of the drum entrys very similar to absound from instruments.

envelopes

Screenshot 2023-04-29 004213

These are the envelopes which control volume modulation. Im not exactly sure how to properly use these but for most custom instruments you can just use the envelope for an already existing instrument.

Inside the envelopes you will find data formatted like this:

  • AAAA BBBB CCCC DDDD EEEE XXXX YYYY ZZZZ
  • A = attack rate
  • B = attack level
  • C = decay1 rate
  • D = decay1 level
  • E = decay2 rate
  • X = decay2 level
  • Y = ALWAYS FFFF
  • Z = ALWAYS 0000

Shout out to darkychao from the MMR Discord for making this desmos graph that helps visualise what your envelope will sound like ingame. Envelopes can become a bit complicated so for simplification of the guide im not going to go into deep detail.

Screenshot 2023-04-29 004904

samples

Screenshot 2023-04-29 004950

Samples is where the bank stores data for the sample that instruments, drums and sfx use.

Screenshot 2023-04-29 152454

Inside one of the sample entrys you will find:

  • unknown1
  • unknown2
  • samplesize
  • sampleaddr
  • loop = &ALADPCMLoop
  • Book = &ALADPCMLoop

Unknown 1 and 2 will always be 00. Sample size is where you set the size of the sample this can be found by opeining the custom sample that you make using sample creation tools and open it in a hex editor then scroll to the end of the data and copy the length of the sample and copy the legnth to "samplesize" (note the the max size a sample can be is 0x0000FFFF before it will crash the game).

Screenshot 2023-04-29 153312

In this case the sample length would be 0x00001B24.

Screenshot 2023-04-29 153751

Whereas in this case the sample length would be 0x000018C0.

Sampleaddr is where the offset of the sample is set (make sure you have the option for hexadecimal on)

Screenshot 2023-04-29 154603

For custom instruments you make this a value that is found nowhere else in the bank and copy that value to the .meta file like this.

Screenshot 2023-04-29 154811

Screenshot 2023-04-29 155128

You only ever want to change the sampleaddr or samplesize for custom imported instruments.

"Loop = &ALADPCMLoop" is where you set the pointer for what "aladpcmloops" entry the sample uses. Each sample has its own unique "aladpcmloops" entry. It is important that you have this set to the correct entry otherwise your sample might have some audio artifacting, the data that it points to is vital for making the sample loop.

"Book = &ALADPCMBook" is basically the same as "aladpcmloops", but instead contains data needed for the audio system to properly decode the .zsound file properly. It is even more important that this data is set correctly otherwise your instrument will sound awful.

aladpcmbooks

Screenshot 2023-04-29 160516

Inside you will find that it looks very similar to "samples", thats because each sample gets its own aladpcm book.

Screenshot 2023-04-29 161055

Inside one of these entrys you will find:

  • order
  • npredictors (this isnt important at all)
  • book

Order is where you set the number of entrys in book. Most already existing samples in the game only use 2 but z64audio generates 4 arrays so for custom samples you would set this number to entrys in "books" which is usually 4 for custom samples.

Screenshot 2023-04-29 161149

Inside book you will find the ALADPCMpredictors, these are whats required to decode the sample data correctly. As mentioned above it extremely important that these are set correctly. Vanilla samples will only use 2 sets of predictors but custom samples use 4 so if you are using a custom sample you will want to duplicate the predictors so that there are 4 like this.

Screenshot 2023-04-29 161522

aladpcmloops

Aladpcmloops is where you set the data that the samples uses to determine how to loop the audio correctly.

Screenshot 2023-04-29 162045

Inside will also look identical to "samples" and "alacpcmbooks" as each sample is also requires to have its own unique aladpcmloop entry.

Screenshot 2023-04-29 162105

Inside one of the entrys will contain:

  • start
  • end
  • count
  • adpcm_state (this is useless)
  • tail

Start is where you set the point that the sample loops back to once it has reached the end of the sample (this is only if the sample is supposed to loop where you would just set the start to 0). End is where you set the end of the sample (this is always required even if the sample doesn't loop) you can find the data necessary for the loop in the "config.toml" that Z64audio generates when you convert a wav sample.

Count is where you determine if the sample loops or not. if the sample doesn't loop you would set this to 00000000 Vs where if the sample does loop you would set this to FFFFFFFF.

Tail is where the loop predictors go if the sample loops. If the sample doesn't loop you can delete the data inside this, similar to "aladpcmbook" these also have to be set correctly and are unique to each sample.

Creating a Custom Sample and Saving the Instrument Bank

For creating a custom sample I will be using Sample Creation Tools.

Credits to Isghj from the MMR community for putting together these tools.

Screenshot 2023-04-29 163420

Inside you will find:

  • Loopbook BIN to XML.py
  • DropYourWavHere.bat
  • z64audio.toml
  • Book BIN to XML.py
  • z64audio.exe

Screenshot 2023-04-29 164110

You want to drag your custom .wav sample into this folder and drag it onto "DropYourWavHere.bat".

Screenshot 2023-04-29 164240

z64audio will now generate:

  • config.toml
  • samplename.wav.book.bin
  • samplename.wav.loopbook.bin
  • samplename.wav.vadpcm.bin

Config.toml contains the loop start and end everything else is basically useless because the program assumes the your wav is tuned to key C5 (60) and only calculates the tuning by dividing the sample rate of the sample by 32000

Samplename.wav.book.bin is the "aladpcmbooks" predictors in hex. For convenience there is a script that converts the hex into xml format that you can CTRL C-V into a bank xml than import back into seq64. The script for .wav.book.bin is called Book BIN to XML.py. Open the wav.book.bin file with the script and it will generate .wav.book.bin.txt, the contents will look like this.

Screenshot 2023-04-29 165127

You will notice that there are 4 arrays of data, this is where you want to make sure there are 4 sets of predictors in "aladpcmbooks" in the instrument bank in Seq64. The easiest way to copy this data into the bank is to export the instrument bank as a .XML file and open the .XML file in a text editor aswell as open the "wav.book.bin.txt" in another window. you then want to find the name of the aladpcmbooks entry and copy the data into the appropriate areas like so.

Screenshot 2023-04-29 165732

Then save the file.

Samplename.wav.loopbook.bin is similar to wav.book.bin, but there is only one array and also is only necessary if the sample loops otherwise skip over this step. If your sample loops you want to take wav.loopbook.bin and run it through the LoopBook BIN to XML.py script to convert it to xml format and do the same steps from above then save the file.

Screenshot 2023-04-29 170701

Samplename.vadpcm.bin is the raw sound data the only thing we need to do is change the file name to match the ZSOUND name in the .meta file like so. You also want to make sure that the string of hex that follows the zsound name matches the "sampleaddr" from "samples" in the bank in Seq64 and that the hex option is enabled like so.

Screenshot 2023-04-29 171434

Screenshot 2023-04-29 184037

Once this is all done you want to load the xml that you imported the predictors into earlier back into seq64 and save the bank into slot 0x25 like so.

Screenshot 2023-04-29 171807

You want to save the rom to OoTR Zbank Ripper, then drag the rom onto "Drop Rom Here.bat" and it will generate a folder with all the banks on the rom. You want to copy "25.zbank" and "25.bankmeta" and paste that into a new folder that you are going to put all the files for the custom music. Additionally you are going to want to move your sequence file, any zsound files and the meta file that the music uses to the same folder as the zbank file/bankmeta file like so.

Screenshot 2023-04-29 172854

Creating A .ootrs File

If you are using a custom bank you will need to include the .zbank and .bankmeta files aswell as the .zsound files (if used) and change the second line in the meta file to "-".

If you are using a pre-existing instrument bank you only need the .seq file and the .meta file.

You now want to turn these files into an .ootrs file to do this i recommend usind 7-Zip to archive the files into ootrs format like so.

Screenshot 2023-04-29 173137

Select all the files in the root of the folder and right click and select "show more options" then select "7-Zip" and choose "Add to archive". Screenshot 2023-04-29 173327

Screenshot 2023-04-29 173452

Make sure that you change the .zip in the file name to .ootrs.

You Have Now Made A Custom Music .ootrs File For The Randomizer

All thats left to do is move the .ootrs file into the music folder in the randomizer and test the music file to make sure it sounds correct and that the bank doesn't crash the game.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment