Friday, November 7, 2014

Sound effects

The past couple nights have been devoted to getting sound working in Anguna 2600. Unlike video, sound is actually pretty easy, as long as you aren't too picky and don't want it to sound like much. There's 2 sound channels, each one having 3 registers: one for volume, one for waveform (one of 7 or 8 presets), and one that controls frequency. Trying to get any particular notes or scales out of it is near impossible, but getting rough sound effects is pretty easy.

Although I spent way too long last night fiddling with it before realizing that I couldn't set the sound registers before the first video frame for some reason. When I did that, everything locked up. I'm still not sure why, I couldn't find any reference to that in the documentation. Oh well.

My first successful test was to pick a semi-random waveform (#4, which is basically a simple square wave), and tie the frequency to the player's X position, to test it out. This ended up accidentally producing the exact sound effect used in Yars Revenge when the Qotile starts spinning and is about to jump out and kill you. (see this google+ post where I have videos comparing the two).

Tonight I sat down to actually build the sound system for the game. I wanted to be able to do a simple "PlaySound #SOUND_SWING_SWORD" type of command, fire and forget, and have the sound engine do the rest (select which channel to play based on which was busy, start playing the correct sound, and turn off that channel after the right amount of time). Oh, and I wanted to have the sound engine use up no more than 2 bytes of RAM.

Which actually, ended up being not too difficult. I use 1 byte of ram for each channel. The upper 3 bits are used to track which sound ID I'm playing (so I only get 8 sounds possible), and the bottom 5 bits are a timer to track when it should be shut off. Each frame I decrement the timer, then go through the assembly equivalent of a big switch-case block to see what wave and frequency values should be set for that sound. If I want to later set it up so that one sound leads into another (ie one sound effect that has two tones in sequence) I can just build that into the giant switch statement, without having to take up more RAM. And if I really need more than 8 sounds, I can designate certain sounds that would belong to each channel. That would mean certain sound effects could never play at the same time, but if I really come up with that many sounds that I want to play, I think I can deal with that limitation.

Right now I have unpleasant sounds for when the player swings his sword, when you take a hit from an enemy, and when an enemy takes a hit. That's the majority of what I need, so for now, I just need to play around and pick better waveform/frequency values for those so they don't sound stupid, and I should be good to go.

Then it's on to building doors that open and close based on game conditions (# of enemies alive, keys in inventory, etc) as well as secret doors that look like walls but that you can walk through.

1 comment:

Bryan R said...

"I wanted to have the sound engine use up no more than 2 bytes of RAM."

To my modern ears this sounds like a typo. Did he mean two megabytes? Surely two kilobytes, then?

Nope, two bytes!

Robo-Ninja Climb

Well, out of the blue, I decided that I was missing out by not entering something into this year's NesDev competition , so a couple week...