Removing music from NES games

Discuss NSF files, FamiTracker, MML tools, or anything else related to NES music.

Moderator: Moderators

Post Reply
sukotto42
Posts: 11
Joined: Thu Jan 28, 2021 10:49 am

Removing music from NES games

Post by sukotto42 »

Howdy, I've seen stuff about this posted before, and have used what I found here to remove the music from Castlevania to do a full piano playthrough w/sound effects a while back. I'm working out a Twitch stream concept, and would like to rip the music out of several NES games, leaving the sound effects only. Essentially like what Bit Brigade was interested in doing a while back. The point of this being so that I can loop the theme music and then play the level, with the sfx. Some games, I want to be able do the entire game this way, some I just would probably go a level or two at a time, but ultimately turning off the music, preserving sfx, across a handful of games, is what I want to do.

I know only about enough to be dangerous in a hex editor, but I did disable Sonic 1 thru 3's soundtracks using some specific information I found. If anyone can help point me in the right direction, that would be incredible. I've exhausted my options without just straight-up asking the community. Thanks!

PS. For some examples, I tried it out for fun this past week on a weekly stream. Around 37 minutes I'm in the middle of building Chemical Plant Zone, and then play the level, and 1:35 I did a Castlevania level plus boss. I can't say either were rehearsed but I plan on spending a lot more time on this stuff!
https://www.facebook.com/scotthannay/vi ... 8727550011
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Removing music from NES games

Post by tokumaru »

Each game uses its own sound driver, but it's common for sound drivers to have a subroutine for starting songs, so your job would be to locate this subroutine and patch it to return without doing anything. Some games have well documented sound drivers (e.g. Mega Man, IIRC) but in most cases you'll have to do some reverse engineering yourself.
sukotto42
Posts: 11
Joined: Thu Jan 28, 2021 10:49 am

Re: Removing music from NES games

Post by sukotto42 »

Okay, so I pulled up Mega Man in FCEUX to watch the hex info. I found what looks specifically like note-related activity at 0xD00 and 0x1500. Should I just write Zeroes to the areas that look active and see what happens...? Or try to find specific songs?
sukotto42
Posts: 11
Joined: Thu Jan 28, 2021 10:49 am

Re: Removing music from NES games

Post by sukotto42 »

Or would this require disassembly? 'cuz zeroes didn't help a damn :lol:
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Removing music from NES games

Post by tokumaru »

sukotto42 wrote: Thu Jan 28, 2021 7:21 pmI found what looks specifically like note-related activity at 0xD00 and 0x1500.
NES RAM actually only goes from $0000 to $07FF, everything $0800 up to $1FFF is just mirroring $0000-$07FF (i.e. $1500 = $0D00 = $0500).
Should I just write Zeroes to the areas that look active and see what happens...? Or try to find specific songs?
That won't help much, as the audio driver will keep trying to do it's thing, only with corrupted values. You're better off looking for the code that plays the music, not the music data, so you can patch it to NOT start songs when the game requests songs to be played.
sukotto42 wrote: Thu Jan 28, 2021 7:30 pmOr would this require disassembly? 'cuz zeroes didn't help a damn :lol:
You should definitely look at the built-in disassembler in FCEUX or Mesen and look for the audio subroutines.
sukotto42
Posts: 11
Joined: Thu Jan 28, 2021 10:49 am

Re: Removing music from NES games

Post by sukotto42 »

Thanks for all the info so far. You really know what’s going on and I appreciate the lookout. Are there any other suggestions to keep track of where the subroutines may be occurring? How will I know what value to write?

I’ve got like 13 games I want to do this for. it’s a worthwhile ‘timesink’ for me because of how badly I want to do this, but I still know so little about the process. I know there’s no Swiss Army knife solution since they will be mostly using different audio drivers, but if I know what sort of thing to look for that would be super useful.
sukotto42
Posts: 11
Joined: Thu Jan 28, 2021 10:49 am

Re: Removing music from NES games

Post by sukotto42 »

Okay, it looks like $0500 is where all the music is happening in the RAM. How do I locate where it's pointing to in the debugger?
The value that looks like it keeps track of the steps in the loop is $0500, I can see where the notes are in the RAM. Trying to figure out where they're sending stuff to, but I still don't know what to do with it when I do.

Holy crap though, going through the debug I accidentally came across a line that literally said something like SQ1_VOL but it disappeared the next time I clicked. Trying to reproduce.
sukotto42
Posts: 11
Joined: Thu Jan 28, 2021 10:49 am

Re: Removing music from NES games

Post by sukotto42 »

With some help from FCEUX docs, noticed the $4000 range appears to be the actual final output from the sound. How do I trace where those values are getting their data from?
Noticed $400C sometimes said BMI NOISE_LO. Identified it as the snare from Bomb Man. I feel like I'm getting a lot closer but am still just swinging.

There are several spots from the block just above that also say things like:
:3FE0: 90 1E BCC SQ1_VOL
:3FE2: 10 00 BPL $3FE4
:3FE8: 90 1E BCC TRI_LINEAR
:3FEA: 10 00 BPL $3FEC
:3FF0: 90 1E BCC DMC_FREQ
:3FF2: 10 00 BPL $3FF4
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Removing music from NES games

Post by tokumaru »

sukotto42 wrote: Fri Jan 29, 2021 6:25 amHow will I know what value to write?
What value to write is the easiest part: once you find the subroutine you need to disable, you can probably put a RTS instruction ("return from subroutine", hex value $60) right at the beginning of it in order to prevent the subroutine from doing anything. The hard part is finding that subroutine.
I’ve got like 13 games I want to do this for.
And locating the proper subroutine will be a slightly different task for each of them due to each game using different audio drivers.
Holy crap though, going through the debug I accidentally came across a line that literally said something like SQ1_VOL but it disappeared the next time I clicked. Trying to reproduce.
This is a nickname for one of the audio registers on the NES. Emulators will sometimes show these nicknames rather than their addresses.
sukotto42 wrote: Fri Jan 29, 2021 9:17 amWith some help from FCEUX docs, noticed the $4000 range appears to be the actual final output from the sound. How do I trace where those values are getting their data from?
The $4000 range is where the audio registers are on the NES. Each address there is a "port" the the CPU writes to in order to communicate with the APU. If you set up a breakpoint for writes to this range ($4000-$4013), the emulator will pause when the program starts writing data there, at which point you can look in the disassembler and see what part of the program is doing that. That will probably be the very end of the audio playback routine, so you may want to go back from there and see if you can make sense of the code executed before that.
There are several spots from the block just above that also say things like:
:3FE0: 90 1E BCC SQ1_VOL
:3FE2: 10 00 BPL $3FE4
:3FE8: 90 1E BCC TRI_LINEAR
:3FEA: 10 00 BPL $3FEC
:3FF0: 90 1E BCC DMC_FREQ
:3FF2: 10 00 BPL $3FF4
This is an erroneous disassembly of a non-memory area of the NES. The emulator is just mistakenly interpreting data as instructions, and by accident some of these "instructions" end up referencing audio registers that are nearby. Ignore this, it means nothing.

Actual program code will be at $8000-$FFFF, which is where the PRG-ROM gets mapped to. Ignore all disassembly below $8000 because there will not be actual code there (except for the very rare cases where programs copy code to RAM, but that's super rare on the NES).
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Removing music from NES games

Post by tokumaru »

Unfortunately, the code you're looking for is not likely to be obvious at all. The playback subroutine, which does the writes to the audio registers ($4000-$4013), runs after songs have already been started, so you can't do much to stop them from playing at that point.

Ideally you'd find the subroutine that starts a song, but that can be called at any time so you can't easily tell when it's running like you can with the playback subroutine.

Another option would be to follow the playback routine step by step untill it's done with the register writes and returns (RTS), at which point you can see the code that called the playback subroutine in the first place, giving you the address of the beginning of the playback subroutine. By tracing it from the beginning, you might be able to tell when it's processing music channels vs. sound effects, which would maybe allow you to patch the music parts to just not process the music streams.

This will be tough without a basic understanding of 6502 assembly, though...
sukotto42
Posts: 11
Joined: Thu Jan 28, 2021 10:49 am

Re: Removing music from NES games

Post by sukotto42 »

I've been learning what the 3-letter instructions all mean; at least the ones I've run across. They seem to mostly make sense.

Trace Logger has been of assistance to me. With Mega Man title screen being static without music, I see a number of things occurring after I press start, between the flashing of the Press Start and the title screen appearing. You can see when all the new code is executed. There are several levels of nesting shown - would it look like a more simple execution to tell the game to start a particular song? Would it then also execute a function to load all the song data into memory? What function might you think it would call to load song data?

I guess it's probably specific to sound drivers, but do any games use a separate BGM and SFX driver and can just "switch off" the BGM driver?

I feel like if I can get this, I will be able to use what I've learned to figure out others.

Thanks again, your helpful insight is keeping me going on this!
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Removing music from NES games

Post by tokumaru »

Here's a quick example: Looking at this SMB disassembly, you can easily search for the words "music" and "sound" to locate all sorts of audio-related variables and subroutines. One particular label caught my attention: RunSoundSubroutines. There you can clearly see calls to subroutines that handle sound effects and music. In this case, doing what you want could be as simple as patching out that call to MusicHandler, skipping the music handling code altogether. Its a pretty simple fix, but someone went through the trouble of reverse engineering that entire game to give all subroutines and variables meaningful names. The actual modifications you want to do will probably be just as simple as this, a change of 1 to 3 bytes, the hard part is locating the subroutines of interest without any meaningful names or comments.
User avatar
Memblers
Site Admin
Posts: 4044
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Removing music from NES games

Post by Memblers »

You might want to look at the NSF rips instead of the full games. NSF files have INIT and PLAY routines. The init routine basically is how you "load" the song or sound effect. Play routine simply plays it, called 60 times a second. Usually the person ripping an NSF file has to insert their own code in the init routine, in your case you would be looking at that and seeing how it interacts with the original game's code. If the NSF includes sound effects, that will show you exactly how both the sound effects and songs are initialized and played. Without all the other code from the game getting in your way.

If the game uses the same method to initialize songs and sound effects, you could modify the engine by checking what track # it's trying to play, and simply aborting if it's not a sound effect. Or you might have to dig deeper into the game code (outside of the scope of the NSF), and find out where it handles sound effect and music calls separately. The latter thing could be a real mess, or real simple.. depends on how it was coded. That's why I'd tend to think modifying the sound engine itself might be easier.
sukotto42
Posts: 11
Joined: Thu Jan 28, 2021 10:49 am

Re: Removing music from NES games

Post by sukotto42 »

I've been thinking about it a lot over the last day but mostly tried to stay hands-off because it consumed me so much the day before, lol

But I damn near fell over sitting down this morning. Saw something somewhere about a ROM map, so I decided to look up the one from Mega Man 1.

There it was in all its glory: 0x11A70 to 0x11AD5...the music and SFX pointers. No further information.

I just started writing zeroes to the addresses and songs started disappearing from the game. I remember from the NSFs that sfx come later so I wondered if that would be the case. Sounds are intact and music is gone.

This one, at least, has been solved!!
Memblers wrote: Sun Jan 31, 2021 2:41 am You might want to look at the NSF rips instead of the full games. NSF files have INIT and PLAY routines. The init routine basically is how you "load" the song or sound effect. Play routine simply plays it, called 60 times a second. Usually the person ripping an NSF file has to insert their own code in the init routine, in your case you would be looking at that and seeing how it interacts with the original game's code. If the NSF includes sound effects, that will show you exactly how both the sound effects and songs are initialized and played. Without all the other code from the game getting in your way.

If the game uses the same method to initialize songs and sound effects, you could modify the engine by checking what track # it's trying to play, and simply aborting if it's not a sound effect. Or you might have to dig deeper into the game code (outside of the scope of the NSF), and find out where it handles sound effect and music calls separately. The latter thing could be a real mess, or real simple.. depends on how it was coded. That's why I'd tend to think modifying the sound engine itself might be easier.
I will definitely try to use this method in conjunction with everything else I've been learning for other games with maybe less documentation. I really want to do Legacy of the Wizard and Wizards & Warriors and imagine they might be tough to find info for. I've at least knocked one off my list!
sukotto42
Posts: 11
Joined: Thu Jan 28, 2021 10:49 am

Re: Removing music from NES games

Post by sukotto42 »

MESEN. I’m not sure what made me try that since I thought FCEUX was doing me pretty well, but holy cow.

The way it highlights values that are writing or reading... I can see what values are actively WRITING to other addresses. I can now do this without documentation!! I did end up finishing Mega Man, and even changed the way I went about it from what I did above. (Even though I forgot to save it, but I’m now not worried about it lol)

I can now surgically remove specific songs from games!! I’m currently on Wizards & Warriors, which has proved to be the buggiest response so far, but actively being able to run code, rewind and try again has helped me clear all the main bug hurdles I’ve come across so far. Once I had my lightbulb moment, I did all of Mega Man 2, Legacy of the Wizard, and Mega Man yesterday; though like I said I forgot to save Mega Man. Got too excited and went right into Legacy of the Wizard lol. I did write down the values I had to change though. By the way, also pretty fun getting to play the game while doing this, not gonna lie!

I started writing down the values of note locations and how the channel headers work with Legacy of the Wizard, but it got too tedious, stuff was kind of messy in that one with sub-loops within songs and such, and the header sizes were different each song. Also, the BGM SQ2 header also controlled the SFX, had to be careful which value I changed or it would kill the SFX during that song, too.

I can’t wait to get this project finished! Thank you both for all your guidance and assistance! I’ll try to remember to share BPS patches when I finish them all in case anyone else has the desire to do this in the future.
Post Reply