I had a day off following the Computer Club at The Lass on Wednesday, my sole plan for the day, to sort out my tracker distortion issues and make some progress. It was a very successful day!
I attempted a few different approaches to resolve the distortion, having the playback routine count how many samples it had played, and the render code then generating that number of samples. Which worked to a point, but just simply delayed the occurrence of the distortion by a chunk of time, and also increasing its duration. It was clearly a slow drift between the two functions. I tried having the render code monitor the playback position and pause or halt if it caught it up, this generated some weird audio effects or maxed out the 68K to 100% as it effectively spent all its time sat behind the playback trying to generate sufficient samples for the next VBI.
Thankfully Cyrano Jones popped up on IRC and whilst discussing stuff he suggested trying a double buffering technique. I wasn’t convinced, but it was something I hadn’t tried. After some battling and issues due to make not assembling all the files when it should of (I now use make clean a lot more 🙂 ) This proved a perfect solution! As long as the output buffers are suitably sized for the maximum number of samples per VBI at the given refresh rate and playback rate all is good! I must have spent 10 minutes listening to the same pattern play listening for the distortion, it didn’t come!
With the distortion issue fixed I now needed to get the other 2 channels in the mix. Due to the way I am heavily using CPU registers for render variables, this was a little more complex and hacky than I would have liked, but this is a prototype so meh, I am looking forward to having the full 64 32bit registers of the DSP to abuse 🙂
The way I am writing the sample data to the DSP buffer is as a single 32bit long, (4x 8bit channels, handy). This allows the DSP code to pick up all 4 channels from a single load, which also gets around the limitation that the DSP can only make 32bit loads and stores when addressing it’s own cache RAM.
As each pass through the render code generated 2 8bit channels at a time, it seemed logical to simply write these 16bit words to the DSP RAM, (improving efficiency as the DSP and 68K only have 16bit data bus width) skipping over the 16bits for the next 2 channels free for when those channels were computed later. Or so I thought…. All hail the wacky hardware bug and all it’s glory :/ I soon discovered that DSP RAM should only be written to as 32bit longs from the 68K! otherwise it has a habit of corrupting the other half of the long! This means the first two channels are written in the high end of a long write, then the last two channels are or’d into the low half of the long :/ so many wasted ticks!
With all 4 channels going, as well as all this 32bit long memory accessing wastage CPU usage is back up to around 40-45%. At least its less than 50% and I am sure with a lot of optimization I would be able to claw some of that back.
However I now need to start working on the code that reads the actual song data and adding the effects, which is proving another challenge due to the way I have written some of the render code. A fresh start may be needed based on what I have discovered. I am completely psyched with the fact this thing actually plays a mod from start to finish and sounds like what it is supposed to! 😀
Of course I have found a few issues in there too which will be fun to fix, but its all progress 😀