One more small optimisation:
case 0x00: u8 reg = *g_ayVGM_Pointer & 0x0F;
The AND is not needed here because the upper nibble is already 0.
I get an average reduction of 63% (especially thanks to the waveforms data packing), but the resulting data is still too big to be really usable in a game (in ROM anyway).
Can you quantify this? Also, when you say too big, are you considering a 32K ROM or a MegaROM?
Here are some numbers.
My personal guideline for a music to be usable in a game is to stay under the 8KB limit.
Here, we are often even over 16KB, which makes them difficult to use, even with a MegaROM.
The AND is not needed here because the upper nibble is already 0.
Fixed! Thanks.
I’m not sure if you want to pursue the SCC any further, but here are some ideas in case you do;
What if you designed the SCC commands exactly like you did the PSG? Omit the PSG. For example:
--------------------------------------- Frequency --------------------------------------- 0n nn 0x80 = nn 0x81 = n Frequency channel 1 1n nn 0x82 = nn 0x83 = n Frequency channel 2 2n nn 0x84 = nn 0x85 = n Frequency channel 3 3n nn 0x86 = nn 0x87 = n Frequency channel 4 4n nn 0x88 = nn 0x89 = n Frequency channel 5 --------------------------------------- Volume --------------------------------------- 5n 0x8A = n Volume channel 1 6n 0x8B = n Volume channel 2 7n 0x8C = n Volume channel 3 8n 0x8D = n Volume channel 4 9n 0x8E = n Volume channel 5 --------------------------------------- Mixer --------------------------------------- An 0x8F = n On/off switch channel 1 to 5 Bn 0x8F = n | 0x10 On/off switch channel 1 to 5 --------------------------------------- Waveform --------------------------------------- C0 nn[32] nn[32] -> 0x00[32] Waveform channel 1 C1 nn[32] nn[32] -> 0x20[32] Waveform channel 2 C2 nn[32] nn[32] -> 0x40[32] Waveform channel 3 C3 nn[32] nn[32] -> 0x60[32] Waveform channel 4 C4 nn[32] nn[32] -> 0xA0[32] Waveform channel 5 (SCC+ only) --------------------------------------- Wait --------------------------------------- Dn Wait 882 * (n & 0x0F + 1) samples (50 Hz) En Wait 735 * (n & 0x0F + 1) samples (60 Hz) --------------------------------------- Special --------------------------------------- FE nn nn End of song with loop FF End of song (without loop)
You can have a separate PSG and SCC player, and play two separate streams simultaneously. The benefit is that the encoding for SCC is more efficient. The cost is that the timing gets encoded (more or less) twice.
I think volume & frequency are the most important ones to optimise. For PSG, maybe mixer is also relevant. For SCC, mixer is probably only set once so not worth dedicating short commands to it? But SCC waveform is important.
As for frequency, you can also consider to set frequency MSB and LSB always together. E.g. 0nnn, 2nnn, 4nnn. Then you only need two bytes to set frequency instead of the usual 3. (Changed it in the example above.)
As for the waveform, probably it gets changed a lot to previously seen waveforms. So it would be worth to move the unique waveforms into a separate table, and change the command to specify the index in the waveform table.
I thought about it.
Another idea I had in mind was to keep a single stream but to mark sections for the AY and for the SCC because in the data I've analyzed, the two are often grouped together in package.
Anyway, it seems like a lot of effort for data that will remain big.
For now, I prefer to look at the TriloTracker format...
Fair enough, it will never go as low as 8k. I’m interested to hear about your future findings .
No matter the result, cool project.
For now, I prefer to look at the TriloTracker format...
You know you will be probably trading speed for song size here. Also I imagine the TT replayer is probably bigger than a VGM based one. Of course neither needs to be a problem.
Going sub 8k for SCC & PSG - 8 channel encoded VGM would I think be challenging. Though, looking at some numbers from Realfun 3 as reference below, it might be possible when keeping the songs "simple" enough (i.e. without many waveform updates). By encoding repetitions and indexing the waveforms, those big SCC songs from metalgear2 and manbow size will come down a lot, maybe not all sub 8k but quite positive it can go below 16 k.
Name Size data waves # ----------------------------------- hydroc 15842 11298 4544 142 miners 17780 12532 5248 164 corridor 15105 7297 7808 244 staff 15525 11717 3808 119 metalsqd 27298 21442 5856 183 battle 18005 10421 7584 237 vector 8915 7059 1856 58
You know you will be probably trading speed for song size here.
For me the speed is the primary benefit of a register-log format. Another pro is the simplicity and freedom to choose any music production tool. In a MegaROM environment I’m less concerned about file sizes, I don’t mind if it goes above 8K. However smaller is still better, so smart encodings are pretty interesting, and seeing what others are doing and what results they’re getting, too.