[PR #493] [MERGED] Alsa backend better buffering #949

Closed
opened 2026-02-27 20:00:34 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/librespot-org/librespot/pull/493
Author: @sniperrifle2004
Created: 6/14/2020
Status: Merged
Merged: 7/24/2020
Merged by: @sashahilton00

Base: devHead: alsa-backend-better-buffering


📝 Commits (6)

  • aaef07e Introduce an appropriate period for the desired buffer
  • 64081a1 Introduce a buffer for a full period
  • cbe3c98 Clear buffer when the sink is stopped
  • a68dfa0 On stop write any chunk(s) left in the period buffer
  • 82e54df Rewrite buffer around the actual period size
  • 1e5d98b Actually store the period_size

📊 Changes

1 file changed (+54 additions, -17 deletions)

View changed files

📝 playback/src/audio_backend/alsa.rs (+54 -17)

📄 Description

Based on experience with the alsa pulse plugin and raspotify (Particularly I was looking into the problem described in dtcooper/raspotify#210) and a comparison with aplay (Which can be regarded as a reference implementation of alsa playback and did fine job using the pipe backend) I started looking into the alsa backend, because it was clear that something was wrong there.

By comparing hw_params used in librespot with those in aplay and also a brief look through aplay.c, I was able to come up with the following two improvements to buffering in the alsa backend:

  1. Introduce a decent period size relative to the desired buffer. This reduces the load on the CPU because it increases the wakeup interval.
  2. Only write to the pcm when a full period of data is available. This again increased performance quite considerably, though the effect probably relies a lot more on the specific pcm. I also changed the struct to a regular one since I had to introduce values for the buffer. I wasn't a big fan of the tuple struct anyway since there is no intuitive association of a datum for AlsaSink with index 0 and 1 and adding 2 and 3 would not make that any better.

NOTE: I did not look for a suitable buffer type before implementing the buffer/buffered_data combination. If anyone is aware of a suitable solution I will gladly make the change if that is preferable. Now replaced with a vector to match the actual period size. Could still be replaced with a buffer type


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/librespot-org/librespot/pull/493 **Author:** [@sniperrifle2004](https://github.com/sniperrifle2004) **Created:** 6/14/2020 **Status:** ✅ Merged **Merged:** 7/24/2020 **Merged by:** [@sashahilton00](https://github.com/sashahilton00) **Base:** `dev` ← **Head:** `alsa-backend-better-buffering` --- ### 📝 Commits (6) - [`aaef07e`](https://github.com/librespot-org/librespot/commit/aaef07e819192b0c204150e8d65eff741fabe1e3) Introduce an appropriate period for the desired buffer - [`64081a1`](https://github.com/librespot-org/librespot/commit/64081a12bb22d1f6a211a7ddde4176dea3af0579) Introduce a buffer for a full period - [`cbe3c98`](https://github.com/librespot-org/librespot/commit/cbe3c98fa122c0c3214f83e7c8e5044823f31e02) Clear buffer when the sink is stopped - [`a68dfa0`](https://github.com/librespot-org/librespot/commit/a68dfa0287790fa5583f41fcf301e25024f4e4f1) On stop write any chunk(s) left in the period buffer - [`82e54df`](https://github.com/librespot-org/librespot/commit/82e54dfaba32cfc5d024781b1eb72716abc2549b) Rewrite buffer around the actual period size - [`1e5d98b`](https://github.com/librespot-org/librespot/commit/1e5d98b8fdd23e3e739b5fdb2ff59d45e12a0409) Actually store the period_size ### 📊 Changes **1 file changed** (+54 additions, -17 deletions) <details> <summary>View changed files</summary> 📝 `playback/src/audio_backend/alsa.rs` (+54 -17) </details> ### 📄 Description Based on experience with the alsa pulse plugin and raspotify (Particularly I was looking into the problem described in dtcooper/raspotify#210) and a comparison with aplay (Which can be regarded as a reference implementation of alsa playback and did fine job using the pipe backend) I started looking into the alsa backend, because it was clear that something was wrong there. By comparing hw_params used in librespot with those in aplay and also a brief look through aplay.c, I was able to come up with the following two improvements to buffering in the alsa backend: 1. Introduce a decent period size relative to the desired buffer. This reduces the load on the CPU because it increases the wakeup interval. 2. Only write to the pcm when a full period of data is available. This again increased performance quite considerably, though the effect probably relies a lot more on the specific pcm. I also changed the struct to a regular one since I had to introduce values for the buffer. I wasn't a big fan of the tuple struct anyway since there is no intuitive association of a datum for AlsaSink with index 0 and 1 and adding 2 and 3 would not make that any better. ~NOTE: I did not look for a suitable buffer type before implementing the buffer/buffered_data combination. If anyone is aware of a suitable solution I will gladly make the change if that is preferable.~ Now replaced with a vector to match the actual period size. Could still be replaced with a buffer type --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-02-27 20:00:34 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/librespot#949
No description provided.