• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Forum moderator applications are now open! Click here for details.
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Adding Songs to FireRed: A Dreadful Tutorial

275
Posts
13
Years
  • Seen Oct 9, 2019
Adding Songs to FireRed: A Dreadful Tutorial

Music sets the tone of a scene. It can add power and substance to a locale. In Ruby and Sapphire, music turned an ordinary mountainous forest into an epic demonstration of nature-based environment design. It has singlehandedly given meaning and impact to some of the most iconic locations in the Pokemon series. (Would Lavender Town have been as memorable without its somber, bereaved melodies?)

Hacking music is extremely difficult. Hopefully, this tutorial will make things a bit easier. Before we start, a disclaimer.

Disclaimer
To be perfectly honest, I'm still learning as I go. There are definitely some better ways to do the things I demonstrate in this tutorial.

Don't take this as a 100% complete, perfect guide. Take this as a music-hacking-newbie's attempt at consolidating several inconsistent, outdated, and hard-to-find resources into one easily-accessible thread. Take this as a place to start your own research and experimentation. A starting place. A stepping stone. It's not the best way to add songs. Heck, it's not even a good way. But it's a way, and hopefully that'll be enough for you to figure out a better way on your own.

(The alternative to this tutorial is many frustrating hours' worth of Google searches. As opposed to this tutorial which, though terrible, is a lot faster and you know in advance that you'll get something out of it. So there's that. :P)

I do plan on eventually getting better with music, and then giving this tutorial a much-needed overhaul.

And now that that's out of the way...

Requirements
Here are the things you will need to follow this tutorial. Do not attempt to install them until you have read the brief notes after the list.

Sappy can be notoriously difficult to install properly. I will provide instructions and download links to it in the tutorial. Links will not provided for Mid2AGB and I would not recommend asking for them. (I've heard that it was leaked from Nintendo's own coding environment. I don't know if that's true. I'm not chancing it.) The rest of the tools should be fairly easy to set up, and instructions for their installation will not be provided in the tutorial.

Installing Sappy
Sappy is one of the key programs used when editing music and sounds in a GBA ROM. When installed properly, it is a fairly good program (though it has a tendency to crash when encountering anything it doesn't expect).

Two steps are needed to install the most recent version. Start by installing version 12, provided by WaHack. The installer for version 12 will set up some key system resources that Sappy needs in order to run. When that installer finishes, run Sappy version 15.

Sappy 15, unlike previous versions, is compatible with Windows Vista and Windows 7. It apparently has received some other enhancements as well. With it set up, you should have no problem viewing GBA music inside of ROMs.

(We will be using Sappy 15 to preview music and to edit the instruments that are heard in music, but we will not use it for actual music insertion. We're doing that manually.)

Finding the song table
The "song table" is a data structure inside of Pokemon FireRed. It is a list of pointers to all songs and nearly all sounds in the ROM. Unfortunately for us, it is sandwiched directly between other parts of the ROM's code; we can't make it bigger without overwriting important data. We therefore have to repoint it -- that is, move it to a different location, and tell the game where we moved it. And to repoint it, we have to find it.

Open your ROM in Sappy. If you are asked to search for a song table, do so.

AQDZLtv.png

You should see this:

d5bVzOo.png

Closing that dialogue will result in this:

EvYfFvp.png

As you can see, Sappy has loaded the song table. We are currently looking at Song 1, which (if I recall correctly) is played when using a healing item on a Pokemon. In the lower-left corner, there is a box labeled "Information". (It may be collapsed; click the chevron to expand it.) Inside of this box is information on the ROM, including the key thing we're looking for: the offset of the song table. In my screenshot, that offset is 0x04A32CC, though it could vary across FireRed versions.

Write that offset down. Close Sappy. Open your ROM in your hex editor, and go to that offset.

IR6bQye.png

Without selecting anything, scroll down until you see eight consecutive 00 bytes. I've marked them with a red line in the image below:

o36co14.png

Hold Shift and click directly after the eighth 00. This will select the entire song table.

GmE52yC.png

Paste the song table's hex data into Notepad.

Repointing the song table
Now that we have copied the song table, we need to find free space for it. At minimum, you will need to reserve the same amount of space that the song table occupied originally. However, you'll want to reserve additional space for new song entries. (If you're not making the table longer, then there's no reason to repoint it!)

Each song entry is eight bytes: a four-byte pointer, followed by four bytes of some kind of metadata. So you can either pick an arbitrary number, or calculate a specific one (a multiple of 8). You can use Free Space Finder to find enough free space, or you can pick an offset that you know isn't used (something after 0x800000 that you haven't stored any data in.)

Scroll to the offset that you have chosen. I am performing this tutorial using an unaltered FireRed ROM, so I will store the song table right at 0x800000. Click at the starting byte of that offset.

v8cgsbm.png

Do a paste write, not a paste insert. A paste insert will make your ROM longer, corrupting it. A paste write will overwrite bytes. Here is my ROM after paste-writing the song table into its new offset:

V0nAcTC.png

Now that we've created a new copy of the song table, we have to tell the game to use it. Scroll to the top of the ROM. Now, remember the old offset of the song table? You need to convert it to a pointer. Split the number into bytes:

4A32CC -> 4A 32 CC

Reverse the order of those bytes:

CC 32 4A

Add an 08 onto the end:

CC 32 4A 08

This is the pointer to the old song table. We need to do the same conversion with the new song table's offset.

800000 -> 80 00 00 -> 00 00 80 08

Now, starting from the beginning of the ROM, search for the old song table pointer. There are five copies of it, which all need to be replaced with the pointer to the new song table.

Important note: Some users have reported that their ROMs become corrupted depending on the order in which the five pointers are changed. I recommend backing up your ROM before changing the pointers. If you experience problems, try changing them again and change the first pointer after changing the other four.


The song table should now be repointed. Open your ROM in VBA and test to make sure. If you get past the title screen, then it works. If it freezes or crashes, then something went wrong.

If it does work, then you can feel free to replace the old song table with free space bytes (FF), as it is no longer needed.

Extending the song table
Extending the new song table is easy enough. All you have to do is add more null entries (eight 00 bytes) to the end. Here, I've extended my table all the way up to, but not including, 0x801000, giving me room for 164 new song entries.

LL8Eg7I.png

Note that the length of the table doesn't determine how many songs you can have. It only determines how many songs you can list. The number of songs you can add is limited by the amount of free space to store song data in.

Telling Sappy where to find the new song table
There is one last thing we have to do before we can actually add music: we have to tell Sappy where the new song table is. Sappy still thinks that it's at the old location; we need to change its mind, by editing its configuration file.

Editing Sappy's configuration file will allow Sappy to open our hacked ROM, but it will prevent Sappy from opening FireRed ROMs that use the normal song table. Because of this, we need to create two copies of the configuration file: one for normal FireRed ROMs, and one for our hacked ROM. We can switch between the two configuration files depending on what ROM we are opening in Sappy.

Go to Sappy's folder and create two copies of "sappy.xml". Name the first "sappy.xml.old", and the second "sappy.xml.hax". Open "sappy.xml.hax". You should see this:

VcdGFFN.png

Find the offset of the old song table, and change it to the new offset. Save.

Now, delete "sappy.xml". Copy "sappy.xml.hax", and rename the copy to "sappy.xml". Sappy is now prepared to open your hacked ROM. To test it, use Sappy to open the ROM with the repointed song table. If Sappy can load that ROM and play songs and sounds from it without crashing, then it worked.

Preparing a MIDI
Next, we have to actually find some music to import. The music must be in the MIDI format, so chances are, you won't be able to use something that's in WAV, MP3, or other normal formats.

VGMusic is a good place to find MIDI versions of popular video game songs. For this tutorial, we will be using their MIDI for the song "Bramble Blast", from Super Smash Bros. Brawl. That MIDI is listed on this page.

We need to use Anvil Studio to edit that MIDI and make it suitable for inclusion in the GBA. Specifically, we need to reduce the number of instrument "tracks" in the song. Download the MIDI, create a copy of it, and then open that copy in Anvil Studio.

zlCh0TY.png

You'll notice that the song has 13 tracks. We need to remove three. If you maximize the Anvil Studio window, you'll see a panel on the right side, which shows a large amount of tick marks. Each row of that panel is like a miniature piece of sheet music, showing the music notes in each channel.

You'll notice that two tracks have very few notes in the song: "Rev. Cymbal" and an unnamed track whose instrument is "Celesta". Right-click on those tracks and delete them from the song. We're down to eleven tracks now.

azNGM0l.png

A close look at the panels reveal that two tracks have the same musical instrument. Tracks 9 and 10 both use "SynthStrings 1". The only differences between them are the notes they play, their volumes, and their "L/R" (how much audio goes to each speaker).

In this case, Track 9 has an "L/R" of 0, meaning that it is balanced between both speakers. It also has the higher volume of the two tracks. So we are going to combine the tracks, keeping the settings in Track 9.

Select Track 9, by clicking in the empty column to its left. In the menus, go to Track -> Merge...

VIVHT2t.png

Anvil Studio will show a dialog box asking which track you want to combine with the selected track. Choose Track 10, and keep the checkbox checked. Click OK.

You'll see that the tick marks from Track 10 were copied into, and combined with, those of Track 9. Delete Track 10; it is no longer needed.

The MIDI is now down to ten tracks. Save the file.

Fixing looping

Real quick: you will need to use Anvil Studio's Compose mode to pad each track to the same length. Otherwise, some tracks will desynchronize with each other when the song loops.

Basically, go to View -> Compose. You'll be able to view each track as sheet music. Find the longest track, and edit every other track. Add rests to the end of those tracks, so that they are all as long as the longest track.

Save the file. Exit.

Converting the MIDI

Here is where Mid2AGB and its component programs become necessary.

Take your modified MIDI file and go to the Mid2AGB folder. Paste the MIDI into the "mid" folder. In the Mid2AGB folder, open TR.EXE. Click the "??" button.

If all goes well, you should see your MIDI file listed in the left column. If it is listed in the right column, then there was something wrong with it, and Mid2AGB was not able to convert it.

Check the Mid2AGB folder again. There should be a new file: song.gba. Open this file in an emulator; you will see the name of your song file, and a person's face in the background. If you press A (or rather, the key that you mapped the A button to), your MIDI will begin to play. The song has now been converted! We just need to transfer it from song.gba into your FireRed ROM.

Open song.gba in your hex editor. Copy all of the data from 0x1B3BB8 to the end of the file; this is the track data. Create a new file (Ctrl+N), and paste the copied data into it. (Your hex editor may warn you that pasting that data will change the size of the new file. Do it anyway.) Save this file using any name you like.

PRkm0G5.png

(The file you are saving contains the track data for the song.)

Use a find-and-replace function to replace all B1 bytes with "B2 00 00 00 00 B1 00 00 00". This is not the usual paste-write, it is a paste-insert. You actually want to change the filesize this time (which is why we copied the information into a separate file). Your hex editor should perform as many replacements as there are tracks in the MIDI.

Finally, go to the end of the file. Delete the ASCII text that shows the original name of your MIDI file, and also delete the four bytes that come immediately before that text. Save the new file.

Transferring the converted song
Once the track data has been altered, copy the contents of the new file. Find some free space in your ROM for the track data. In your hex editor, go to that free space and do a paste-write, not a paste-insert. (In my ROM, I will be pasting to the offset 0x801000.) Write down the offset that you're starting the paste at.

Note that the free space offset should end in 0, 4, 8, or C. Otherwise, the song header (explained later) won't be readable.

n6SIPL3.png

Correcting the track pointers
Before we continue, I'll briefly explain what it is we are about to do.

The data that you have copied into your ROM is track data, followed by a song header. Each track starts with a BC byte, which marks the start of the track. The music data follows. After that is a B2 byte and a four-byte pointer. The B2 acts like a musical "goto" statement, and the pointer after it is supposed to point back to the start of the track. Basically, this is the code that makes the track loop.

Unfortunately, our B2 bytes don't have valid pointers after them; they're followed by 00 00 00 00. We need to change those bytes to point to the next track, and we need to do this for each track.

Go back to the start of the track data; you should find yourself at a BC byte. In your hex editor, search for B2. You should find B2 00 00 00 00 B1 00 00 00. The first four 00s are a pointer. Change that pointer to point to the start of the track.

Search for the next BC byte; this is the start of the second track. Write down its offset. Search for the next B2; this is the loop code of the second track. Change the four 00s after it into a pointer to the second track's BC byte.

Repeat the process for each track in the song, until there are no more BC bytes. Do not, at any point, lose the offsets to each track; keep all tracks' offsets written down somewhere.

Correcting the header
After the last B1 00 00 00, you'll find yourself at the header. (Write down its offset.) The first byte will be the number of tracks in the song; it will be followed by 00 0A 00. Next is a pointer to the voicegroup. After that are pointers to each track. Replace each of the track pointers with the pointers you wrote down earlier.

I2ZS7km.png

Now, we will deal with the voicegroup. A voicegroup is a set of instruments stored in a ROM. Basically, it controls how each track sounds. We will want to pick a voicegroup from the game to test with. There is a list of all voicegroups in FireRed; choose one that has, at minimum, as many instruments as your song has tracks. Copy its offset.

Convert that offset to pointer form. Go back to your song's header, and change the voicegroup pointer to the new pointer you've chosen. (The voicegroup pointer came immediately after the first four bytes of the header, remember?)

Nj0JZYO.png

Adding the song to the song table
Go back to the repointed song table. Scroll to the last valid entry.

240bCW8.png

Each entry is a pointer followed by four 00 bytes. Click after the last entry. Type in a pointer to your new song's header offset.

fFxbVrp.png

Save the ROM and open it in Sappy. Go to the song you just inserted, and attempt to play it. If all goes well, you will hear a recognizable sequence of notes. The song itself won't sound good at all, because it's using the wrong instruments at the wrong volumes; however, it's still playable by Sappy, and the notes themselves have the right timing and sequence.

In other words, the track data was imported successfully. We now need to change the voicegroup data.

Creating a new voicegroup

A "voicegroup" is a table that lists "voices", or instruments in a GBA song. Chances are, there won't be a voicegroup in the game that matches exactly with our imported song. We therefore need to create our own.

Open your ROM in Sappy and go to your new song.

6yw2H6d.png

Next to the play and stop buttons, the offset for the voicegroup (labeled "Voices") will be listed. Double-click it. You will be prompted to enter the address for a new "voice table".

You will need to find 1536 bytes of free space in your ROM -- room for a voice table that contains 128 voices, with 12 bytes per voice. Find the free space, and enter the offset into Sappy. I'll be using 900000 for this tutorial. Click "OK". If asked if you are sure, click "OK" again.

Because there is no voice data at our new voicegroup, you won't be able to preview the song anymore; all you'll hear is silence. We're going to fix that.

Go here to see a list of all of the normal voicegroups and their voices. Find an instrument that you'd like to start with. For the tutorial, we are going to start with the "Strings" instrument found in the 0x48ABB0 voicegroup.

You'll need to find a song in Sappy that uses that voicegroup. In this case, song 259 -- a fanfare from RSE. Go to that song in Sappy. Then, go to Tasks -> Edit voice table.

T8fMj2V.png

In Magnius' voicegroup list, each voice had a number next to it. That is the position of the voice within the voicegroup. The number for "Strings" was 48, so select voice 48 in the dialog.

PPgImig.png

Write down all of the information for that voice. Close the dialog. Go back to the new song that you inserted.

z6U5NG7.png

In the screenshot above, I circled a small arrow in red. Click that arrow. Doing so will show you information about each track.

1ixNMmq.png

You'll notice that each track has five colored numbers beneath it. The red number shows what voice the track is currently using. (Yes, "currently" -- a track can switch from one voice to another mid-song.) I think the orange number shows the current volume of the track. I have no idea what the rest of the numbers mean.

Click play, and wait for the song to start. Then, click stop. Now, the numbers will have values, and you will be able to see which voices each track is using.

8THH5QS.png

Go to Tasks -> Edit voice table. For each of the voice numbers that the tracks use, change all properties to make them identical to the "Strings" voice from the normal voicegroup that we examined earlier.

Now, here is where things will get difficult. You will need to preview your song, and pay careful attention to the way the individual tracks sound. For each track, you will need to find the most fitting instrument in another voicegroup, and change that track's voice to match that instrument. (For example, I changed voice 25 to the "Electric Bass (Fingered)" voice from voicegroup 48B8B8.) This will take a while, because it is largely a trial-and-error process; you'll have to try copying voices from several voicegroups and finding the one that fits the best.

When you've found the voices you need and added them to the new voicegroup, the end result should sound quite a bit like the original Bramble Blast theme.

But some tracks are missing notes! And some don't play anything at all, no matter what voice I gave them!
I know. I had this problem when coming up with the tutorial.

Basically, there are two major kinds of voices: DirectSound and GBSynth voices. You can't have more than five of either kind, and you can't have more than six voices playing at one time if DirectSound is involved.

A GBSynth is any voice that uses a waveform -- that is, Square1, Square2, Wave, and Noise voices. All other voices (DirectSound and Multi Sample) are DirectSound.

So when copying voices from the game's normal voicegroups to your new voicegroup, you have to choose them very carefully. You have to choose a set of voices based on which tracks use them, and when, so that you adhere to the above limits.

Oh, and chords? When multiple notes play at the same time? Each note counts individually toward the DirectSound limit. A six-note chord counts as six DirectSound instruments playing at once.

As I said -- music hacking is very, very difficult.

Acknowledgements
Information on repointing the song table came from linkandzelda's tutorial on the subject.

Information on song data structures came from gamesharkhacker. Additional information on song data structures, along with information on converting and copying song data, came from the Fire Emblem Ultimate Tutorial [offsite link] (section: "Part 11: The Music Hacking Run-Down").

The Sappy 15 download link came from ArchsageX. Information on getting it to work came from Lyzo.

Information on the limits regarding how many DirectSound/MultiSample tracks can play at once came from this thread by Magnius.

One of the links in the tutorial goes to a list of all FireRed voicegroups and their voices. That list was compiled by Magnius.

Appendix / Further Reading
A voicegroup has 128 voices (which are zero-indexed in editors) and uses the following syntax:

<voice 0> <voice 1> [...] <voice 127>

Each <voice> represents, well, a voice. Voice definitions are always 12 bytes long, but their contents vary depending on their type. (There are five voice types, so far as I am aware.) The format of those types is not something you need to know, as voices are generally alterable in Sappy. However, if you are interested in their format, you can check Charon's New and Improved Music Hacking Tutorials [offsite link]. A thread on the Pokemblem Forums has instructions for transferring voices from voicegroup to voicegroup using a hex editor.

Track data has no padding before or after it, so far as I am aware. 0xBC marks the start of a track. B2 ZZ YY XX WW is an instruction that tells the interpreter (the GBA) to jump to offset 0xWWXXYYZZ and continue playing from there; it is used to loop tracks by jumping back to their BC bytes.

Song headers are of the following format:

TT 00 0A 00 WW WW WW WW XX XX XX XX[ YY YY YY YY[...]]

Where TT is a byte holding the number of tracks; WWWWWWWW is a pointer to the voicegroup that the song uses; XXXXXXXX, YYYYYYYY, and so forth are pointers to the starts of each track (to their BC bytes). So far as I am aware, there is no padding of any kind before or after the header.

Information on the track data itself can be found here. That document contains detailed information on the Sappy format, including listings of which hex bytes trigger which functions during audio playback. (Note to self: check if B3 can only be used to jump to measures rather than independent notes...)
 
Last edited:
2
Posts
12
Years
  • Seen Feb 23, 2012
Did the first part of this and it all repointed but i reopened in Sappy after editing the XML to look like this.

Code:
<rom code="BPRE" name="Pokémon Fire Red" songtable="0x800000" creator="Gamefreak">
        <playlist name="Main">
            <song track="0x100">Healing (RS)</song>
            <song track="0x101">Level Up </song>
            <song track="0x107">Evolution Start</song>
            <song track="0x108">Evolution/Safari</song>
            <song track="0x109">Battle 1</song>
            <song track="0x10A">Battle 2</song>
            <song track="0x10C">Fanfare 1</song>
            <song track="0x10D">Fanfare 2</song>
            <song track="0x10E">You Fail It!</song>
            <song track="0x10F">You Fail It Again!</song>
            <song track="0x110">Follow Me</song>
            <song track="0x111">Game Corner</song>
            <song track="0x112">Evil Lurks</song>
            <song track="0x113">Gym</song>
            <song track="0x114">Jigglypff's Song</song>
            <song track="0x115">Introducion</song>
            <song track="0x116">Pokemon Theme</song>
            <song track="0x117">Cinnabar Island</song>
            <song track="0x118">Lavender Town</song>
            <song track="0x119">Healing</song>
            <song track="0x11A">Bicycle</song>
            <song track="0x11B">Encounter 1</song>
            <song track="0x11C">Encounter 2</song>
            <song track="0x11D">Encounter 3</song>
            <song track="0x11E">You're In The Hall Of Fame!</song>
            <song track="0x11F">Viridian Forest</song>
            <song track="0x120">Mount Moon</song>
            <song track="0x121">Abandoned Place</song>
            <song track="0x122">End Credits</song>
            <song track="0x123">Route Theme 1</song>
            <song track="0x124">Route Theme 2 / Intro</song>
            <song track="0x125">Route Theme 3</song>
            <song track="0x126">Route Theme 4</song>
            <song track="0x127">Indigo Plateau</song>
            <song track="0x128">Battle 3</song>
            <song track="0x129">Battle 4</song>
            <song track="0x12A">Battle 5</song>
            <song track="0x12B">Battle 6</song>
            <song track="0x12C">Pallet Town</song>
            <song track="0x12D">Oak's Lab</song>
            <song track="0x12E">Oak's Theme</song>
            <song track="0x12F">Pokémon Center</song>
            <song track="0x130">SS Anne</song>
            <song track="0x131">Surf's Up</song>
            <song track="0x132">Pokémon Tower</song>
            <song track="0x133">Silph Co.</song>
            <song track="0x134">Cerulean City</song>
            <song track="0x135">Celadon City</song>
            <song track="0x136">Victory 1</song>
            <song track="0x137">Victory 2</song>
            <song track="0x138">Victory 3</song>
            <song track="0x139">Vermillion City</song>
            <song track="0x13A">Viridian City</song>
            <song track="0x13B">Gary's Theme</song>
            <song track="0x13C">Gary's Theme (bis)</song>
            <song track="0x13D">Fanfare 3</song>
            <song track="0x13E">Fanfare 4</song>
            <song track="0x13F">You caught a Pokémon!</song>
            <song track="0x140">Trainer Card Photo</song>
            <song track="0x141">Gamefreak</song>
            <song track="0x142">Victory 2 (bis)</song>
            <song track="0x143">Intro Message 1</song>
            <song track="0x144">Intro Message 2</song>
            <song track="0x145">Intro Message 3</song>
            <song track="0x146">Game Corner (+1)</song>
            <song track="0x147">Game Corner (+2)</song>
            <song track="0x148">Net Center</song>
            <song track="0x149">Mystery Connection</song>
            <song track="0x14A">Game Corner (+3)</song>
            <song track="0x14B">Mount Ember</song>
            <song track="0x14C">Follow Me (alt)</song>
            <song track="0x14D">Water Labyrinth</song>
            <song track="0x14E">Tanoby Ruins</song>
            <song track="0x14F">Islands 1-3</song>
            <song track="0x150">Islands 4-5</song>
            <song track="0x151">Islands 6-7</song>
            <song track="0x152">PokéFlute</song>
            <song track="0x153">Battle - Deoxys</song>
            <song track="0x154">Battle 5 (+1)</song>
            <song track="0x155">Battle 5 (+2)</song>
            <song track="0x156">Encounter 4</song>
            <song track="0x157">Deoxys Encounter</song>
            <song track="0x158">Trainer Tower</song>
            <song track="0x159">Pallet Town (fame mix)</song>
            <song track="0x15A">Teachy TV</song>
        </playlist>
    </rom>
Now the songs work but are all in the wrong order. For example, Pallet Town plays the Pokemon battle music. Does this happen or have I made a mistake?

EDIT: Yeah, my fault. Somehow I managed to paste it a few rows down than I meant to. Weird how it still worked.
 
Last edited:

cheshirecat

A Tad Insane
4
Posts
12
Years
Ok so I'm running into a bit of a problem here. The music I want in playing in Sappy perfectly (don't even need to change the voice group which is awesome), but when the game tries to launch it will do the opening animation (Gengar v. Nidoran) but when it tries to move to the start screen the game screeches like a baboon and crashes. Any insight as to why this may be occurring?
 
Last edited:

Jambo51

Glory To Arstotzka
736
Posts
14
Years
  • Seen Jan 28, 2018
@OP Good tutorial, well written and has just about everything you could need, but...

The game freaks out like this because you're replacing the pointers to the music table in the wrong order. This is known as one of the wonders if rom hacking!

There are 5 pointers to the music table in the FR rom, and you MUST replace the first one in the ROM LAST. This irrepairably breaks your ROM if you do it wrong, so make sure you make a backup!

Also, you don't need to manually insert every new song for it to work. Sappy is capable of inserting new music for you if you set it up correctly.
 
Last edited:
275
Posts
13
Years
  • Seen Oct 9, 2019
The game freaks out like this because you're replacing the pointers to the music table in the wrong order. This is known as one of the wonders if rom hacking!

There are 5 pointers to the music table in the FR rom, and you MUST replace the first one in the ROM LAST. This irrepairably breaks your ROM if you do it wrong, so make sure you make a backup!
Eh? I just replaced them in the order that Ctrl+F found them in HxD, and it worked for me. I figured the tutorial I read that in had just made a mistake somewhere. :\

I'll go update my post, then.

Also, you don't need to manually insert every new song for it to work. Sappy is capable of inserting new music for you if you set it up correctly.
I inserted a song with Sappy. 50% of the inserted data was the actual song. The remaining 50% was worthless ASCII metadata that Sappy wastefully tacked onto the end, for no discernible reason.

Manual insertion is more difficult, but it ensures that you insert only what you need. :\
 

unknownism

UnKnOwN oNe
5
Posts
14
Years
I have a problem, when I click the "??" button in the "TR" program, the midi is placed on the left, but then a pop-up says "de-bug assertion failed". There is a song.gba file made in the Mid2gba folder, but has 0bytes on it. Did I do something wrong?
 

ManInTheMask

Pro Hacker
31
Posts
12
Years
  • Seen Oct 27, 2016
ManInTheMask here. Does this trick work in Pokemon Leaf Green, Ruby, Sapphire, and Emerald?
 

ManInTheMask

Pro Hacker
31
Posts
12
Years
  • Seen Oct 27, 2016
Hey! I seem to have a problem. Whenever I insert a song or overwrite a song with my own, and try playing it, Sappy closes! WHAT'S WRONG!?

Ok, it was the version, but now it don't see any of the track bars!
 
Last edited:

Kaith

Hacker of Fire
49
Posts
12
Years
Okay, I'm a bit lost. After I paste the old list in the 0x800000 section, I don't understand what you mean when I have to reverse 4A32CC. I don't see that anywhere in the old code. Do you think you can post a picture?
 
275
Posts
13
Years
  • Seen Oct 9, 2019
Okay, I'm a bit lost. After I paste the old list in the 0x800000 section, I don't understand what you mean when I have to reverse 4A32CC. I don't see that anywhere in the old code. Do you think you can post a picture?
0x4A32CC was the offset that Sappy found when I loaded the ROM -- that is, the offset of the original song table. It may be different for you if you're using a different game or version of the game (I'm on FireRed US 1.0 -- that is, FireRed BPRE).
 

Kaith

Hacker of Fire
49
Posts
12
Years
0x4A32CC was the offset that Sappy found when I loaded the ROM -- that is, the offset of the original song table. It may be different for you if you're using a different game or version of the game (I'm on FireRed US 1.0 -- that is, FireRed BPRE).

Actually it's the exact same offset for my game. I just don't see where I need to reverse it.
 
275
Posts
13
Years
  • Seen Oct 9, 2019
Actually it's the exact same offset for my game. I just don't see where I need to reverse it.
You need to find the pointers to it, and the pointers are reversed. So put the offset into Notepad or something and then reverse it as I describe. Go to your hex editor (I'm assuming HxD here), Ctrl+F, and put the reversed hex into the search field. Make sure the search is for hex bytes, not text. Then, search.
 

droomph

weeb
4,285
Posts
12
Years
The game freaks out like this because you're replacing the pointers to the music table in the wrong order. This is known as one of the wonders if rom hacking!

There are 5 pointers to the music table in the FR rom, and you MUST replace the first one in the ROM LAST. This irrepairably breaks your ROM if you do it wrong, so make sure you make a backup!

Wait, I don't get it. Why would you need to replace the pointers in a certain order? The memory is not being actively read, and thus it shouldn't matter which order you replace them.
 

DefiningTheDecade

I may not be famous.. but..
75
Posts
13
Years
Okae. I'm a tad bit lost. In the section Correcting the Track Pointers you say look for the BC byte then you say go back to the first B2 Byte then you say replace the first four empty bytes with the pointers at the start of the track.. and I'm not sure what is meant by the beginning of the track like is it Before/After/Starting with/Ending with the BC byte? It wasn't really specified.
 

Lyzak

wishes he had a Hacking Team
33
Posts
13
Years
  • Seen Jan 19, 2012
Basically, there are two major kinds of voices: DirectSound and GBSynth voices. You can't have more than five of either kind, and you can't have more than six voices playing at one time if DirectSound is involved.

A GBSynth is any voice that uses a waveform -- that is, Square1, Square2, Wave, and Noise voices. All other voices (DirectSound and Multi Sample) are DirectSound.

So when copying voices from the game's normal voicegroups to your new voicegroup, you have to choose them very carefully. You have to choose a set of voices based on which tracks use them, and when, so that you adhere to the above limits.

Oh, and chords? When multiple notes play at the same time? Each note counts individually toward the DirectSound limit. A six-note chord counts as six DirectSound instruments playing at once.


I think I need this bit clarified:
No more than 10 channels. Got it.
No more than 5 GBSynth, no more than 5 DirectSound (so, 5 of each for max channels). Got it.
No more than six simultaneous voices/notes...? Clarify:

Example time:
1) Say I have DirectSound instruments in my piece. However, they are not playing at the moment. Can more than 6 NOTES of GBSynth be played?

2) Piece has DirectSound instruments. Two are playing, with only one note. All 5 GBSynth tracks are playing simultaneously. Problem?

3) Suspended notes: Do these count as "being played" for the duration of their hold? So, for example, a whole note is played at the beginning of measure X, where it is within limitations. However, at the end of measure X, while it is still being held (but not initiated), 6 more notes are being played. Does this override the limit on DirectSound notes?

Thanks
-Lyzák
 

ipatix

Sound Expert
145
Posts
15
Years
I think you seem to be wrong:
-You can play one note for each GB compatible channel => 2x square wave, 1x programmable waveform, 1x noise; to use more is technically not possible, because each hardware channel can only play at one frequency
-With default sound driver settings of Pokemon games you can use up to 5 digital sound (i.e. DirectSound) notes simultanously. You can spread these on more tracks or only one; You can't use more without changing the sound driver mode; if you're playing 5 notes, notes wth the lowest priority will drop and won't play (notes with a higher track nr. have a lower priority; notes that are in release state have a lower priority than notes that are hold; lower MIDI keys have a lower priority (for example if you are playing 5 notes on one track and start playing another one after a moment the lowest note will stop playing))

Hope I could help ;-)
-You can have up to 10 tracks, more tracks are ignored
 
Back
Top