-
Notifications
You must be signed in to change notification settings - Fork 5k
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
Inconsistent AL_SAMPLE_OFFSET updates on Raspberry Pi OS leading to audio synchronization issues (too slow playing position update with too large sample steps) #6422
Comments
I can't see this getting much attention anytime soon. |
I believe this bug is a key factor contributing to choppy sound during audio and video playback, similar to what occurs on devices like the Raspberry Pi Zero 2W. Therefore, addressing this issue is important to ensure smooth sound playback and avoid potential disruptions in audio performance. Which I believe is very important. |
And how long has this problem existed? |
it seems that it exists for a long time, just tested it on an old RaspiOS Bullseye and the issue is present, maybe a little bit less worse than on Bookworm. But does it means that it should not be fixed? Any idea why it works different than on other Linux distro? My first thought is that it may be related to the USB host driver issues, but the issue present even with RPI4 onboard HDMI sound. So, it looks like issue in sound subsystem in general. |
I can't think of any pi specific sound subsystem code that is common to hdmi and usb audio (unless you could suggest where you think the problem lies?). In which case, it's a problem with upstream code which we are not going to know a lot about. Is your test app using alsa directly, or going thought pipewire (possibly using the pipewire-pulse shim)? |
My test app uses OpenAL (libopenal-dev), which uses backend "pulse".
I'm a newbie in Linux audio, so I don't know exactly how it works under the hood. I'm trying to port code originally written for Windows DirectSound (DirectX). In DirectSound, it is possible to assign events that are automatically triggered by the driver during sound buffer playback. This allows user code to simply wait for the event, which is convenient in terms of minimizing CPU load. However, in OpenAL, I don't see such a mechanism - I have to poll the buffer in a loop, which increases CPU load. Perhaps you could suggest a more efficient way to set an event for thread synchronization as the sound buffer plays (I'm interested in a 1/50 second interval). |
So audio will be going though: so there many places for it to go wrong. Might be worth trying to disable pipewire (and its pulseaudio shim) which will hopefully mean openal uses alsa directly. The result of that will narrow down the problem somewhat. |
Just tried to configure OpenAL to use ALSA directly. Now OpenAL uses backend "alsa", but the issue still present:
As you can see, it shows the same 1114 sample step and is unable to notify the app about the buffer overrun. You can see that it notifies 2 buffers at once in the 121.0 - 121.6 ms time interval, and before that, there is no sign of a buffer overrun. Other Linux distro has very stable 512 sample step in this case and it works without buffer overrun. Just noticed:
Where did this |
just tried to set
But it don't works. It uses alsa driver as specified in Here is what OpenAL reports in the log when I set
It's not clear why 557 instead of configured 512??? But actual update size is still 1114, only first update size is 557, all other is 1114:
For comparison, on Arch Linux, changing Any idea where it is hard-coded to 1114 on Raspberry Pi OS? Is it firmware code? |
No. The firmware is not involved in anything like this. |
Of note: Pipewire also hijacks alsa clients to make sure everything's under the same umbrella. There's a difference between ALSA the kernel API (which to my knowledge is also used by Pipewire itself to actually talk to audio devices) and ALSA the userspace library. To check whether something's going through Pipewire, try looking at The package responsible for this is |
Describe the bug
I am debugging my code, which is designed to synchronize precisely with the sound card to maintain a continuous audio stream without interruptions and with minimal latency. However, I have encountered an issue where my code fails to maintain stream synchronization with the sound card on Raspberry Pi OS, while it works fine on other systems (Windows, Linux Arch).
A detailed investigation revealed that on Raspberry Pi OS, the AL_SAMPLE_OFFSET position updates occur in excessively large steps with a long interval, and the update step is quite unusual (not a power of two).
For example, at a sample rate of 48 kHz, the step is typically 1114 samples with an update interval of 30 ms, which is too much to maintain synchronization with a buffer length of 1/50 or 1/60 seconds (to match the display refresh rate). In contrast, on Linux Arch with the same USB sound card, I see a stable update step of 512 samples and an update interval of 10 ms, which is sufficient for most use cases.
Could you please fix it to get 10 ms update and 512 sample steps at 48 kHz sample rate as it works on other OS?
Steps to reproduce the behaviour
sudo apt install libopenal-dev
test-al.cpp
with the following test code:g++ -o test-al test-al.cpp -lopenal
./test-al 500
Expected result:
max delta samples: 512
and max dt about 10 ms +- jitterActual result:
For comparison, here is results from Linux Arch with the same USB sound card:
As observed, Raspberry Pi OS can update the sample position by as much as 2228 samples in a single step (and even more!), while the buffer size is just 960 samples. Consequently, it occasionally updates the sample position only once per three buffers, resulting in significant lag and sound streaming breaks.
Device (s)
Raspberry Pi 4 Mod. B
System
Logs
Raspberry Pi OS:
Linux Arch on the same USB sound card:
Additional context
Tested with USB sound card CX31993. But with other sound cards it shows the same issue.
The text was updated successfully, but these errors were encountered: