This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Where do you store/manage the engine for music and why

Where do you store/manage the engine for music and why
by on (#224200)
For my current tests in C, I ported the code back to neslib examples and I'm using, I think, NROM (128/256). For now the code and data fits in 32k and I have no issue but once I switch back to my target mapper I need to decide how to manage it.

For my test, since I was not able to convert the song to famitome (for this project is not big deal), I decided to try the example by Shiru that uses famitracker for music and a trimmed down version of famitone for sound fx and it's working quite well. My old ft3.0 data converted to 4.6 got trimmed by at least 1k so there was some good things out of it.

As you can imagine, those 2 engines put together will take a lot of space. From my map file, both combined seems to takes around 177E bytes, which is almost a bank on mmc3.

How would you manage such a big engine and the music data on an MMC3? Would you keep the engine in the locked banks or switch them when necessary?

For testing code only, everything is the same bank is more than enough but it will become an issue to fix so I should start to migrate the code as soon as possible.
Re: Where do you store/manage the engine for music and why
by on (#224203)
The only thing that needs to always be present is DPCM samples.

I like to store the music code with the music data, and bank it in only temporarily when I'm calling the player function.

If you have a lot of music data, though, it might help to put the player in its own bank, or fixed bank, I guess. On MMC3 you could put data at $8000-BFFF and player in $C000-DFFF if you weren't using DPCM. (Not using DPCM opens up a lot of possibilities, in general.)
Re: Where do you store/manage the engine for music and why
by on (#224214)
I see. For my current project I do not need DPCM so it should be fine. Since the combined drivers are almost 8k, I cannot put the music in the same bank since 1 song is easily 1~2k. This means I would need a bank for the driver and bank(s) for the songs.

The only thing that I may need to check is how the famitone fx driver do for playing fx. It should be done during at the same time as music but what happens when you request an fx. I may need to adapt the code for setting up fx to be in a static bank since the request will be done outside the nmi.
Re: Where do you store/manage the engine for music and why
by on (#224216)
I'd consider this a last resort, but some games place a copy of the driver in several banks to avoid bank switching. Metroid keeps a couple of songs and a copy of its driver in each level bank*. With a big driver, this is less attractive of course.

*(the "world map" itself is actually commonly shared for all levels, but the structures each room in that world map points to are stored in the level bank, along with other level specific data)
Re: Where do you store/manage the engine for music and why
by on (#224225)
The Curse of Possum Hollow uses MMC3 and a FamiTone-derived driver. It has the engine and SFX data at $8000-$9FFF and music sequence data in three different banks swapped into $A000-$BFFF. When the driver isn't executing, something else is swapped into those banks.

Nova the Squirrel uses MMC1 (or, with a compile time switch, UNROM + SRAM) and Pently 5. The vast majority of the soundtrack fits in one 16K bank that gets switched into $8000-$BFFF. I seem to remember that a couple tunes in cutscenes or wherever use a different driver, and one of the hidden minigames (DABG) uses a copy of Pently 3.
Re: Where do you store/manage the engine for music and why
by on (#224230)
From the comments, if the fx are not too big, since there will be some remaining space in the driver bank, maybe I should but them there at the same time.
Re: Where do you store/manage the engine for music and why
by on (#224231)
Sounds like a good plan. I suppose you're planning to use a lot of the same sfx across multiple portions of the game? It makes sense.
Re: Where do you store/manage the engine for music and why
by on (#224263)
It will depends of the game made. For now, my engine is based on my old files which was a mega man based game and it should mostly be using the same fx in all stages. So hopefully the fx content will not be too big (didn't check yet ^^;;;).

Using an existing game to build the foundation of my engine is really saving me a lot of time that I don't have. I'm grateful too of using tools from the community to converting assets without having to work too much on the UI part. If I had to focus on fleshing out a new game and building an engine when you can sometime work only a few minutes on it, it would go nowhere. Hopefully, the resulting engine will be flexible enough but once I have an engine working it should be possible to adapt to the game I had in mind since I wanted to make an action platformer game anyway.
Re: Where do you store/manage the engine for music and why
by on (#224279)
FrankenGraphics wrote:
I'd consider this a last resort, but some games place a copy of the driver in several banks to avoid bank switching. Metroid keeps a couple of songs and a copy of its driver in each level bank

I feel like that's more an artifact of being an FDS port than anything else, just making a "snapshot" of the driver combined with each level's song and picking one of the snapshots, since it can't combine them in realtime.

tepples wrote:
Nova the Squirrel uses MMC1 (or, with a compile time switch, UNROM + SRAM) and Pently 5. The vast majority of the soundtrack fits in one 16K bank that gets switched into $8000-$BFFF. I seem to remember that a couple tunes in cutscenes or wherever use a different driver, and one of the hidden minigames (DABG) uses a copy of Pently 3.

Yeah, the entire game's soundtrack (8 songs and 5 level select loops, plus all the sound effects) fits into that bank alongside Pently (sans the period tables). True to its purpose, Pently seems to be really good at keeping the music size small too, and it might be feasible to keep even a large game's soundtrack in 16KB.

The other engine was only used in the sound test for bonus songs, and was just because Famitone 2 was built for noise instruments played at different pitches, which Pently isn't good at.
Re: Where do you store/manage the engine for music and why
by on (#224285)
In my UNROM template for neslib+famitone2, famitone itself resides on the fixed bank but is able to play music from a different bank via a very simple modification, in case you want to check.
Re: Where do you store/manage the engine for music and why
by on (#224288)
In Twin Dragons I'm using famitracker driver + famitone sfx driver. I have 3 16k banks of music data, and the drivers are in each bank.

The ideal solution would be what rainwarrior said, having the engines in an 8k bank at $C000-DFFF and switch 16k banks of data at $8000-BFFF. I tried that when I was playing with VRC6 mapper, it worked well.
Re: Where do you store/manage the engine for music and why
by on (#224296)
NovaSquirrel wrote:
I feel like that's more an artifact of being an FDS port than anything else


Oh, that makes a lot of sense. I completely forgot about some games being originally written for the FDS. Also, the "riddle music" is instanced across every level bank (except tourian, which iirc has the escape music there instead).
Re: Where do you store/manage the engine for music and why
by on (#224298)
glutock wrote:
In Twin Dragons I'm using famitracker driver + famitone sfx driver. I have 3 16k banks of music data, and the drivers are in each bank.

The ideal solution would be what rainwarrior said, having the engines in an 8k bank at $C000-DFFF and switch 16k banks of data at $8000-BFFF. I tried that when I was playing with VRC6 mapper, it worked well.


After reading everyone comments my idea would be to put the engine in 1 bank with fx and the songs in another 8k bank. I usually save the songs one by one so it's quite easy to limit to a few in 1 bank. I didn't check how much I would save if I put many together but the latest famitracker seems to optimize when instruments are not used (it just drop them).

For now space is not my main priority. I may try to optimize later, once the game engine actually works ^^;; I ported my code back to mmc3 and it loaded the bank at the location I expected.

Thanks everyone for the comment, I have many ideas to try.
Re: Where do you store/manage the engine for music and why
by on (#224337)
Here is my suggestion:

FamiTone into the fixed bank. Music and sound effects into other banks.

As long as music and sound effects are all in the same bank, it's no problem: Just switch to the corresponding bank before you call any FamiTone function that accesses a song or sound effect.

As soon as you need more than one bank for music and sound effects, you need to alter the FamiTone library itself in one single place.

In the function FamiToneUpdate, find this code:
Code:
.if(FT_SFX_ENABLE)

   ;process all sound effect streams

   .if FT_SFX_STREAMS>0
   ldx #FT_SFX_CH0
   jsr _FT2SfxUpdate
   .endif
   .if FT_SFX_STREAMS>1
   ldx #FT_SFX_CH1
   jsr _FT2SfxUpdate
   .endif
   .if FT_SFX_STREAMS>2
   ldx #FT_SFX_CH2
   jsr _FT2SfxUpdate
   .endif
   .if FT_SFX_STREAMS>3
   ldx #FT_SFX_CH3
   jsr _FT2SfxUpdate
   .endif

Before the comment, include code to switch to the sound effects bank. (Assuming that all your sound effects fit into one bank.)

This way, it works as intended:
Before you call FamiToneMusicPlay or FamiToneUpdate, you set the corresponding music bank.
Before you call FamiToneSfxPlay, you set the sound effects bank.

And switching from music bank to effects bank in FamiToneUpdate is done due to the lib's code change.
Re: Where do you store/manage the engine for music and why
by on (#224381)
I'm using MMC3 right now and it quite frankly feels like I died and went to heaven. 8kb bankswitching makes it easy to keep the sound engine, envelopes and sfx in one 8kb bank and then swap out music in the other 8kb bank. Don't know how I managed previously, haha. I had a smaller soundtrack before, everything fit in one 16kb bank including the music engine.
Re: Where do you store/manage the engine for music and why
by on (#224423)
@DRW

Since I'm using the famitone/famitracker combo, I will test how much famitone can be separated in a fixed bank without issue. For the music, I think switching bank in the nmi seems a reasonable solution.

Now that I received many feedback, I will experiment based on that and see how it goes. I may have questions later if something goes wrong.

Thanks everyone!
Re: Where do you store/manage the engine for music and why
by on (#224426)
Banshaku wrote:
Since I'm using the famitone/famitracker combo

You mean the version where you use the FamiTracker driver for the music and FamiTone for the sound effects?
Not really what I would suggest. The FamiTracker driver is so big and quite CPU-heavy that I wouldn't use it in an actual game.

But if you really want to use such a big driver, you might just as well do the following, given that you use a mapper like MMC-1 where you can configure at runtime which bank is the fixed bank:

You put the FamiTracker and FamiTone driver plus some wrapper functions into bank A.
You put music into bank B or in several different banks.
You put sound effects into bank C.
The regular code is in fixed bank X.

Whenever you need to do something with music and sound effects, you do this:

(The code bank X is now in the fixed bank.)
1. You load bank A into the variable bank.
2. You call a function from bank A that switches which one is the fixed and which is the variable bank.
(Now bank A is the fixed bank and bank X is the variable one.)
3. You load bank B or C into the now new variable bank.
(Bank X is now inactive.)
4. You call any music and sound effects functions, switching between bank B and C as necessary.
5. You put the original code bank X back into the variable bank.
6. You switch which bank is the variable bank and which is the fixed one.
(Bank A is now the variable bank again and bank X is the fixed bank, just like in the beginning.)
Re: Where do you store/manage the engine for music and why
by on (#224434)
Yes, I'm aware that this driver is heavy :lol:

My current project is used as a place holder for making my engine so once a "real" project will be created, I will remove the code under the sound_driver facade that just call the famitracker/famitone combo code in the back. So I'm not too concerned on the impact on my engine since the goal is not to have something performant but to use my old code/assets and see the performance impact with all those things together. It will be interesting to see where it slow down, when and why.

Once I make some original game I will just target my music for famitone 2 (or any other lightweight driver available at the time) and will be fine.

Because of the size, I will test the "swap the driver in the nmi" pattern to see how it goes and check how you need to organize your code based on that. That will be a lot of new things to learn from it. What you wrote is very close to what I will do so I will keep you example if I have issues with my test.

Thank again for the example!