Amount of music in a game a function of...?

stevenshepherd

New member
what exactly contributes to the amount of space music takes up and thus how many tracks are possible to include? Is it the density of information in a song (hypothetical example, a 20 second loop with a handful of whole notes vs. all 1/8 notes and instrument effects)? Is it just the length of the track? Just trying to wrap my head around how the NES handles this. Thanks! :)
 

CutterCross

Active member
stevenshepherd said:
what exactly contributes to the amount of space music takes up and thus how many tracks are possible to include? Is it the density of information in a song (hypothetical example, a 20 second loop with a handful of whole notes vs. all 1/8 notes and instrument effects)? Is it just the length of the track? Just trying to wrap my head around how the NES handles this. Thanks! :)
From what I've experimented with each song can be no longer than ORDER 09. I haven't experimented with how many songs NESmaker can hold or how many rows each frame/ORDER can be. (By default each frame/ORDER is 64 rows.)

Oh by the way, you can't use note effects with NESmaker. Just a quick refresher. :) I've already listed a list of GGsound constraints on the forum.
 

Mihoshi20

Member
CutterCross said:
stevenshepherd said:
what exactly contributes to the amount of space music takes up and thus how many tracks are possible to include? Is it the density of information in a song (hypothetical example, a 20 second loop with a handful of whole notes vs. all 1/8 notes and instrument effects)? Is it just the length of the track? Just trying to wrap my head around how the NES handles this. Thanks! :)
From what I've experimented with each song can be no longer than ORDER 09. I haven't experimented with how many songs NESmaker can hold or how many rows each frame/ORDER can be. (By default each frame/ORDER is 64 rows.)

Oh by the way, you can't use note effects with NESmaker. Just a quick refresher. :) I've already listed a list of GGsound constraints on the forum.

Hmm, I'll have to do some experimenting. Making a blank project with only what's in it to get the game to boot, assemble it and look at what banks are empty, then simple just fill up the project with song and assemble and see what bank/banks fill up and keep adding songs until it overflows. Thankfully the export file from famitracker is so well laid out and organized that it's nearly a copy and paste job.
 

RadJunk

Administrator
Staff member
If I understand the question correctly, the amount of music will completely depend on how complex the music is. Four notes takes four times the amount of bytes as one note. An instrument with a one value volume envelope takes up less data than an instrument with a 50 value volume envelope. Etc, etc, etc.

Right now, there is sort of a hard coded 16 song limit, however this was due to how we pulled index songs, not space constraints...with the redux to the collision data, that will be changed. It MAY also be possible to fetch data from other banks, which means that if you have stray banks you want to store more music in, that may increase the amount of music your game can hold (by sacrificing something else that could go there).

Does this help?
 

CutterCross

Active member
TheNew8bitHeroes said:
If I understand the question correctly, the amount of music will completely depend on how complex the music is. Four notes takes four times the amount of bytes as one note. An instrument with a one value volume envelope takes up less data than an instrument with a 50 value volume envelope. Etc, etc, etc.

Right now, there is sort of a hard coded 16 song limit, however this was due to how we pulled index songs, not space constraints...with the redux to the collision data, that will be changed. It MAY also be possible to fetch data from other banks, which means that if you have stray banks you want to store more music in, that may increase the amount of music your game can hold (by sacrificing something else that could go there).

Does this help?
That actually helps a lot for me! I just have another question. Say I had 8 different volume envelopes, 6 different pitch envelopes, and 3 different duty cycle envelopes. All of those envelopes are really small, only about 1-4 values each. Does it take up any additional space if I mix-and-match those envelopes across, say 50 instruments? Do instruments by themselves (without any envelope data) take up space? Or are they just labels to assign instrument data to?

Sorry if that question sounds a bit confusing.
 

RadJunk

Administrator
Staff member
To judge for yourself, you can get GradualGames sound engine and run famitracker text through it. The resulting ASM file is almost exactly what our tool will spit out. So any particular question you might have should be easy enough for you to investigate, even if you don't yet have access to the beta :)
 

Mihoshi20

Member
TheNew8bitHeroes said:
To judge for yourself, you can get GradualGames sound engine and run famitracker text through it. The resulting ASM file is almost exactly what our tool will spit out. So any particular question you might have should be easy enough for you to investigate, even if you don't yet have access to the beta :)

Experimenting with the song CutterCross made for Mermay's Den and padding the song out to Order 09 length then copy and pasting it into the import file until an assembly fails. It seems the importer in NESmaker will allow you to load in more songs then will fit into the song bank 1B but will assemble with an error Value out of Range because of the full bank.

Using this method I got 7 songs with a full order 09 length in and 1 song of order 08, and then the 1 order 00 SFX, and 1 order 00 waves song into the tool and assembled successfully into a rom. Results may vary as I don't know much about Famitracker and if adding notes and keeping silence changes the size needed. These are just the results of the experiment.
 

RadJunk

Administrator
Staff member
Yes. You can download Shiru's NES Space Checker, and when you successfully compile a game, you can drag the ROM onto the tool and see the banks and how much space is used. If you get the value out of range in the assign banks script, it means that a bank has overflowed. Eventually we'd like to have a memory watcher inside the tool for quick and easy checking. :)
 

Mihoshi20

Member
TheNew8bitHeroes said:
Yes. You can download Shiru's NES Space Checker, and when you successfully compile a game, you can drag the ROM onto the tool and see the banks and how much space is used. If you get the value out of range in the assign banks script, it means that a bank has overflowed. Eventually we'd like to have a memory watcher inside the tool for quick and easy checking. :)

Yeah, I've been using the NES Space Checker a lot. It's been a life saver especially when I was manually shuffling banks around to cramming it down for my ports to Playchoice 10 and Vs. System MAME constraints. Though I noticed the program doesn't scale well to certain resolutions so I have to use it on a dedicated NESmaker machine with higher res to see the full bank report.

The problem though with the space checker though is that you can only use it after the fact. Assembling a successful rom and then checking it. I conducted my experiment to get at least a rough idea of the constraints I have to work with before hand. Though having even a rudimentary space watcher/checker beforehand in the tool would be kickass.
 

stevenshepherd

New member
Ok so this is going to be overly simplistic, but if anything hopefully gets across what I am thinking:

So it seems that a 5 second song on a loop would take up less space than a 30 second song with the same 5 second loop 6 times. Which makes me think:

Say I have a song with an AABB structure. If I did this out in Famitracker I would have to copy section A twice, and section B twice, each adding "unique" information that takes up space, but in reality it is just the same section repeated. I am just wondering how the NES handles this and/or if there was a way for it to play AABB as, for example: "play these 32 notes (section A), then play them again. Play these other 32 notes (section B), then play them again" which would be 66 "pieces of information" as opposed to 128. Hopefully that makes sense. This me trying to translate my abstract lay intuitions about memory etc into something that makes sense.
 

Kasumi

New member
To answer your first bit. (A 30 second loop with the same 5 second loop 6 times would take up more space.) It usually would, but not for the reason I think you think? Data is usually made of layers of grouped concepts. This is a bit simplified, but... Say a group of 16 notes takes up 16 bytes. That's the first layer. Now say you wanted to repeat those same 16 notes 5 times. That only takes five bytes. (Rather than 80.) This is because the second layer only stores "which set of 16 notes" rather than just outputting a byte for each of the total 80 notes. The size of these 16 notes repeated five times is 21 bytes. The size of it repeated once would be 17 bytes.

So let's say 16 notes is one second. Let's say each second uses a unique set of 16 notes. To store that 5 seconds of note data, you need 80 bytes. But then you also need the second layer. A byte for each second of the song. And then a third layer. Info about the song. (How many groups of 16 notes in the whole song, plus maybe tempo. We'll say that's 3 bytes.)

The equation for how many bytes a song takes up (in this simplified example) is number of unique 16 note sections times 16 plus number of total 16 note sections in the song plus three.

So a 5 second loop looped once is gonna be 16*5+5+3 bytes. 88.

If you wanted to do a five second long loop looped six times. The note data is still 16*5. 80 bytes. The tempo and length of song would still be 3 bytes. (Instead of 5, the length would be 30, but that's still only one byte.) What changes is you still need a byte for each 16 byte section of the song. So the equation is 16*5+30+3. 113 bytes. Which is bigger. But it's not 80 (16*5) bytes vs 480 (16*30) bytes.

A smart enough converter could in theory even detect that it just looped that way and output the exact same thing (88 bytes) for both cases. (But that's something I wouldn't count on expecting.)

If you did AABB in FamiTracker you could not have to copy section A twice, or section B twice. FamiTracker lets you reuse parts of a song. (Provided said sections matched the length of the "Rows" value within FamiTracker.) Edits to either part would change both.

I'd have to investigate how the GGSound Converter handles it, but I would bet it would not create duplicate data if you did that. If you create duplicate data that doesn't match rows, it probably would output the duplicate data more than once. (Detecting reuse in "unaligned" data is a much harder engineering problem.)

Edit: Now I have checked out GGSound handles it. Yes, if you reuse data in the Famitracker way, GGSound will not export duplicate note data. But the looped song is still a bit bigger because of the "song" data rather than the "note" data.

So shorter: Famitracker already lets you re-use parts of a song in a memory friendly way, I would expect most converters that read famitracker's output to not output the same data twice if Famitracker's exported data doesn't. But to reuse parts in Famitracker, you need to have the repeated sections match the "Rows" length.

Edit2: So basically... you can repeat notes, but the information that tells the engine how to repeat still takes up space even if the repeated notes don't. This is why the 30 second loop takes more space than the 5 second loop.

But! You could handle repeated data in any way you like if you wrote your own music engine data. There's no real "default" for NES. You could write code that creates entirely procedural music based on what's happening on screen with no actual note OR song data stored.
 
Top Bottom