Skip to content
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 for WASAPI device stop #938

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from

Conversation

Pizzabelly
Copy link

My method of testing was to play a song and repeatedly pause and unpause with a considerably long fade-in/out and listen for pops. My program stops the device from a different thread after the first dataCallback where it returned entirely silence.

When draining the device, waitTime was being calculated in seconds, which could easily round to 0. WaitForSingleObject doesn't wait if given a 0ms timeout, causing the unchanged available frames check to always be hit and not drain the device at all. Also, move ResetEvent above WaitForSingleObject in the loop so it doesn't immediately wake up, which I occasionally observed.

Sometimes stopping the device gave a message [WASAPI] Failed to reset internal playback device.. That seems to be caused by not releasing an outstanding buffer before stopping the device. My understanding is that the remainder of that buffer would also have to be zeroed because the user has no way to handle that. The capture device case is untested but I assume it works the same.

Draining in WASAPI exclusive mode also appears possibly broken, with or without the changes here. It seems to work very different from shared mode. If it's down to timing/latency, i.e. if your device is too slow it will always cutout, I don't think I can properly test that. I noticed pops on both device stop and start so it may even be a deeper issue.

@mackron
Copy link
Owner

mackron commented Feb 7, 2025

Thanks, and sorry I didn't get back to you sooner. I'll review this next time I boot up my Windows machine and report back.

@Pizzabelly
Copy link
Author

I changed the ma_silence_pcm_frames call to use internalFormat/Channels instead of format/channels because that seems more consistent with the rest of the WASAPI functions.

I also got a proper Windows machine set up and did a lot more testing. I think the changes here are still good. I tested exclusive mode as well, padding the end of the stream with silence can mitigate the popping on both device start and stop. It seems the amount of silence is dependent on your device and the playback buffer size, which makes it really hard to test. I don't think "draining" is really a thing in exclusive mode and any kind of extra waiting before stopping the device causes very audible glitching. So not sure if there's much that can be done there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants