Skip to content

Commit 741badc

Browse files
committed
aplay: reduce ALSA buffering
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.
1 parent 1002906 commit 741badc

File tree

4 files changed

+16
-11
lines changed

4 files changed

+16
-11
lines changed

.github/spellcheck-wordlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ ATRAC
6868
BlueALSA
6969
BlueZ
7070
Fraunhofer
71+
iPhone
7172
IWYU
7273
LDAC
7374
LHDC

doc/bluealsa-aplay.1.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ OPTIONS
8989

9090
--pcm-buffer-time=INT
9191
Set the playback PCM buffer duration time to *INT* microseconds.
92-
The default is 500000. It is recommended to choose a buffer time that is
92+
The default is 200000. It is recommended to choose a buffer time that is
9393
an exact multiple of the period time to avoid potential issues with some
9494
ALSA plugins (see --pcm-period-time option below).
9595
ALSA may choose the nearest available alternative if the requested value is
@@ -101,7 +101,7 @@ OPTIONS
101101

102102
--pcm-period-time=INT
103103
Set the playback PCM period duration time to *INT* microseconds.
104-
The default is 100000.
104+
The default is 50000.
105105
ALSA may choose the nearest available alternative if the requested value is
106106
not supported.
107107

@@ -232,12 +232,12 @@ Instead it will choose its own values, which can lead to rounding errors in the
232232
period size calculation when used with the ALSA `rate` plugin. To avoid this,
233233
it is recommended to explicitly define the hardware period size and buffer size
234234
for dmix in your ALSA configuration. For example, suppose we want a period time
235-
of 100000 µs and a buffer holding 5 periods with an Intel 'PCH' card:
235+
of 50000 µs and a buffer holding 4 periods with an Intel 'PCH' card:
236236

237237
::
238238

239-
defaults.dmix.PCH.period_time 100000
240-
defaults.dmix.PCH.periods 5
239+
defaults.dmix.PCH.period_time 50000
240+
defaults.dmix.PCH.periods 4
241241

242242
Alternatively we can define a PCM with the required setting:
243243

@@ -250,8 +250,8 @@ Alternatively we can define a PCM with the required setting:
250250
ipc_key 12345
251251
slave {
252252
pcm "hw:0,0"
253-
period_time 100000
254-
periods 5
253+
period_time 50000
254+
periods 4
255255
}
256256
}
257257
}

utils/aplay/alsa-pcm.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,9 @@ static int alsa_pcm_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t buffer_size,
8989
goto fail;
9090
}
9191

92-
/* start the transfer when the buffer is full (or almost full) */
93-
snd_pcm_uframes_t threshold = (buffer_size / period_size) * period_size;
92+
/* start the transfer when the buffer is half full - this allows spare
93+
* capacity to accommodate bursts and short breaks in the bluetooth stream. */
94+
snd_pcm_uframes_t threshold = buffer_size / 2;
9495
if ((err = snd_pcm_sw_params_set_start_threshold(pcm, params, threshold)) != 0) {
9596
snprintf(buf, sizeof(buf), "Set start threshold: %s: %lu", snd_strerror(err), threshold);
9697
goto fail;

utils/aplay/aplay.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,11 @@ static bool ba_profile_a2dp = true;
8686
static bool ba_addr_any = false;
8787
static bdaddr_t *ba_addrs = NULL;
8888
static size_t ba_addrs_count = 0;
89-
static unsigned int pcm_buffer_time = 500000;
90-
static unsigned int pcm_period_time = 100000;
89+
/* Many devices cannot synchronize A/V with very high audio latency. To keep
90+
* the overall latency below 400ms we choose ALSA parameters such that the
91+
* ALSA latency is below 200ms. */
92+
static unsigned int pcm_buffer_time = 200000;
93+
static unsigned int pcm_period_time = 50000;
9194

9295
/* local PCM muted state for software mute */
9396
static bool pcm_muted = false;

0 commit comments

Comments
 (0)