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

Use Ring Buffer for Aplay #459

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Use Ring Buffer for Aplay #459

wants to merge 3 commits into from

Conversation

niko132
Copy link

@niko132 niko132 commented Jun 16, 2021

As #156 points out when using aplay for speaker functionality, the delay increases while playing audio.
I noticed around 1s of delay every 1h of continuous audio.

From my analysis, this delay comes from the file descriptor filling up because ALSA blocks for too long while executing snd_pcm_writei(). But I still don't know why this happens.

However using a ring buffer to constantly flush the file descriptor and only store the most recent ms of audio data (a.k.a. dropping excessive frames) solved the problem for me.

@arkq
Copy link
Owner

arkq commented Jun 17, 2021 via email

@borine
Copy link
Collaborator

borine commented Jun 17, 2021

ALSA blocks for too long while executing snd_pcm_writei()

That is because the clock used by the ALSA sink is the playback device clock (ie the soundcard clock), whereas the clock used by the bluetooth source is the bluetooth controller clock (synchronized by the bluetooth protocol to the source device). As no two independent clocks ever "tick" at exactly the same rate (at least not for consumer products) the there will always be some drift and jitter when capturing from one device and playing back to another. ALSA can make this worse, because the rate plugin introduces rounding error, which when used with small period sizes can be very significant - this is evidenced by #451

An alternative solution, rather than dropping samples or inserting duplicates, is to resample "on the fly" using a variable output sample rate calculated to keep the delay within a narrow range. By this means the "pitch" of the resulting sound is not modified, and the "harsh" audio artifacts caused by discontinuities in the sample stream are avoided. See "loopback" applications such as alsaloop or JACK's zita-j2a for examples. Unfortunately both those examples are GPL, so we cannot just import their code. After looking at #451 I have thought about proposing a --sync= option to bluealsa-aplay to enable sync adjustment, but I have not done any work on that idea - I suspect it would not be trivial and may be beyond my capabilities. Perhaps the approach proposed in this PR could be --sync=simple whereby the stream is padded with duplicates or frames are dropped to achieve the required playback rate. The existing (default) would be --sync=none, and some future enhancement might be --sync=resample.

@arkq
Copy link
Owner

arkq commented Jun 17, 2021 via email

@Asikbct
Copy link

Asikbct commented Oct 12, 2024

Hi,
I am facing the same audio latency issue. After pausing the audio, it plays for some time (noticeable small delay).

I did check with this ring buffer patch Use Ring Buffer for Aplay #459 also, It did not make any changes in my audio latency issue.

For this issue, I have tried increasing delay as a sink #156 method, it reduces the latency. But randomly I get audio break (underrun) issue. Is it acceptable or still we can improve the audio latency along with avoid random audio breaks?

is there any other way to get a solution?

Here is our bluealsa and bluetoothd version,

bluealsa --version

4.1.1

bluealsa-aplay --version

v4.1.1

/usr/libexec/bluetooth/bluetoothd --version

5.72

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

Successfully merging this pull request may close these issues.

4 participants