So, I was brainstorming yesterday, and had an idea of a method of sample playback on the NES, at high quality, with little CPU overhead and small size (2-bit/sample average).
And this is the result: https://github.com/VitinhoCarneiro/2a03-d-plus-pcm
Unfortunately I'm not any good at 6502 ASM programming (though I might give it a try), so I just did a simulation of the encoding/decoding process in C. So, no ROMs or demos yet, though I've uploaded a sample of the program output here: https://www.youtube.com/watch?v=qgnXLjX4EMI
This codec is based on ideas from za909's MintaBOOM sample engine, available here: viewtopic.php?f=22&t=14520
How it works:
-The codec combines 7-bit PCM with DPCM deltas and uses the DMC interrupt for triggering samples.
-The audio is divided into 2-byte blocks, containing 8 samples.
-The first byte is a 7-bit PCM value to be written to the DMC delta counter.
-The second byte represents a pointer to the DPCM sample table - it's basically a sequence from 0x00 to 0xFF, where the value of the pointer is equal to the value stored in the table.
-On playback, the PCM value is written to the delta counter, and then the 1-byte DPCM sample is triggered and the interrupt set to trigger on the sample end; the CPU then returns to execution of normal code until the interrupt fires.
-The sample rate can be varied by simply changing the DMC frequency value, since that's what triggers the sample playback - this also opens possibilities for sample repitching.
Based on these ideas, this method of sample playback should be very easy to integrate into games/demos (as long as they don't require cycle-accurate execution, since the interrupt will disrupt their timing), since it should take very few CPU cycles to trigger a new block of samples every time the interrupt is fired.
Besides from low overhead, this codec also has a high compression rate (2 bits per sample, as opposed to the usual 8-bit padded PCM), and still high quality (even at ~32kbps ($C playback rate), it sounds way better than plain DPCM at $F).
I might try making a simple NES decoder for sample playback as a proof-of-concept for this method. But anyone is free to study and modify the source code, improve on it, and even making demos out of it.
I'd love to hear your feedback on this. I feel like this could be a game-changer for sample playback on the NES.
(PS: I'm thinking about a version of this that will use only 1 byte per 8 samples, using 4-bit ADPCM and vector-quantized DPCM sample blocks. I might have to test if it will decompress well, though...)
And this is the result: https://github.com/VitinhoCarneiro/2a03-d-plus-pcm
Unfortunately I'm not any good at 6502 ASM programming (though I might give it a try), so I just did a simulation of the encoding/decoding process in C. So, no ROMs or demos yet, though I've uploaded a sample of the program output here: https://www.youtube.com/watch?v=qgnXLjX4EMI
This codec is based on ideas from za909's MintaBOOM sample engine, available here: viewtopic.php?f=22&t=14520
How it works:
-The codec combines 7-bit PCM with DPCM deltas and uses the DMC interrupt for triggering samples.
-The audio is divided into 2-byte blocks, containing 8 samples.
-The first byte is a 7-bit PCM value to be written to the DMC delta counter.
-The second byte represents a pointer to the DPCM sample table - it's basically a sequence from 0x00 to 0xFF, where the value of the pointer is equal to the value stored in the table.
-On playback, the PCM value is written to the delta counter, and then the 1-byte DPCM sample is triggered and the interrupt set to trigger on the sample end; the CPU then returns to execution of normal code until the interrupt fires.
-The sample rate can be varied by simply changing the DMC frequency value, since that's what triggers the sample playback - this also opens possibilities for sample repitching.
Based on these ideas, this method of sample playback should be very easy to integrate into games/demos (as long as they don't require cycle-accurate execution, since the interrupt will disrupt their timing), since it should take very few CPU cycles to trigger a new block of samples every time the interrupt is fired.
Besides from low overhead, this codec also has a high compression rate (2 bits per sample, as opposed to the usual 8-bit padded PCM), and still high quality (even at ~32kbps ($C playback rate), it sounds way better than plain DPCM at $F).
I might try making a simple NES decoder for sample playback as a proof-of-concept for this method. But anyone is free to study and modify the source code, improve on it, and even making demos out of it.
I'd love to hear your feedback on this. I feel like this could be a game-changer for sample playback on the NES.
(PS: I'm thinking about a version of this that will use only 1 byte per 8 samples, using 4-bit ADPCM and vector-quantized DPCM sample blocks. I might have to test if it will decompress well, though...)