Sound syncing in emulator

I’m working on an NES emulator, and having problems with syncing the sound… I’m using the Perf-timer to time the framerate, but it seems I’m still producing the audio too fast.
The sourcedataline buffer will very quickly fill up, and introduce considerable lag from when an event takes place in the game until it’s eventually reflected in the music/sound fx.

The amount of samples produced each frame is constant, so it seems I’m producing a little bit too much. The problem now is writing the produced samples to the line without the buffer emptying, and also without writing too much.

What would be the best way to sync this? I’ve tried adjusting the sleep time between frames, and also sleep some extra when too many frames are produced, but it seems that no matter how I do it, I either get lots of buffer underflows, or a horrible lag… :’(

I guess the real problem is, I don’t know how much data is in the buffer at any given moment. The method for getting the available bytes before blocking doesn’t seem to be updated frequently enough, so I can’t rely on it. Is there any solution to this? Any sound package I can use that is better at this?
Any help will be appreciated :slight_smile:

Yes, that is a difficult one which I haven’t totally solved myself.
What I did was:

  • Have a seperate thread with the sound chip emulator in a tight loop that fills the sound buffer.
  • The sound buffer is as small as possible (to avoid underruns and to minimize lag)
  • The separate thread just keeps filling the buffer until it blocks (when the buffer is full).
  • The main thread feeds the sound thread with commands for the sound chip (usually using CPU ports or memory mapped I/O).

This approach works, but has some problems (feeding many commands in quick succession is sometimes a problem, sound timing is sometimes unstable). Maybe I need to sync the threads but I’m not sure…
It looks like sometimes the thread blocks for longer periods than other times causing the instabilities where I expected that blocking to be of more or less fixed periods.

The sound chip emulation and the sampling is clocked by the CPU emulation, so I can’t put it in a separate thread. If I don’t sample at the correct time, the produced sound won’t be accurate, especially at high frequencies. I’ve tried getting a smaller sound buffer, but it stays at 65536, which is way too big (is this device-dependent?).

Hmm I dunno, I set up a line buffer of 4096 and that seems to work fine here.

You might want to check out NESCafe (http://www.davos.co.uk/nescafe/index.html), another NES emulator with sound. As far as I remember, sound was emulated ok.