-
Notifications
You must be signed in to change notification settings - Fork 189
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
bluealsa-aplay delay reporting improvements #738
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #738 +/- ##
==========================================
- Coverage 70.49% 70.49% -0.01%
==========================================
Files 96 96
Lines 15999 16005 +6
Branches 2510 2508 -2
==========================================
+ Hits 11278 11282 +4
- Misses 4604 4606 +2
Partials 117 117 ☔ View full report in Codecov by Sentry. |
I've just pulled your PR and when streaming from Android to RPi I still can see ClientDelay ~500 ms. I've tested with AAC, so SBC should be ~450 (AAC has total codec delay ~75ms). When starting bluealsa-aplay while the A2DP is already started the delay is ~300 ms. So, maybe the PCM start threshold should be changed (now it starts when the buffer is full), or at least allowed to be tuned by the user? |
Also, regarding delay reporting, I'm still not sure what is wrong with Windows™. With this PR the A/V sync seems to be better, but I'm rather far from stating that the A/V works as expected. The case is that now the initial overall delay is lower, so it appears that A/V is in sync... but it's not :D Also, I think that now, since the delay reporting is in place (and at least works with BlueZ-BlueZ setup) it's time to have another look at the problem reported in #459 Because when playing video I can see steady delay accumulation (Windows sends audio faster than RPi plays it)... |
Hmm, that is disappointing indeed. This PR sets the ALSA buffer size to 200ms, so for a hw device the maximum ALSA delay cannot be significantly higher than that. I can only assume that the balance of the delay is from samples in the fifo or read buffer. Can you provide more info about the hw setup and stream parameters? I'm using
With this PR the start threshold is 100ms, so I would expect a typical delay to be just over 100ms; and in fact in my testing I see ClientDelay values between 120ms and 150ms.
Sure, if you find that really helps, but I note that
I don't have any Windows to test with. I do find it bizarre that one OS would run a clock significantly faster than Linux or iOS. Does Windows perhaps use a different sample rate? The only time I've seen a significant difference in clock rates is when using |
I've now set up a USB audio card on the pi zero, and I see the same results as with the i2c card: excellent A/V sync with iphone, linux/pipewire and linux/bluealsa; steady ClientDelay with both 48000 rate streams and 44100 rate streams (value changes only when the stream is paused then unpaused, and is always in the range 105ms to 140ms) I've also tried with "plug:'dmix:IQaudIODAC'". In this case when using 44100 rate streams the ClientDelay does steadily increase with default ALSA config, but is constant when dmix is configured according to the note in the bluealsa-aplay manual page (as amended by this PR). Is there any other specific config I need to use to reproduce your results? I may be able to set up an old pi 1B+ with USB bluetooth to try the (really poor) on-board jack-plug audio output on that, but will need several days to get all the pieces together. |
Hmm... so maybe I will have to do testing again... I've been testing on RPi4 with connected JBL GO2 (Bluetooth speaker) via USB. And yes, I've put dmix in front of hw, so maybe that's the case. I'll try test it on my laptop later today. Anyway, if you are saying that you have excellent A/V sync with this smaller buffer, I think that we can go with this PR. In case of underrruns user can always increate the buffer, but at least the default will be tuned for lower latency. |
I've now done some long-running tests, and in these I can clearly see the ClientDelay value increasing. The rate of increase is small, somewhere between 50ms and 70ms per hour, so I can play audio for over 4 hours before the fifo becomes full and frames are dropped by the server. Throughout this time the A/V sync remains correct (as far as I can tell from watching lip-sync for speech, and drum stick beats etc for music). So I conclude that the delay reporting is accurate enough for typical bluetooth audio usage.
There may be some use-cases where it would be beneficial to limit the absolute size of ClientDelay by using frame rate adjustment, but I see that as a separate issue which does not affect the validity of this PR. I would like to re-word the commit comments slightly, then I will mark this PR as ready for code review. I am happy to make any other changes that you request. |
0de9503
to
0bd2182
Compare
Yes, I was not referring to that PR, but for something that might be worth looking at in the future :)
Yes, sure. I have no additional comments regarding this PR. Like I've said, changing default buffer size is OK as long as there are no underruns in common default usage. |
It seems that safari on the iPhone cannot adjust A/V sync when the audio latency exceeds about 400ms. So to keep the default delay when using bluealsa-aplay below that critical value, change the default ALSA hw params to lower values which are still compatible with the majority of sound cards.
0bd2182
to
e77b82b
Compare
This PR attempts to resolve two issues I've found with the new sink delay
reporting.
The first is that although A/V sync is mostly good with BlueALSA devices as source,
my iphone is unable to sync. I found that a typical commercial sink has a delay
between 100ms and 200ms with both SBC and AAC codecs, whereas my BlueALSA sink
has a delay of over 400ms. By adjusting the bluealsa-aplay ALSA parameters to
reduce the delay, I can achieve very good A/V sync with both the iphone and
BlueALSA sources.
The second is that although A/V sync is generally very good, it can on occasion
be understated by over 100ms (as measured by setting the ClientDelay property on
a BlueALSA source to correct the sync). I believe this is caused by the
relative payload sizes of the L2CAP frames, codec frames, and ALSA start
threshold, combined with the precise timing of the arrival of the initial L2CAP
frames. In some runs, sufficient PCM frames accumulate in the pcm pipe and/or
bluealsa-aplay read buffer so that they cannot all be transferred to the ALSA
buffer in a single iteration. So I have extended the delay calculation to
account for these buffers, and so far with this change I have had always had
good A/V sync with all source devices .
This needs testing with a variety of sources and sink devices to check that the
reduced default ALSA start threshold and buffer size do not lead underruns; I
have not found any data to help select the "best" compromise values, so the
values chosen here are somewhat arbitrary.