-
Notifications
You must be signed in to change notification settings - Fork 467
feat: add Stream::buffer_size() and improve AAudio buffer configuration #1080
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
base: master
Are you sure you want to change the base?
Conversation
60a92a5 to
401e5b9
Compare
|
@will3942 @marcpabst @j-n-f as you've requested or contributed to similar in the past, would you give your view? |
|
Note that the burst size can be smaller than the actual buffer size, and on some devices (e.g., the Pixel 9), it can be low enough that using it will cause underruns in many cases. c.f. cmus/cmus#1386 |
Thanks for that nudge. With this default buffer thing it seems that no matter how you try do it right, you never do it right. While I can see a 80 ms minimum working for many scenarios, setting minimums is precisely what we've been trying to steer away from since v0.17 because in the end, they are rather arbitrary and use-cases dependent. It seems that the best thing to do would be to dynamically optimizing the buffer by monitoring underruns like here: https://developer.android.com/ndk/guides/audio/aaudio/aaudio#tuning-buffers. I'll save that for another PR - I think that this PR won't make things on Pixel 9 better or worse from what we already had. Can you confirm? |
b3270f3 to
f9eb872
Compare
|
@roderickvd Will this set the same buffer size as AAudio would default to if we don't specify a buffer size (as in the latest master)? If so then I'm happy, but I can't test until 12 Jan. Agreed that we need to adjust in response to underruns, or give the developer the ability to. At the moment we've measured an acceptable buffer size for our application in production and set that manually. |
I'd also need someone to confirm for me. |
Not entirely sure. In cmus, I ended up taking a shortcut and just choosing a relative high buffer size based on a fixed period to reduce CPU usage and to avoid underruns (especially as newer devices are capable of lower latency streams) since I wasn't concerned about latency. When testing AAudio with cmus, the default buffer size on the 9 was 3 times the burst size, but on the 8, it was 2 times the burst size. I haven't fully followed how it's set in AOSP, but some random thoughts:
You get the value of |
You may be right. Your pushback makes me think that we probably cannot reliably make assumptions about what devices do when we set nothing at all.
These are very valuable resources, thank you very much for pointing to these lines so specifically. Key pattern seems that nobody actually calls Google seems to set a large capacity but start with minimal active size, then grow it on underruns. So our current implementation is likely over-constraining AAudio by explicitly setting the callback size when we should just be setting the capacity and staying out of the way. This seems to be confirmed over at https://developer.android.com/ndk/reference/group/audio:
So I implemented this equivalently in 5656daa, what do you think? On top of this, we'd still want the dynamic buffer tuning.
Yeah, I know. I took it from https://developer.android.com/ndk/guides/audio/audio-latency#buffer-size. Oboe sets 16 as floor. |
f3fcca3 to
5656daa
Compare
|
Now that I'm working on a tuning implementation, I'm realizing that we should be setting buffer size instead of capacity. |
90cfd27 to
3cb1c06
Compare
Add buffer_size() method to Stream trait that returns the number of frames passed to each data callback invocation (actual size or upper limit depending on platform). AAudio improvements: - BufferSize::Default now explicitly configures using optimal burst size from AudioManager, following Android low-latency audio best practices - buffer_size() query falls back to burst size if frames_per_data_callback was not explicitly set - Refactored buffer configuration to eliminate code duplication Addresses #1042 Relates to #964, #942
Replace `Stream` enum with a struct containing `inner: Arc<Mutex<AudioStream>>` and `direction: DeviceDirection` fields. This eliminates code duplication while maintaining the same functionality.
f4d1b0e to
400a8ed
Compare
Add
buffer_size()method toStreamtrait that returns the number of frames passed to each data callback invocation (actual size or upper limit depending on platform).AAudio improvements:
BufferSize::Defaultnow explicitly configures using optimal burst size from AudioManager, following Android low-latency audio best practicesbuffer_size()query falls back to burst size ifframes_per_data_callbackwas not explicitly setAddresses #1042
Relates to #964, #942