APU sound buffering strategies

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
APU sound buffering strategies
by on (#140668)
I implemented all the APU channels in my emulator and it doesn't sound that bad, but it does occasionally crackle. The emulator is likely producing slightly fewer sound samples than the target sample rate due to the occasional slow-down. I was considering buffering up samples and only writing to the sound system once per frame. If the buffer was not fully filled, it could fill the tail end with duplicates. I'm not sure if that's a good strategy. What do other emulators do?
Re: APU sound buffering strategies
by on (#140674)
Time to bring up past threads...

viewtopic.php?f=3&t=11612
viewtopic.php?f=3&t=9478 (probably the most relevant thread)
viewtopic.php?f=3&t=9454

nemulator's methodology is most likely the best choice, but it may or may not require newer Windows (ex. Vista or 7 onwards). James can explain it if you're curious. (I like how I just volunteered him to do so, haha...)

You didn't disclose what platform/architecture you're developing for, or if multi-platform, what APIs and SDKs/frameworks you're using (e.g. SDL and what version etc.). All this matters.
Re: APU sound buffering strategies
by on (#140714)
Thanks koitsu. Those forum links were very helpful.
Re: APU sound buffering strategies
by on (#140732)
I find that dynamically resampling sounds awful, it's all warbly. Retroarch does it, and it's annoying, I need to change its sample rate change ratio down to the lowest possible setting to not hear warbling.
Re: APU sound buffering strategies
by on (#140739)
koitsu wrote:
nemulator's methodology is most likely the best choice, but it may or may not require newer Windows (ex. Vista or 7 onwards).

nemulator requires >= Windows Vista, but this method does not. It should work with XP or any other OS, in theory. Windows/DirectSound may have an advantage here, though, because you can directly query the position of the write and playback cursors of the output buffer and get an accurate measurement of the actual playback rate. From what I know of other audio APIs (admittedly, very little), streaming is accomplished by providing packets of audio through a callback method. You could infer the playback rate by how often that callback is called, but I'm not sure how accurate it would be.

Anyway, OP, if you have any questions after reading through those threads, I'd be happy to answer them.

Dwedit wrote:
I find that dynamically resampling sounds awful, it's all warbly. Retroarch does it, and it's annoying, I need to change its sample rate change ratio down to the lowest possible setting to not hear warbling.

Done correctly, it should be inaudible. nemulator's playback rate fluctuates +/- just a couple of hundredths of a percent.