RE'ing ALttP - Unknown sound driver?

LeviathaninWaves

Member
OP
Newcomer
Joined
Jul 15, 2020
Messages
10
Trophies
0
Age
35
XP
90
Country
United States
Heya. So I've been researching the sound driver situation for A Link to the Past + Four Swords. It seems that Four Swords uses Sappy, but A Link to the Past might use something Nintendo proprietary?

Loveemu has a very fascinating tool on github, called melosearch. You specify a melody in MML and it will search a binary or file for a sequence of bytes that match the melody. Long story short, I was able to find the locations of sequenced data in Oracle of Seasons this way, but not GBA A Link to the Past. So it got me thinking, is the sequenced data compressed?

I thought that maybe the SNES version might provide some clues, but information on the music format there is a bit scarce. One source implies it might be compressed... and the source code for editors like Hyrule Magic, are not an easy read. What do we know about the sound driver in GBA A Link to the Past? Did Nintendo recompose the music and bring it to a new format? Did they convert it? Did they copy over the sequenced data and create a sound driver specifically for handling SNES formats like this?
 

FAST6191

Techromancer
Editorial Team
Joined
Nov 21, 2005
Messages
36,798
Trophies
3
XP
28,348
Country
United Kingdom
You are probably going to be the one broaching new ground with this; nobody particularly latched onto this version as the definitive one to do anything with (compared to the fun stuff that happened with the Final Fantasy ports). Could be anything like what you describe. Fully custom driver and emulated would be an odd one for Nintendo to go in for though; give or take pokemon (which is usually an extended version of standard things) then most of their first party efforts use the standard formats.

I am seeing a rip out there in the wild in the usual sources though so I guess someone has gone before. https://datacrystal.romhacking.net/wiki/Category:GBA_games has nothing though, which means if Sappy (including the various other/newer versions or whatever else is out there that nominally handles the format) fails then might be time to go manual https://www.romhacking.net/documents/361/
http://problemkaputt.de/gbatek.htm#gbasoundcontroller
http://belogic.com/gba/index.php

Curious to try out the tool mentioned though (granted that will first see me have to learn MML, and then probably give up as my musical transcription talent is rather low).
 
  • Like
Reactions: LeviathaninWaves

LeviathaninWaves

Member
OP
Newcomer
Joined
Jul 15, 2020
Messages
10
Trophies
0
Age
35
XP
90
Country
United States
You are probably going to be the one broaching new ground with this; nobody particularly latched onto this version as the definitive one to do anything with (compared to the fun stuff that happened with the Final Fantasy ports). Could be anything like what you describe. Fully custom driver and emulated would be an odd one for Nintendo to go in for though; give or take pokemon (which is usually an extended version of standard things) then most of their first party efforts use the standard formats.

I am seeing a rip out there in the wild in the usual sources though so I guess someone has gone before. https://datacrystal.romhacking.net/wiki/Category:GBA_games has nothing though, which means if Sappy (including the various other/newer versions or whatever else is out there that nominally handles the format) fails then might be time to go manual https://www.romhacking.net/documents/361/
http://problemkaputt.de/gbatek.htm#gbasoundcontroller
http://belogic.com/gba/index.php

Curious to try out the tool mentioned though (granted that will first see me have to learn MML, and then probably give up as my musical transcription talent is rather low).
I had found a similar post that you had replied to regarding this game and already got started. If I'm not mistaken, DMA 1 and 2 are usually used for moving audio around right? If so I'm likely currently at the audio buffer in WRAM. Assuming it's mixed and preparing to be output to the FIFO.
 

LeviathaninWaves

Member
OP
Newcomer
Joined
Jul 15, 2020
Messages
10
Trophies
0
Age
35
XP
90
Country
United States
I've made some progress on this. What I've found is that the sound effects and instrument samples have a header with 4 variables. The first is unknown, 2nd is base frequency, 3rd is starting loop point offset, and 4th is the length of the whole sample.

That's the good news, the bad news is in how each sample is indexed. The data used to index each sfx/instrument sample comes just before the cascade of audio data... but it's all part of a dynamically calculated pointer chain. I've managed to work my way backwards to nail down some of these "base" ROM pointers, but I'm sitting here thinking I could've coded this myself in a much less convoluted way.
 

LeviathaninWaves

Member
OP
Newcomer
Joined
Jul 15, 2020
Messages
10
Trophies
0
Age
35
XP
90
Country
United States
Since I've never encountered this before in asm, I'm not sure. But I've been trying to document and graph it out on paper.

There's a data block just above the sample bank that has offsets for each sample. But there's other values and pointers above throughout the ROM that functions use to reach this data block. I haven't tracked down the variables that dictate the flow of which pointers and values lead to a specific offset in the block. But either the pointers point to other pointers, or they will point to a value that is either shifted left and added to another pointer, or simply added to another pointer, eventually leading to the offset block.

My guess is the variables that control this flow would be sort of an instrument preset with a sample number as well as song metadata that specify which instruments need to be loaded. My hypothesis is that sound effects are sequenced like music, even if it's just one note.
Post automatically merged:

While I still haven't fully worked out how the game finds offsets for samples, I did make even more progress. I found the section where all the music sequence data is located. I figured out how to change a note's pitch, length and velocity. But the rest is still very black box for now. It's not compressed though. It's not the format seen in games that use sappy and it's different from the documented SPC formats I came across used in many SNES games.

If I can fully work this out, the doors can finally be open for modding the sound effects and music. (Nintendo didn't always do well with sound effects when porting SNES games to GBA)
 
Last edited by LeviathaninWaves,

DanTheManMS

aka Ricochet Otter
Member
Joined
Jun 2, 2007
Messages
4,453
Trophies
1
Age
34
Location
Georgia
XP
751
Country
United States
I have very little to share, as you already know way more about this than I do. I can only state that it would be unlikely for them to use the original SPC file for the SNES, at least not emulated. Even assuming that Nintendo's coders could get an SPC emulator working better than the homebrew effort, it would take too much processing power and leave no room for the rest of the game.

Here's the homebrew version. I only ever got it to work with Chrono Trigger music. https://web.archive.org/web/20161223110449/http://forwardcoding.com/projects/spcemu.html

It was later updated and used as the sound core for every (?) SNES emulator on the DS, with its increased horsepower.
 

LeviathaninWaves

Member
OP
Newcomer
Joined
Jul 15, 2020
Messages
10
Trophies
0
Age
35
XP
90
Country
United States
Dynamically calculated chain or linked list?
How are linked lists usually coded in ARM? I found the command that chooses an instrument for a channel and have followed that byte and am baffled by what the code is doing with it. It looks like adding new samples after the end of the ROM will be very challenging simply because this algorithm (I'm simplifying the explanation) takes a pointer to a byte, lsl the byte, add to pointer which points to either zeroes or another byte for shifting, or to a chunk that acts as a offset to the sample... it's a complex chain that happens in some relatively full space. So figuring out how to point to added samples looks like it could be close to impossible without rewriting stuff.

I have very little to share, as you already know way more about this than I do. I can only state that it would be unlikely for them to use the original SPC file for the SNES, at least not emulated. Even assuming that Nintendo's coders could get an SPC emulator working better than the homebrew effort, it would take too much processing power and leave no room for the rest of the game.

Here's the homebrew version. I only ever got it to work with Chrono Trigger music. https://web.archive.org/web/20161223110449/http://forwardcoding.com/projects/spcemu.html

It was later updated and used as the sound core for every (?) SNES emulator on the DS, with its increased horsepower.
You're right. They clearly made sacrifices on some effects using the sound driver they used for gba. I'm not sure why some sfx are way off pitch from the original SNES version (each sample has a header with a base sample rate variable), but the warp transition between Light World and Dark World relied heavily on the SPC echo effect, which is absent here obviously.

I've managed to work out more of the sequencer format used in this game though. There's a series of 16 bit values for a header. 1st specifies number of tracks or channels, 2nd one is an offset to be added to the base pointer, pointing to tempo (so location of a master control track perhaps). 3rd one and on (offsets, add to base pointer) points to the start of each channel). So if the number of channels is equal to 5, there will be 6 of these 16 bit values.
Sequencer commands:
e4xx = tempo
eaxx = master volume
c2xx = instrument select
c1xx = musical rest (duration)
Frequent pattern of 3 bytes is note, length, velocity.
Made up example, 0x80, 0x30, 0x70.
Notes cannot exceed 0xbf. Lowest is untested.
0xff appears to signify the end of a channel.

There's more I'm still figuring out but so far so good.
At some point I'd like to check if the Super Mario Advance series uses any of this as well. I only have access to Super Mario Bros 3 though.

EDIT: After taking a quick look at Super Mario Advance 4: Super Mario Bros 3, I can confirm that the sample format including headers appears to be the same as ALttP gba. In addition to that, the music sequence format appears to be the same as well. I'm also seeing the bizarre pointer/variable structs that are used to reference these blocks of data. I would venture to say the rest of the Super Mario Advance series uses this sound driver. What I don't know yet is where the differences are, if there are any.
 
Last edited by LeviathaninWaves,
  • Like
Reactions: DanTheManMS

FAST6191

Techromancer
Editorial Team
Joined
Nov 21, 2005
Messages
36,798
Trophies
3
XP
28,348
Country
United Kingdom
GBA games would generally be coded in C, maybe with some inline stuff for the time critical things (if your code is located in the 08?????? region then it is probably not that, if it is in the 03000000-03007FFF part on the GBA http://problemkaputt.de/gbatek.htm#gbamemorymap then that is the fast on chip RAM within the ARM CPU that fancier code will use for the time critical stuff).

To that end whatever the compiler at that point was going to do, compiler theory/history of compilers is not my strong suit, much less for ARM, but they were still fairly procedural things at this point rather than whatever craziness we have today with AI trained (granted that, or at least what is today recognised as an ancestor, would have been well known by that point) and not necessarily repeatable aspects they pull from database stuff. Linked lists in assembly then being whatever the coder wanted to do, and that point you also get to debate whether it is one of the sub types and related concepts (doubly linked or something, though that would not be that useful here).

It was more that you were looking to approach it like it was some arcane https://prog.world/the-story-of-mel-a-real-programmer/ (nice video discussion of said same) type arrangement when looking at it more like one of the various C family constructions might be worth considering when pulling it apart.

Shifting in ARM processors is fairly common -- they are actually noted for their abilities to do it (marketing phrase though also in documentation being barrel shifter). Quite useful as well when you can't do register size immediate values (your assembler might provide it for you but it will be pseudo instructions) in instructions*, even more so in THUMB mode (which is going to be a fair chunk of the time it seems). To that end I kind of expect in pointer handling these days.

*you do have things like movn as well which is mov but inverts things, useful if you need all FF in the higher bits.
 

DanTheManMS

aka Ricochet Otter
Member
Joined
Jun 2, 2007
Messages
4,453
Trophies
1
Age
34
Location
Georgia
XP
751
Country
United States
Again I'm sure you already know this, just saying it just in case:

Don't forget that in GBA mode, there are a few parts of the GB/GBC hardware still accessible, namely the audio channels. Often used for sound effects, while the GBA audio hardware handled the music.

Perhaps that's where some of the assembly calls are jumping to.
 

LeviathaninWaves

Member
OP
Newcomer
Joined
Jul 15, 2020
Messages
10
Trophies
0
Age
35
XP
90
Country
United States
I managed to figure it out. At the top of it all there's a base pointer. The code takes the instrument number, shifts it left by one and adds that to the pointer to create an offset pointer. It'll then grab the pointed to value and add that to the base pointer. There's a bit of a series to it, but eventually the note value from the music sequence comes into play and is compared against a couple of pointed values, branching off to separate offset values for samples and frequency data to be added or multiplied with a sample's base frequency. This is basically how keymapping is handled. So yeah maybe like a linked list.

I was able to append to the end of the ROM a ~3 second recording of the snes light world/dark world warp sfx, point to it and rewrite the "music sequence" to stream it.

I don't know if this driver supports gameboy sound but I will have to check how the code handles sequencer commands to see if any of them could lead to that. This is 2 games in one cartridge, The Legend of Zelda: A Link to the Past & Four Swords. Four Swords uses Sappy and makes heavy use of the gameboy sound where A Link to the Past uses an unknown driver that uses none of the gameboy sound features. Still, I'd like to check if the capabilities are there.
 
Last edited by LeviathaninWaves,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    BigOnYa @ BigOnYa: Ok good chatting, I'm off to the bar, to shoot some pool, nighty night. +1