-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Resolve some popping and mistiming in AudioStreamInteractive #99264
base: master
Are you sure you want to change the base?
Conversation
I did some further testing, and I have discovered a new bug introduced by this PR, specifically due to the changes from Since this seems like an underlying issue with those streams, I'm going to undo the changes from |
Oops, tried to enable your workflow but that removed the draft status for some reason; that should be resolved now |
The draft status is for when you think the PR needs more work from your side and should not be merged as is (e.g. in between the time you found a bug in your PR and fixed it). If you think it's ready and you would like others to take a look and give feedback it should be marked as ready for review. |
Yeah, it should be good to go now. I'll mark it as ready. Thanks! |
Just encountered another regression due to the change with always returning |
Fixes #94538. Tested using that issue's MRP, as well as with small modifications to it (e.g. converting to WAV and checking for pops/mistiming there as well). Also tested using the original interactive music project from #64488 to ensure no issues appeared there.
In all, from what I could identify, there are several issues at play here, which produce different popping and mistimings:
queue_active
field to each state, which queues a state to be activated after all currently-active states have finished mixing (and potentially queuing). This is only used for auto-advance, as it is irrelevant otherwise.from_state
's playback position, which is from after mixing the current buffer. This erroneously offsets the queue timing by the duration of the mixing buffer. This PR solves this by tracking the playback position of the state before the current mixing started, and using that for auto-advance queuing, which is the only place that is affected. This also sidesteps issues fromAudioStreamPlaybackResampled
causing another time offset with the duration of its internal buffer, because it immediately begins mixing whenstart()
is called.AudioStreamPlaybackResampled::mix
was the culprit (which is used for OGGs). When it runs out of data to mix, it seems like it reuses old data that happens to be in the internal buffer, repeating it. Whilemix()
did originally return a lower number of mixed frames to signal this, AudioStreamInteractive did not account for it, and I'm sure other locations do not as well. I modifiedmix()
toalways returnsample silence when it runs out of data. This seems to work well, but I would like verification that this is a good solution - I tried some others beforehand, with limited success.p_frames
, and toThis is more of a future-proofing thing (and feel free to undo these changes for this PR if desired), but I changed instances ofThis has been undone for now and will be reintroduced in a future PR, see Resolve some popping and mistiming in AudioStreamInteractive #99264 (comment).float
todouble
when calculating queue times/offsets. This is to prevent floating point inaccuracy drifting a few samples in edge cases where music can last very long (probably at least 10-20 minutes), and the cost is negligible due to how infrequently_queue()
is called. It's also consistent with all the other values usingdouble
.