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.

DS development > Audio mixer callback function not interrupt safe

#129879 - TheChuckster - Mon May 28, 2007 4:59 pm

I finally managed to get sound streaming to work on the DS, but the callback function that generates the audio (via emulation of the Atari 2600 TIA chip) is not interrupt safe.

I am not quite sure why it is not interrupt safe. What makes a function "interrupt safe"?

I do know that if I put that function within an interrupt, the DS locks up.

I tried using a "semaphore" global variable that would tell the emulator to generate (x) sound samples during the next frame into buffer (y) for the sound streaming, but that is too slow.

I even tried moving the emulator loop into the interrupt code itself (just as a test to satisfy my curiosity). The DS still crashed. Apparently, even if the emulator loop is executed "in sequence" inside the interrupt, it still crashes. Even though the only difference is that it is being called inside an interrupt.

Which leads me to my next question, can another interrupt interrupt an interrupt in progress? Maybe that's screwing things up...

Is there a way to work around this? I brainstormed a bit and thought of using filling up a secondary buffer during emulation, and then just having the callback function use that. I'm not sure if that would work, but it would be challenging to know the position of the "sound cursor" within that secondary buffer.

How have other developers accomplished this? It might just be easier for me to identify what is making the TIA update function "interrupt unsafe". What should I be looking for?

#129880 - tepples - Mon May 28, 2007 5:01 pm

A function is interrupt unsafe if it takes longer than interrupt time to execute it, or if it uses a lot of stack space, or if is not thread safe.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#129881 - TheChuckster - Mon May 28, 2007 5:09 pm

In that case, it probably is taking too long to execute.

#130109 - TheChuckster - Thu May 31, 2007 12:57 am

This is to save any other developers many hours of frustration. I solved the problem by using a ring buffer.

WinterMute: how is "ring buffer" in any way related to "interrupt safety"?
TheChuckster: well
TheChuckster: instead of calling the emulator audio callback function in the interrupt
TheChuckster: i have it fill up the ring buffer in the main loop
TheChuckster: and then i just read in the buffer in the interrupt

There you have it. If you have an alternative solution in mind, feel free to post it. What I'm doing works beautifully, though, even if it's not the cleanest way of handling this.