The Gameduino has a 64-voice synthesizer, and it can also play back samples.
To do this, the Arduino loads the sample byte into the SAMPLE_L and SAMPLE_R registers, and the Gameduino mixes the sample with the 64-voice synthesized audio.
The simplest way to play a sample is to take the sample data and blast it into the SAMPLE registers. Here is the code to play an 8KHz sample:
the resulting sound output: cowbell.wav
To play back samples without halting gameplay requires a sample buffer. You can use Arduino timer interrupts, but coordinating SPI writes from inside an interrupt service routine is fiddly.
Or, use a 256-byte sample buffer in Gameduino memory, and a coprocessor microprogram to feed the samples into SAMPLE_L and SAMPLE_R:
The soundbuffer microprogram continuously plays back samples from the sample buffer, updating the read pointer at COMM+0 as it sweeps through the buffer.
start-microcode soundbuffer \ Interface: \ COMM+0 sound read pointer \ 3F00-3FFF sound buffer \ This microprogram provides a simple sound sample buffer. \ It reads 8-bit samples from the buffer at 3F00-3FFF and \ writes them to the audio sample registers SAMPLE_L and \ SAMPLE_R. \ The current buffer read pointer is COMM+0. h# 3f00 constant BUFFER [ 125 50 * ] constant CYCLE \ one cycle of 8KHz in clocks : 1+ d# 1 + ; : - invert 1+ + ; : main d# 0 ( when ) begin CLOCK c@ over - \ positive means CLOCK has passed `when` d# 0 < invert if COMM+0 c@ dup h# 3f00 + c@ dup SAMPLE_Lhi c! SAMPLE_Rhi c! 1+ COMM+0 c! CYCLE + then again ; end-microcode
At the 8KHz rate, 254 samples is enough for 31 milliseconds of sound. So if a game refills the sample buffer at least once during every 36 Hz frame, the audio playback will be continuous.
Last modified $Date: 2011-05-13 11:32:42 -0700 (Fri, 13 May 2011) $