nukeykt / Nuked-OPL3

Highly accurate Yamaha OPL3 (YMF262, CT1747) emulator
GNU Lesser General Public License v2.1
166 stars 18 forks source link

Multiple synths conflict #4

Closed Malvineous closed 3 years ago

Malvineous commented 3 years ago

Is there any sort of global state used in this synth? I am debugging https://github.com/adplug/adplug/issues/120 and here there are two instances of the NukedOPL3 synth in the same program. If we call OPL3_GenerateStream on only one instance then playback is fine, but if we call that function on both instances then there is significant audio corruption. The song tempo also seems to increase, as if we are losing chunks of audio. It's almost like the OPL3_GenerateStream call advances time for all NukedOPL3 instances instead of just the one being called.

I have looked through the code but I cannot find any sort of global state. I tried removing the static qualifier on everything but it made no difference. Using other emulators like the one from DOSBox works fine with multiple instances, it's only NukedOPL3 that seems to have a problem.

Is there any reason you can think of why we are unable to run two instances of the synth at the same time?

nukeykt commented 3 years ago

Vanilla version does not use any global variables AFAIR. libadlmidi for example uses my core and doesn't have any problems

Malvineous commented 3 years ago

Thanks for the quick response! I've done some more investigation, and it now seems to be a problem with OPL3_GenerateStream() where you get audio corruption if you call it with a very small numsamples value. If I change our buffer fill function to make many calls to OPL3_GenerateStream() with small buffer sizes, then the audio comes out quite bad, with pops, clicks and lost samples. Using numsamples of 4 or smaller seems to cause problems, 8 or larger seems ok.

I am confused about this because looking at your code, it looks like you generate one sample at a time anyway, so why would the number of samples matter?? I will keep investigating and see if I can work out what's going on.

Malvineous commented 3 years ago

Ok gonna close this issue as it looks like it's elsewhere after all. If I use a different audio output method (SDL, disk writer, etc.) then everything works fine. It only seems to break with the ALSA output device. If I increase the ALSA buffer then that improves the corruption. It looks like something in the ALSA chain isn't handling buffer sizes properly.

I still can't explain why it only affects NukedOPL3 and not any of the other synths, but given that it works with the disk writer plugin I think we can safely say that there's nothing wrong with NukedOPL3! Sorry for the noise :)