This week's episode: Experiments in sound…or rather: failures in sound.
Since I'm writing this game in NextBASIC I'm abstracted much higher up that machine code (which has it's obvious benefit to my programming experience). The downside is control over the machine.
Currently Oh Mummy has (really cool) music thanks to Richard Faulkner (from the Spectrum Next facebook forum). To play sound effects poses a number of problems, and ultimately I've had to park the idea entirely.
Since my game is pretty high speed and involves constant movement, any sound effect is going to have to run along side the rendering. The way BASIC is wired up doesn't really allow this. When I'm calling the BEEP
function (for instance) I can't be moving my sprite.
In machine code it doesn't work like this anyway, so it's useful to think in machine code context. The way it works at the lowest level is that the user code changes the interrupt routine (in web language this would be akin to request animation frame) and then tones would be adjusted at this point.
Without knowing the details, I'm fairly confident that this is how the audio DRIVER
call works to play the NextDAW music.
So the BEEP
function is pretty much out of the window. Not only because it'll pause the runtime enough to make playing uncomfortable, but also I can't design a beeper based sound to sound decent enough. Though it might be worth my looking at Beepola.
NextBASIC also comes with a powerful PLAY
function which sends commands to the AY-8-3912 chips. This does sound great (assuming I can construct the right string to send to the PLAY
command) but it also suffers from locking up the play back.
I also looked at Beepfx which is Windows specific but does generate machine code that I can call from BASIC using RANDOMIZE USR 60000
. This works pretty well for sounds and includes a very useful demo library of sound effects. The problem is that a) it also locks up until complete - which could be mitigated with extremely short sounds, but most importantly b) it's configured to run on a 3.5Mhz spectrum not one running at 28Mhz which is the speed I'm using to get the game to feel quick and responsive. The beepfx sounds are more like a crazed mouse on acid.
Sadly, I can't get my head around the sound engineering maths required to modify the beepfx values, and switching down to 3.5Mhz, calling the routine, then speeding back up to 28Mhz has the same (if not worse) slow down.
One novel approach that Dave Clarke (also of Spectrum Next facebook forum) uses is to enable the AY chips via the OUT
function in BASIC, set the volume to zero, then adjust the volume on demand in his game loop. The same technique can be used to adjust the tones on demand to create effects.
I also experimented with working through a string of toggles during the game loop and it kinda half works but the sounds I'm making are quite terrible and I'm competing with the background music for the AY chips (which in reality just doesn't let me play back).
So, for the time being, this game will have to be sans sound effect. Which is a bit of shame. I think the only reasonable solution will be some machine code that hooks the interrupt and checks a queue for sound effects to play, but I've had limited success with the im 2
opcode.
That said, I did a bit of graphics tinkering and a small change is looking really nice now.