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

ASIO401 should support write-only mode for large buffer sizes #12

Closed
dechamps opened this issue Jan 24, 2019 · 1 comment
Closed

ASIO401 should support write-only mode for large buffer sizes #12

dechamps opened this issue Jan 24, 2019 · 1 comment
Labels
enhancement New feature or request

Comments

@dechamps
Copy link
Owner

Currently, ASIO401 always reads from the QA401, even if no input channels are enabled on the ASIO side.

For small buffer sizes this makes sense, because read pushback is the only signal ASIO401 can use to determine what the output queue watermark is - the alternative would be to keep the output queue filled, which would increase output latency.

However, for large buffer sizes that equal or exceed the hardware output queue size, the QA401 will push back on writes anyway, so we don't need to use read pushback as a signal, therefore we could simply not read at all in this configuration.

The advantage of not issuing reads is that it makes the pipeline more efficient (in particular it uses less USB bandwidth) and therefore reduces the risk of missing deadlines.

@dechamps dechamps added the enhancement New feature or request label Jan 24, 2019
@dechamps
Copy link
Owner Author

dechamps commented Feb 2, 2019

Currently, a read completes at the same time the previously written buffer has finished playback, and a buffer switch occurs immediately afterwards. In contrast, a write completes 1024 samples before the buffer finishes playback. If we request a buffer switch immediately after the write completes, we would be asking the application to produce the next buffer 1024 samples earlier, therefore increasing the output latency by 1024 samples.

One possible way to work around this is to sleep for the equivalent of 1024 samples (in CPU time, not QA401 time, since we don't want to read) after a write completes. The problem here is clock drift. We will resynchronize with the QA401 clock as soon as we block on a write, but that assumes that we will, in fact, block. If one iteration around the loop (including the sleep) is taking longer than the average time budget (i.e. ASIO buffer length), then the QA401 output queue will not be filled and we will not block on the next write. This makes this solution pretty much non-viable for a 1024 buffer size, and would likely increase glitch frequency for higher buffer sizes (especially if bufferSwitch() wants to make use of most of its time budget). That kinda defeats the point of the exercise.

I think a more reasonable approach is to simply accept that, in this mode, output latency will increase by the length of the hardware output queue, and allow the user to make the tradeoff between low latency and efficiency.

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

No branches or pull requests

1 participant