Topic: new engine: zbmod
Already made this a couple of months ago, but didn't release it earlier because I wanted to "troll" the next best beeper compo with it first. de:coded provided the opportunity (not sure if I was successful because the results file is still not released), so here we go.
zbmod is a 3-channel mod player, meaning it plays PCM WAV samples of arbitrary length, like SampleTracker. It has a few advantages over the latter, though.
- better sound (still plenty of noise of course, but still a massive improvement over ST's replayer methinks)
- better note range
- possibility to use looped samples
On the technical side, the mixdown runs at about 9 KHz, with 21 relative volume levels. The routine uses the undocumented "OUT (C),0" instruction, so there different versions for NMOS and CMOS are required. I was too lazy to add CPU detection again, sorry
I also tried some things which were only moderately successful. Firstly, reloading data is done during the sound loop. This was a major p.i.t.a. to code, and ultimately didn't reduce noise as much as I had hoped, so I'm still not sure if it was worth the hassle.
Secondly, sound generation is done in a way so the beeper will always stay afloat* (ie it won't retract completely). This works reasonably well on hardware, but on emulators, a high-pitched parasite tone will be introduced. I've included a special emulator version which reduced the parasite tone somewhat, albeit at the cost of a lowered overall sound quality.
*Ok, some words about the reasons behind this. zbmod switches the state of port #FE with 8 t-state precision. However, this is a problem if one wants the beeper to be "on" for exactly 8 t-states (= rel. volume level 1), because the fastest switch would still take 11t (out (#fe),a). The 3t difference would be neglicable, but switching after 11t would introduce a lot of noise because of IO contention. So the earliest moment to switch state would in fact be after 16t, at which point we've already reached volume level 2. How to solve this? zbmod simply pretends that 16t uptime is volume level 0. Works fine on hardware, but unfortunately it fails on emulators. I assume this is due to errors introduced by the quantization of the beeper output, so it's not something that can be easily fixed with better emulation. So this approach is ultimately a bad idea considering a lot of beeper fans don't have access to real hardware.