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

Audio glitches when using the MME backend #30

Closed
dechamps opened this issue Nov 29, 2018 · 2 comments
Closed

Audio glitches when using the MME backend #30

dechamps opened this issue Nov 29, 2018 · 2 comments
Assignees
Labels

Comments

@dechamps
Copy link
Owner

dechamps commented Nov 29, 2018

I've noticed that, with FlexASIO 1.0, when using MME (default settings otherwise), with some USB audio device, audio from REW is glitchy. This doesn't appear to be the same problem as #29 because the stream callbacks do keep firing when using MME.

@dechamps
Copy link
Owner Author

dechamps commented Dec 3, 2018

Just like #29 though, increasing the default buffer size from 20 ms to 40 ms makes the problem go away. Switching to output only, however, does not.

Taking a look through the excellent API Monitor reveals that MME is using WASAPI internally (no surprises there). When the buffer size is too small, weird things can be seen in the sequence of WASAPI calls: MME literally stops and restarts the WASAPI audio client between buffers. This of course cannot end well. I suspect this is MME's way of reacting to a buffer underflow.

@dechamps
Copy link
Owner Author

dechamps commented Dec 6, 2018

Strike my last, this behaviour seems to be caused by FlexASIOTest being too slow for the period I was testing with (Windows console output is really slow). Testing with REW doesn't show these start/stop sequences.

There are suspicious periods between two waveOutWrite(), oscillating between 10 ms and 40 ms (proper behaviour would be a regular 20 ms cadence). I have verified that this is not caused by REW processing time, which is always very short (around 2-3 ms). Each buffer seems to take 50 ms to make it through the pipeline, instead of 40 ms.

Looking at WASAPI calls made by MME, and correlating that to MME buffer state at the time of the calls, MME's behaviour is surprising. MME provides buffers to WASAPI around 5-7 ms after waveOutWrite() is called, which is not quick but not necessarily a problem. The problem is that MME seems to be too slow to notify PortAudio that buffer space is available (i.e. it takes too long to switch the buffer state to DONE).

The issue can actually be seen at the very beginning of the stream, where MME initially provides WASAPI with a 40 ms initial buffer, which is fine, but then after the first 20 ms half is reported as consumed by WASAPI (through GetCurrentPadding()), MME, inexplicably, waits for an additional 20 ms before providing the next buffer to WASAPI. By that time, the WASAPI buffer is of course empty, and a glitch is pretty much guaranteed to occur. MME could recover by providing two additional buffers at that point, but doesn't, and seems to maintain a constant 20 ms lag. Unsurprisingly, this results in repeated buffer underruns in the WASAPI buffer.

When using a larger buffer size, such as 40 ms, the issue seems to disappear and the behaviour appears to be correct. I suspect that's because the WASAPI buffer always has a fixed length of around ~47 ms (2066 samples at 44.1 kHz) in my testing. It might be that MME only behaves correctly when the total size of its buffers (here, 80 ms) is larger than the WASAPI buffer size.

Just like #29, the correct fix would be to increase the default buffer size from 20 ms to at least 40 ms.

@dechamps dechamps changed the title Audio glitches when using the MME backend with REW Audio glitches when using the MME backend Dec 6, 2018
dechamps added a commit that referenced this issue Dec 7, 2018
DirectSound is unable to achieve a read cursor granularity lower
than ~30 ms on the input side, which means the default 20 ms buffer
size simply cannot work properly with the default backend.

Fixes #29 #30.
@dechamps dechamps closed this as completed Dec 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant