-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes DynamicSoundEffectInstance Requesting Buffers Too Late #7566
base: develop
Are you sure you want to change the base?
Conversation
Fixes DynamicSoundEffectInstance Requesting Buffers Too Late
I'll need to look at this again another time as the tests don't quite look correct. According to this:
However some of the tests seem to be checking that only a single BufferNeeded event is raised per buffer used or play call. In other words only points 2 & 3 of the above, not point 1. This doesn't seem to match XNA which keeps raising the BufferNeeded event during playback until 3 buffers are queued. Edit: It seems the tests are based upon not submitting data when the BufferNeeded event is raised. This is where my PR doesn't match XNA. However the current MonoGame implementation doesn't match XNA when data is actually submitted with the event (which can be seen with the sample project). I'll need to look at this again and update the PR to match XNA, but also add tests for submitting data with BufferNeeded events as this is more important for correct playback operation. |
Point 1 makes me think that the check/event happens on every tick. |
Yeah, during normal playback some of the points seem to be asking for the same thing. However I think the points begin to be different when SubmitBuffer is called outside of BufferNeeded and when no SubmitBuffer occurs during a BufferNeeded event. My next step is to create a table of XNA results with the combinations of SubmitBuffer before playback, SubmitBuffer outside of BufferNeeded and no SubmitBuffer during BufferNeeded. I'm hoping to do that in the coming weeks and revise the PR. For now the PR will fix the choppy audio glitch but shouldn't be committed yet as it will cause tests to fail. |
Something that seems to work is to
edit |
I did quickly try the above, however I'm still getting failed tests with that. For some reason I thought I had tried the sample project with XNA, however I must have only compared it to the XNA docs. Point 1 is not being done by XNA and it will not automatically queue up 3 buffers (even though it's stated in the docs). Both XNA and MonoGame have the audio glitch when submitting buffers solely on the BufferNeeded event. Pre-submitting buffers before playback can fix this, but the documentation makes no mention of this as a requirement. Sorry for the confusion there. Also I noticed with the MonoGame documentation (https://docs.monogame.net/api/Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance.html) that the BufferNeeded event should be called "when the number of queued audio buffers is less than or equal to 2". Again this matches the XNA documentation but hasn't been implemented in this way. So going forward this raises the question should MonoGame match the documentation and the tests be revised or match XNA behaviour and the documentation be revised? Another thing I noted just is in the tests the Thread.Sleep calls within the SleepWhileDispatching loop can take longer than expected and this can cause intermittent fails. Adding StopWatch to exit the loop early seemed to fix this issue. Edit: Just noticed the remarks in the MonoGame documentation says "this event may occur when Play() is called or during playback when a buffer is completed", so that part is correct. I guess the question then is should MonoGame be changed to always automatically queue up 3 buffers or should manually queuing up buffers before playback be a requirement in the documentation? |
XNA implementation isn't that good. for example State isn't updated immediately after Play/Pause/Stop. I 'll try a couple more things. I will bring back the eventNeeded counter, but I have removed the code entirely from Play(). |
Great. Nice find on the article. I need to read it some more, but there are a couple of points of interest.
This comment implies buffers (multiple) should be sent on a BufferNeeded event, not just one.
This example is also submitting two buffers to "avoid glitches". That implies it's probably working as expected and a single buffer per event will cause glitches, which is what is occurring in the sample project. I guess the question now is should this be improved with MonoGame automatically calling BufferNeeded to properly maintain the TargetPendingBufferCount or should the documentation be improved to state that multiple buffers are required per BufferNeeded event. |
by looking at the test i see that xna fired event only on buffer completion. I prefer the documented behavior better. |
By the way, thank you for the test project. It helped a lot. |
No problem and thanks. Just looking at the test failures again it seems these are due to what happens when no SubmitBuffer occurs during a BufferNeeded event. This should stop additional calls to build up to the TargetPendingBufferCount, but there should still be a call for each buffer consumed. If I revert the PR (so that _buffersNeeded is counter of play/consumed events, not the number of buffers needed to reach the target) and change this
To this
Then this not only fixes the audio glitch but also passes all the existing tests as multiple BufferNeeded calls are ended early if the buffer count didn't change after a BufferNeeded event. I need to test this some more but it seems to work so far. |
the while loop will halt if the user write the following, unless you add a limit check
This is what i ended up with. Will probably break the tests.
|
If you were referring to the while loop in my code that won't happen as it already breaks the loop if the PendingBufferCount doesn't increase. With the code you posted I think it will fail the tests as it won't stop raising the event after SubmitBuffer isn't called. According to the document you linked:
The tests seem to be based around this, although this seems to go against point 1 of the XNA api (https://docs.microsoft.com/en-us/previous-versions/windows/xna/ff433726(v=xnagamestudio.40)) where events keep occurring in playback. The tests could be changed though if it was intended to keep raising events regardless of whether SubmitBuffer occurs. I'm not sure if this is desirable or not though. Just with the code I posted, to make it clearer I've reordered it and commented although it does exactly the same as before
|
This reverts commit 00fa367.
Fixes DynamicSoundEffectInstance Requesting Buffers Too Late
This pull request is to fix DynamicSoundEffectInstance requesting buffers too late. More details on the issue can be found here: #7565
For demonstration purposes please see the OpenALPendingBufferCount project within here:
https://github.com/squarebananas/MonoGameSamplesForIssues