Drain request is sometimes acked too soon
update by @tanuk: The root cause seems to be that the SINK_INPUT_MESSAGE_DRAIN
handler in protocol-native.c
sends the drain ack if the stream buffer is empty, without taking into consideration that the stream audio may still be waiting in the sink buffer. Below is the original issue description (slightly edited):
speaker-test -c 2 -t wav
fails to play back audio unless pavucontrol is running at the same time.
Alternatively, playing a long youtube video on Firefox or using pactl subscribe
also works instead of running pavucontrol.
Producing white noise with speaker-test -c 2
works otherwise.
Steps to reproduce
- Open a terminal and run
speaker-test -c 2 -t wav
. You should get lots of output and no audio.
Observations
I tried asking on #pulseaudio at first and we have observed some interesting results:
-
Bypassing the pulseaudio server with
pasuspender -- speaker-test --nloops=2 --test=wav --channels=2 --device=default
produces audio. -
speaker-test -c 2 -t wav
works when either pavucontrol, Firefox (with a long youtube video) orpactl subscribe
is running alongside it, and fails to play back audio otherwise. -
The problem can also be reproduced when setting the --buffer to zero (default). Increasing the buffer size to 1 or higher produces audio but sometimes results in "Write error: -32,Broken pipe".
Expectations
-
speaker-test -c 2 -t wav
works normally (audio, output, etc).
Version info
Distro: Arch Linux
Kernel: Linux thinkpad 4.19.2-arch1-1-ARCH #1 SMP PREEMPT Tue Nov 13 21:16:19 UTC 2018 x86_64 GNU/Linux
Hardware: ThinkPad T450
pulseaudio 12.2
alsa-utils 1.1.7-1
alsa-lib 1.1.7-2