From 92a41ba21f858a56a41f7592ead80c57dee454cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20R=C3=BCmelin?= Date: Thu, 23 Mar 2023 19:30:21 +0100 Subject: [PATCH] pipewire-pulse: generate silence on underflow correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Filling a buffer with zeros to produce silence is wrong for unsigned sample formats and compressed sample formats. This is silence with an offset. A silent stream with unsigned or compressed samples mixed with another stream produces a clipped stream. To hear the problem start QEMU with qemu-system-x86_64 -accel kvm -smp 4 -m 4096 \ -audiodev pa,id=audio0,out.mixing-engine=off \ -machine pc,pcspk-audiodev=audio0 \ -device ich9-intel-hda -device hda-duplex,audiodev=audio0 \ -boot d -cdrom Fedora-Workstation-Live-x86_64-37-1.7.iso on a host configured to use PipeWire and start audio playback on the guest HDA device. PA_SAMPLE_U8 is the only unsigned PulseAudio sample format. There is no need to care about unsigned multi-byte formats. Signed-off-by: Volker RĂ¼melin --- src/modules/module-protocol-pulse/pulse-server.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index b029cf3fa..3beb0f56c 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -1411,7 +1411,20 @@ static void stream_process(void *data) if (avail < (int32_t)minreq || stream->corked) { /* underrun, produce a silence buffer */ size = SPA_MIN(d->maxsize, minreq); - memset(p, 0, size); + switch (stream->ss.format) { + case SPA_AUDIO_FORMAT_U8: + memset(p, 0x80, size); + break; + case SPA_AUDIO_FORMAT_ALAW: + memset(p, 0x80 ^ 0x55, size); + break; + case SPA_AUDIO_FORMAT_ULAW: + memset(p, 0x00 ^ 0xff, size); + break; + default: + memset(p, 0, size); + break; + } if (stream->draining && !stream->corked) { stream->draining = false;