OK, to cut a long introduction short, I'm embarking on another NES tracker. I know, I know.
I've been busy (on and off) rewriting an audio engine from scratch that runs at (so far) 240hz and you can layer up the effects for some pretty weird-sounding stuff.
Anyway, all that is going well. However, because of the CPU intensiveness of updating the engine 4 times per frame, I'm trying to create an interface that minimises screen updates and data decoding. I think I've got this fairly sussed but one thing I'm struggling with is the design of the music data.
NTRQ used "fixed" length patterns and while it meant memory handling wasn't necessary, it was also very wasteful (2 bytes per pattern step, even if that step was empty).
This time I'm wanting to have 2 FX columns plus the note column but I'm going to take a leaf out of LSDJ's book and limit the pattern length to 16 steps so that I don't have to have "scrolling" data.
This would mean that one pattern, done like NTRQ, would take 80 bytes (1 byte for note, 2 bytes for FX1, 2 bytes for FX2 multiplied by 16 steps = 80)
My rough memory map allows me 4096 bytes for pattern data (again using 8KB battery RAM) which would only allow me about 50 patterns and that's just not enough.
So.....(there's a point, yes )
I've been trying to figure out a dynamic memory method to make more efficient use of the battery RAM. Instead of having fixed patterns, in memory they will be tokenised so that, for example, 9 blank steps is represented by one byte, $89, instead of 45 bytes (9 x 5 bytes per step as explained above).
My idea so far would be to have a edit buffer in main RAM that you decode the pattern to when editing. As you enter editing mode;
1) Decode the pattern from SRAM to main RAM.
2) Shuffle all the pattern data from the address of the pattern being edited upwards to close the gap (the size of the encoded pattern in SRAM).
3) All edits are performed in the edit buffer in main RAM.
4) If you change patterns or exit edit mode, the pattern in the edit buffer is encoded to SRAM but at the end of existing patterns and it's pointer address is updated accordingly.
The obvious gotcha is going to be when the limit of the 4096 bytes of pattern RAM are being reached and you're editing patterns low down in the memory - there'll be a lot of data to shuffle upwards before editing can begin.
Just looking for some advice, optimisation, tips, alternatives etc.
I've been busy (on and off) rewriting an audio engine from scratch that runs at (so far) 240hz and you can layer up the effects for some pretty weird-sounding stuff.
Anyway, all that is going well. However, because of the CPU intensiveness of updating the engine 4 times per frame, I'm trying to create an interface that minimises screen updates and data decoding. I think I've got this fairly sussed but one thing I'm struggling with is the design of the music data.
NTRQ used "fixed" length patterns and while it meant memory handling wasn't necessary, it was also very wasteful (2 bytes per pattern step, even if that step was empty).
This time I'm wanting to have 2 FX columns plus the note column but I'm going to take a leaf out of LSDJ's book and limit the pattern length to 16 steps so that I don't have to have "scrolling" data.
This would mean that one pattern, done like NTRQ, would take 80 bytes (1 byte for note, 2 bytes for FX1, 2 bytes for FX2 multiplied by 16 steps = 80)
My rough memory map allows me 4096 bytes for pattern data (again using 8KB battery RAM) which would only allow me about 50 patterns and that's just not enough.
So.....(there's a point, yes )
I've been trying to figure out a dynamic memory method to make more efficient use of the battery RAM. Instead of having fixed patterns, in memory they will be tokenised so that, for example, 9 blank steps is represented by one byte, $89, instead of 45 bytes (9 x 5 bytes per step as explained above).
My idea so far would be to have a edit buffer in main RAM that you decode the pattern to when editing. As you enter editing mode;
1) Decode the pattern from SRAM to main RAM.
2) Shuffle all the pattern data from the address of the pattern being edited upwards to close the gap (the size of the encoded pattern in SRAM).
3) All edits are performed in the edit buffer in main RAM.
4) If you change patterns or exit edit mode, the pattern in the edit buffer is encoded to SRAM but at the end of existing patterns and it's pointer address is updated accordingly.
The obvious gotcha is going to be when the limit of the 4096 bytes of pattern RAM are being reached and you're editing patterns low down in the memory - there'll be a lot of data to shuffle upwards before editing can begin.
Just looking for some advice, optimisation, tips, alternatives etc.