Best way to get clean sound below 60fps?

support for the gba/nds sound library from www.maxmod.org

Moderator: eKid

Post Reply
Chano
Posts: 28
Joined: Fri Dec 12, 2008 7:38 pm

Best way to get clean sound below 60fps?

Post by Chano » Sat Dec 13, 2008 12:56 pm

Which way do you think is the best to get clean sound below 60fps?

If you put the mmFrame call after VBlank interrupt (mmSetVBlankHandler(mmFrame)) the sound output is great at any frame rate, but if you get too much active channels probably you'll run out of VBlank cycles.

I think the best idea is to call mmFrame at the end of VBlank period when the game is at 60fps and to call mmFrame after VBlank interrupt when the frame rate drops below 60fps:

Code: Select all

//Main loop:
while(1)
{
	// Game logic:
	...

	mmSetVBlankHandler(NULL);

	VBlankIntrWait();

	// Update GBA HW during VBlank period:
	...

	mmFrame();
	mmSetVBlankHandler(mmFrame);
}
Updating maxmod this way in my engine the sound output is good until frame rate drops below 30fps (and I don't know why :p).
So... which way do you think is the best to get clean sound below 60fps?

eKid
Posts: 65
Joined: Sat Dec 06, 2008 6:07 pm
Contact:

Re: Best way to get clean sound below 60fps?

Post by eKid » Sat Dec 13, 2008 4:24 pm

Huh, that code should work okay...

Only threat I see is if a VBlank interrupt occurs between mmSetVBlankHandler(NULL) and VBlankIntrWait(); which isn't very likely to happen.

Does it make a constant distortion noise when the framerate drops? How much work are you doing inside "// Update GBA HW during VBlank period:"?

Another solution would be to call mmFrame in the VCount interrupt, that way you keep your VBlank cycles and get a smooth 60hz update too. Also, when updating maxmod in an interrupt, you must make sure it doesn't collide with any maxmod functions [they aren't irq safe].

Code: Select all


volatile int sound_locked=0;
volatile int sound_needs_update=0;
void vcount(void)
{
   if( !sound_locked )
      mmFrame();
   else
      sound_needs_update=1;
}

main()
----------
...
irqSet( IRQ_VCOUNT, vcount );

while(1) {

   // do software 3d rendering (or whatever you're doing :)
   ...
   // lock updates
   sound_locked = 1;
   // do music/sound effects
   ...
   
   // unlock updates
   sound_locked = 0;
   if( sound_needs_update ) {
   
      // update canceled frame
      sound_needs_update = 0;
      mmFrame();
   }
   VBlankIntrWait();
   
   // update GBA HW
}

Chano
Posts: 28
Joined: Fri Dec 12, 2008 7:38 pm

Re: Best way to get clean sound below 60fps?

Post by Chano » Sat Dec 13, 2008 6:48 pm

Only threat I see is if a VBlank interrupt occurs between mmSetVBlankHandler(NULL) and VBlankIntrWait(); which isn't very likely to happen.
Mmm... I had some profiling code between mmSetVBlankHandler(NULL) and VBlankIntrWait(), so I moved that code away and the sound distortion is almost gone. Good!
Does it make a constant distortion noise when the framerate drops?
Nope, random clicks.
How much work are you doing inside "// Update GBA HW during VBlank period:"?
Variable, but it should never reach VDraw period.
Another solution would be to call mmFrame in the VCount interrupt, that way you keep your VBlank cycles and get a smooth 60hz update too.
I tried to call mmFrame in the VCount interrupt before, but it collides with HBlank interrupt.
Also, when updating maxmod in an interrupt, you must make sure it doesn't collide with any maxmod functions [they aren't irq safe].
I'll have that in mind.

eKid
Posts: 65
Joined: Sat Dec 06, 2008 6:07 pm
Contact:

Re: Best way to get clean sound below 60fps?

Post by eKid » Sun Dec 14, 2008 12:10 am

Ah HBlank interrupts.. You could allow nesting in the vcount interrupt so the hblank interrupts don't get missed (I don't suppose you're doing anything sound related in them).

Code: Select all

void vcount(void)
{
   REG_IME = 1; // allow interruption
   if( !sound_locked )
      mmFrame();
   else
      sound_needs_update=1;
}

Post Reply

Who is online

Users browsing this forum: No registered users and 12 guests