That old PCM player that’s in the download in links section? No good. I was looking over it and realized that not only is it convoluted and complex, but the interface really doesn’t show how to use the damn thing. It’s a poor example.
So I revisited it. I’m going to attempt to modularize it into an easy library of sorts. I’ll include macros and routines for basic functions for controlling each channel. I also made it a little more friendly to memory page layouts compared to the fix bank requirement from before. This bumped the cpu resource up by 2.7%. In addition, I added dynamically controlled fixed frequency sample streaming for the last two channels. So 4 XM channels and 2 PCM streaming channels.
I refer to them as XM channels, because they use a linear frequency approach compared to period base system of MODs. It’s a phase accumulator. The nice thing about this, is that I don’t need a huge table to translate notes to frequencies. I actually only need a table of 12 notes at C3 (octave 3). Everything else can be derived by shifting that left or right. The phase accumulator is 19bits long with the top three bits being the whole number and the lower 16bits being the float part (fractional value). So I have a finetune table of 16 points between notes (plus or minus direction) for finetuning the wave form without the need of an external program. And lastly, I have 32 frequency steps in between notes. I could have more… waaayyy more given the 16bit fractional part of the frequency divider, but honestly from my experience 16 usually cuts the cake anyway, so 32 should be enough. The steps are for frequency sliding (or vibrato).
I’ll include a small command line utility that prep a wave file to the format needed for the player. The player supports loop points, so those would need to be included into the waveform directly for that support. I also don’t track the waveform by its length, but rather have an end of marker value in the stream itself. So those need to be included as well.
So the numbers I have for 4 XM channels is 29% cpu resource from the call to the RTI at 117 times per frame (1/60) – for all channels playing. The frequency division is all handled inside the timer routine, so you would just need to provide the note to play. For the 4 XM and 2 PCM, that number jumps to 36.6% if all six channels are playing. Still not bad at all. The timer interrupt is actually 6.991khz and not 7khz, but I reset the timer counter ever vblank to keep it in sync, and do an mid-between call to the timer routine – so it ends up being 117 calls per frame or 7.02khz. Honestly, if I skipped it and did 116 I doubt there would be an audible difference.
On the topic of audio, have you guys ever heard the PCE stream 55khz 5bit PCM using the channel’s waveform memory as a buffer? Check it out: http://pcedev.net/6280a/sgx_dump.wav That was recorded from my SuperGrafx. Basically it’s a 1.7khz timer interrupt, which means an interrupt called 29 times per frame. Each interrupt call, just refill the buffer. On the SGX, you only need one channel to do this (or any of the core grafx consoles with the 6280a processor). The regular 6280’s need two channels to do this. Sounds pretty good for 5bit audio. Because of how audio tends to get filtered/blended at that higher range, you can actually interleave channel streams and have them mix together. You could do a ~64khz output setup, but have four streams feeding it in interleave format for a 4 channel PCM stream at 16khz each. Not bad at all, especially considering how light the cpu resource is compared to something like 7khz single channel output the old fashion way. But here’s the crazy thing, as if that wasn’t crazy enough, you can do this with two channels on the SGX and stream 10bit audio in the same fashion. Just let that sink in for a minute…