gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Audio > Sound rendering methods: the difference

#58697 - SittingDuck - Tue Oct 25, 2005 1:27 pm

As far as I know there are three methods for rendering audio: DMA, timer interrupts and VBlank interrupts. What's the difference? What are the advantages and disadvantages of them?

My limited experience of sound on the GBA in its entirety is absolute head-banging hell!

#74203 - mlequim - Fri Mar 03, 2006 2:10 pm

I didn't know there was three methods, but I suppose the only change could be the speed.

#74221 - poslundc - Fri Mar 03, 2006 4:57 pm

Any efficient mixer will want to use DMA to load data from the mix buffer to the sound FIFOs. It is possible to manually load the FIFOs using a timer interrupt, but this is not going to be as efficient. (I once considered the possibility of mixing directly to the FIFO's and not buffering anything, but this seems like risky business.)

The remaining issue is when/how do you want to replenish/swap your mix buffers. This can either be done on a clock-basis (using a timer) or on a frame-basis (using VBlank).

The main advantage to using a timer interrupt is that it allows for more even buffer sizes (256 or 512 for example), and perhaps code that's a bit easier to follow because of it.

Mixing on VBlank, however, frees up the timer and lets you control more precisely when in your game loop mixing is to occur (as opposed to using the timer, in which case you will mix whenever the interrupt happens to fire). I've also heard that not having the timer interrupt is more friendly with multiplayer code.

Dan.

#74233 - Miked0801 - Fri Mar 03, 2006 7:10 pm

Quote:

I've also heard that not having the timer interrupt is more friendly with multiplayer code.


Nothing is friendly with multiplayer code :)

#74677 - RavenWorks - Mon Mar 06, 2006 11:15 pm

It seems to me that using interrupts is the most reasonable way to write any sort of mixer; which proves to me that there's something I'm not understanding, judging by how much people prefer the DMA method ;)

This might be a newbish question, but can I assign my own interrupt function to the same timer that's already being used for the DMA transfer to the sound buffer? If not, won't generating the new sound require a second timer, on top of the one already being used to fill hardware buffers A and B?

Or is that why people use vblanks? Fill a software buffer every vblank, and reset the sound DMA to its start every vblank as well, letting it walk its way down to the end while the screen draws? Something like that?

Thanks :)

#74693 - DekuTree64 - Tue Mar 07, 2006 12:36 am

RavenWorks wrote:
Fill a software buffer every vblank, and reset the sound DMA to its start every vblank as well, letting it walk its way down to the end while the screen draws?

Exactly :)
Only a few frequencies time out perfectly with VBlank though (see the table here). If you want something different you'll have to use a timer to count samples, but it's still usually best to mix on VBlank rather than using any timer interrupts.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#74694 - RavenWorks - Tue Mar 07, 2006 12:51 am

I was afraid that would be a big waste of RAM, but I suppose at 21024 Hz, that's only about 350 samples per vblank, which is about 3k of RAM... but still, is there that much of a benefit in doing it all at once vs. having a timer do it piece-by-piece, say, filling the upper two samples at half the sample rate? Or am I being way too stingy with the RAM ;)

#74713 - tepples - Tue Mar 07, 2006 2:40 am

Most games just fill a buffer every vblank and then set the FIFO DMA loose on that buffer.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#74718 - RavenWorks - Tue Mar 07, 2006 3:17 am

Why does Deku's guide recommend two buffers? Would the interrupt triggered by the vblank not have time even to fill up the first few bytes before the DMA starts to dig in to it, I guess?

#74782 - tepples - Tue Mar 07, 2006 5:37 pm

RavenWorks wrote:
Would the interrupt triggered by the vblank not have time even to fill up the first few bytes before the DMA starts to dig in to it, I guess?

Correct. Efficient mixers start by blanking the output and then adding one or two channels at a time to the output (unless you're a freak like jd and can figure out how to squeeze four channels into one set of 15 ARM registers).
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#74909 - SittingDuck - Wed Mar 08, 2006 7:35 pm

RavenWorks wrote:
I was afraid that would be a big waste of RAM, but I suppose at 21024 Hz, that's only about 350 samples per vblank, which is about 3k of RAM... but still, is there that much of a benefit in doing it all at once vs. having a timer do it piece-by-piece, say, filling the upper two samples at half the sample rate? Or am I being way too stingy with the RAM ;)


Having a timer to do it piece by piece, say sample by sample, would produce too many interrupts, too many function calls - the speed would be considerably slower. It's beneficial to process larger buffers.

#75023 - nl - Thu Mar 09, 2006 3:55 pm

for optimal audio quality you should use the native sampling frquency of 32768 hz. other frequencies (except for fractions of the native frequency like 16384, 8192) will result in more distorted, noisy sound. vblank does not fit with that frequency, so a second timer, cascading from the sample timer, would be needed for buffer refilling.

however, if audio quality is not that important, vblank timing may be the better solution.