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.

Beginners > Way of coding when playing sounds

#157445 - mca - Sat May 24, 2008 5:25 pm

Hi,

is it recommended to use the VBlank as a kind of timer to play sounds a distinct amount of seconds and to pause a distinct amount of seconds between two sounds?

Should other mechanics be used like 'Timer IRQs' to accomplish this?

Thanks...
mca

#157447 - Maxxie - Sat May 24, 2008 5:46 pm

It is possble to do so, there are some pitfalls however

If you use VBLank to feed a buffer, you have to keep in mind that the sample rates (after converting it into the format the registers expect) contain some rounding issues.

A part of a ringbuffer (organised in 4 chunks) for sound i am currently using for fixed 11025 s/sec music reads as
Code:

      SCHANNEL_TIMER(0)  = SOUND_FREQ(11025);
      // this rounds to -1519 as register value, which in return are 11031.593811718235681369321922317 samples per second
      // or 1470.8791748957647575159095896423 per 8 frames (on rounding to 1471, we are losing ~8/100,000th on precission)
      //     -> we are skipping one chunk (1/4th) per 4596875 samples = 416 seconds = 6:56mins
      // or 6618.956287030941408821593153389 per 36 frames (on rounding to 6619, we are losing ~7/1,000,000th on precission)
      //      -> we are skipping one chunk (1/4th) per ~236392857,14samples = 21429 seconds = 357:9mins


which explains it abit.

When using timers you can chose delays between feedings that fit better to the sampling frequency, and you can achive higher precission even on smaller buffers.

On the other side,
The VBlank solution is my choice because it synchronizes sound with everything else. If i send the DS into Sleep (Lid closed) i am just turning off/on sound hardware and VBlank at nearly the same time, so that i don't need to resync both again when awaking, which i would need otherwise because timers would still continue while sleeping or load the refresh value when disabling/enabling again.