Hello! I noticed most music tutorials out there involve using Sappy or other difficult programs, so I decided to write a tutorial for Zahlman's Song Editor, which I use all the time, and it works very nicely. It was originally made for editing music in Fire Emblem, but it also worked well for Fire Red, and presumably this method will work for other GBA games as well.
What you need:
- A GBA Pokemon ROM. This tutorial was written with Fire Red in mind, but if you know the appropriate offsets and such for R/S/E it should work fine there too.
- A MIDI you want to insert.
- A calculator that can do math in hexadecimal. Microsoft Windows Calculator does just fine if you put it in Programmer Mode (Hit Alt+3)
- A program for editing MIDIs. I use Anvil Studio. Google it.
- The Song Editor uses Python, so be sure to have that installed. Get Python 2.7, not 3.x.
- The Song Editor itself - it's at the bottom of this page
- Optional: FreeSpaceFinder or a Hex Editor of your choice
Step 0: Backup your ROM
I highly recommend backing up your ROM just in case you make a mistake, as I have done many times.
Step 1: Preparing the MIDI
First, pick a voicegroup from this list. Then, change all the instruments in the MIDI to instruments that the voicegroup you selected uses. (For info on drums see this thread)
Next, try to reduce the filesize of the MIDI as much as you can by deleting tracks you don't need and cutting out repeated parts of the song since we'll be making the song loop later. Also, make sure all tracks in the MIDI have the same length, otherwise they'll desync after the first loop.
Step 2: Converting the song
Make sure your ROM and MIDI are in the same folder as main.py, then open main.py. The song editor has a command line interface.
First, use the command open romname where romname is your ROM's filename. Note that you do not need to type in the file extension in this program, ever.
Next, use the command convert -l X voicegroup filename to convert the MIDI to a GBA song.
X is the loop point of the song in GBA ticks. (The song loops back to the loop point after reaching the end) There are 24 ticks in a beat. If you're bad at math type the number of beats followed by a colon: the program will do the math for you. If you don't want the song to loop at all, leave out the -l argument.
voicegroup is the offset of the voicegroup you selected earlier. filename is the MIDI's filename, again without the extension. By default the entire MIDI is converted. While I prefer to cut the parts of the song I don't want in a MIDI editor, you can add "-b X -e Y" before the -l argument to specify the beginning (X) and end (Y) of the song, again in GBA ticks.
At this point you can use the command save filename to save the song's binary data to a BIN file. Also be sure to use the command info which will tell you the precise amount of space needed to insert the song - you can then search for that space in FreeSpaceFinder or a hex editor of your choice.
Step 3: Inserting the song
After converting the MIDI, or loading a BIN file, you can use the command burn pointeroffset songoffset to insert the song.
songoffset is where the song is going to be inserted. Find some free space to put it.
pointeroffset is where a pointer to the song will be inserted in the song table. We need to do a little math here, so open your calculator. First look at this list and pick a song to replace. (If you relocated the song table you can use an unused number) Multiply the song's number by 8 and add 0x4A32CC (Which is the song table's location in the Fire Red ROM. If you relocated the song table use its new location instead) and that'll be the number to use for 'pointeroffset'. If this is too complicated you could just put the pointer in free space and edit the pointer in the song table manually as well.
IMPORTANT: After using the burn command, use the command close romname to close your ROM. Changes made are NOT saved until you do so.
Step 4: Test the song
Go to wherever the song plays in the game, and listen to it. I recommend scripting a jukebox or something in the game somewhere that's easy to access for this purpose. If something seems out of place in the song, see if you can find out what's wrong, tweak the MIDI and try again.
Step 5: Profit!
That's the end of the tutorial! Any questions or suggestions, let me know! If you need help, the song editor has a help command as well.
P.S. does anyone know where the song table is in R/S/E? It's probably a good idea for me to list it.