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.

Coding > Audio works fine in VBA, buggy on real GBA

#494 - DefaultLocation - Wed Jan 08, 2003 3:49 am

Hi all,

I have taken over a GBA game demo created by someone else, and the biggest bug at the moment is the audio. The audio works perfectly fine using VisualBoyAdvance, but when I try it out on my retail GBA, it is broken.

I am using a modified version of the "Audio Programming on the GameBoy Advance Part 1":

http://www.gamedev.net/reference/articles/article1823.asp

Basically I just created support for a second sound channel using Direct Sound channel B and timer 1. I use this for my music (yeah, lame I know) so I loop that while I play my sound effects on DS channel A (with timer 0). This works perfectly in VBA, but when I put it on a cart (Flash Linker) and try it in my GBA, it doesn't behave properly.

On the real GBA, the "play sound sample" calls seem to somehow be delayed by one call (bear with me). That's a terrible explanation, maybe an example will be better. Say at time 1 I want to play sound effect A, and at time 2 I want to play sound effect B. Works fine on VBA, but on the GBA, at time 1 NO sound will play, and then at time 2, sound effect A will play. This will continue to behave in this manner (at time 3, sound effect B, etc.). I time the sound effect DMA transfer by the vblanks and sample size (as in the tutorial), so that I stop the transfer when the sound effect is over. But it is using the wrong value, it is using the # of vblanks for the sound effect that SHOULD be playing, instead of the one that is playing (so I guess really it's the RIGHT # vblanks, but the wrong sound effect is playing). So this part seems to be behaving properly.

So this all happens whether I use one channel (A) or both channels (A+B). The only thing I can think of is that somehow the buffers (FIFO) are not emulated exactly the same as the real GBA, or maybe some difference in the DMA transfer settings?

I can post my modified audio code if anyone cares. Thanks for the help!

#503 - jaymzjulian - Wed Jan 08, 2003 5:22 am

basically, afact, the issue is, the GBA sound registers come up in a completly uninitialised state when you power the thing up, whereas VBA initualises everything to zero for you ;).

The solution is initialise the things, wait a frame for the audio hardware to catch up with you, and *then* start playing.

The other solution, of course, which I implented originally, was play the first note twice ;)

#558 - DefaultLocation - Wed Jan 08, 2003 8:25 pm

Well, I used the initialization that was shown in the tutorial, shouldn't that clear everything out? There is not much documentation on this, can you tell me what extra work I need to do for initialization?

This is what I have from the tutorial:
Code:
void initialize_Sound ( void )
{
   // turn on the sound chip
   REG_SOUNDCNT_X = SND_ENABLED;

   // make sure DMG sound output channels 1-4 are turned off (doesn't affect Direct Sound)
   REG_SOUNDCNT_L = 0;

   // set the Direct Sound output control register
   REG_SOUNDCNT_H = SND_OUTPUT_RATIO_100 |   // 100% sound output
                DSA_OUTPUT_RATIO_100 |   // 100% direct sound A output
                DSB_OUTPUT_RATIO_100 |   // 100% direct sound B output
                DSA_OUTPUT_TO_BOTH |   // output Direct Sound A to both right and left speakers
                DSB_OUTPUT_TO_BOTH |   // output Direct Sound B to both right and left speakers
                DSA_TIMER0 |         // use timer 0 to determine the playback frequency of Direct Sound A
                DSB_TIMER1 |         // use timer 1 to determine the playback frequency of Direct Sound B
                DSA_FIFO_RESET |      // reset the FIFO for Direct Sound A
                DSB_FIFO_RESET;      // reset the FIFO for Direct Sound B

   REG_DMA1SAD = 0x0;
   REG_DMA1DAD = 0x0;
   REG_DMA1CNT = 0x0;

   REG_DMA2SAD = 0x0;
   REG_DMA2DAD = 0x0;
   REG_DMA2CNT = 0x0;
}


The last 6 lines (the REG_* = 0) I just added, which didn't seem to make a lick of difference. Also, my stop_Sound() code (taken from tutorial) doesn't seem to work on the real GBA either. I appreciate the help so far, thanks!

#854 - dummer Anf?nger - Sat Jan 11, 2003 9:45 am

Hm ... i have an simular problem with the midi lib (look here ito the forum) that would work on real hardware as well, too.

First i think its stupid to make an emu that dont generate same errors as real hardware too because its not an 1:1 emulation :/

Emulate me more errors, i need errors ^^



However. Can it be that the timers (using dovotos timer code) works too different? In past i have big differences between emu timer and gba timer. but this was before i started using sound
_________________
... but im just a dummy Newbie

(sorry for my terrible english)

#855 - Splam - Sat Jan 11, 2003 10:06 am

Timers on VBOY aren't exact but they're VERY close :) I use vboy for testing most of my code but when working on Splam!SID I have to compile different versions for vboy and gba else you get timer errors.

#860 - NEiM0D - Sat Jan 11, 2003 1:05 pm

Have a look at my NMOD assembler source, it's a complete module music player for GBA. (It should be somewhere on http://www.gbadev.org).

Why are you using 2 timers?
Only 1 with the playback rate is enough.

Oh btw, there is a C version included in the NMOD zip, but it won't compile though, you need to fix some stuff.

Cheers,

NEiM0D.

#1061 - tepples - Tue Jan 14, 2003 7:17 am

NEiM0D wrote:
Why are you using 2 timers?
Only 1 with the playback rate is enough.

You need two timers if you want the GBA to stop at the end of the wave, as in Doom and Pinobee. One timer controls the sample rate; the other controls the number of samples played back. But with a mixer such as the one in NMOD or my Tri Engine, on the other hand, you always know that your buffer is exactly n samples long and exactly one frame long, so you don't need another timer counting off samples.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#1104 - snug - Tue Jan 14, 2003 5:20 pm

One thing to keep in mind if you are setting a restart value for your timer: In VBA you can set this value either before or after you start the timer, but on the AGB I'm pretty certain you HAVE to set it AFTER you start the timer or it will reset to 0 when it overflows.

#1145 - Splam - Wed Jan 15, 2003 12:13 am

Don't forget also that if you've got to STOP the dma before you can start it properly again. The emu's let you get away with some things but the harware will throw a fit at you if you do it wrong, it's also very precise on where you stop/reset things.

#1148 - Costis - Wed Jan 15, 2003 1:09 am

Hi,

Due to the ROM wait-states, etc. it's very difficult to accurately emulate the GBA's timing 100%. Also, the GBA hardware and the ARM processor itself are not simple little frameworks. Instead, they are very complicated and it is pretty nice to know that VBA can accurately emulate most of it. 100% accurate emulation is very rare for advanced\complicated systems.

Costis