icculus / mojoAL

An SDL2-based implementation of OpenAL in a single C file.
https://icculus.org/mojoAL/
zlib License
154 stars 20 forks source link

Buffers can be deleted while still attached to a source #6

Closed sonneveld closed 2 years ago

sonneveld commented 2 years ago

I noticed a behavioural difference between mojoal and macos's openal, and I think it suggests a bug.

Basically you can delete buffers while they are still attached to a source. In mojoal, you don't get an error on delete and when you attach new buffers to the source to play a new sound, you get a brief blip of the previously buffered audio.

In comparison to macos's openal: when you attempt to delete a buffer that is still attached, you will get an "Invalid Operation" error.

Attached is source for testing this bug. Create two different raw audio files called tone_880.raw and tone_440.raw (different so you can hear the previous buffer play a bit), and comment/uncomment out #define AL_CLEAR_BUFFER_ON_STOP to trigger the bug.

openal_test.cpp.tar.gz

Tested using mojoal 8af8cd366257e3b9d734f635f7d17d67fc4d48f7

ericoporto commented 2 years ago

@sonneveld I think it's a different case, but from this PR here they also appear to have solved for their use a similar blip case: https://github.com/gosu/gosu/pull/619

icculus commented 2 years ago

So this wasn't the buffer or source state being incorrect (the test app was correctly unqueueing buffers before deleting them), it's that the internal buffer the source uses for resampling wasn't being cleared during alSourceStop(), so when you restart it, it would still have a little data from the last buffer sitting in there, resampled and ready to be played, before it would start using data from the new buffer.

alSourcei(...AL_BUFFER...) happens to forcibly destroy and recreate the SDL_AudioStream it uses for resampling, which is why that would work around the issue.

This is fixed now.