Discussion:
[pulseaudio-discuss] PulseAudio null sink monitor gives distorted audio randomly
Mikael Nousiainen
2018-11-08 09:00:50 UTC
Permalink
I've got a very weird issue with PulseAudio when trying to route audio
from one application (Firefox 64.0b7 (64-bit)) to another one (WSJT-X v1.9.1).
I'm experiencing the same issue with different browsers (Chrome and Chromium too).
The browser is receiving audio from a radio transceiver through a WebRTC
connection and I'm feeding it to WSJT-X to decode the data in the audio signal.

I'm using two module-null-sink modules to transfer the audio between
the browser and WSJT-X. I use pavucontrol to make the browser play audio to
null sink called "radio-output" and then let WSJT-X listen to the audio
via "radio-output.monitor". The kind of setup exists for transmitted audio
where WSJT-X feeds audio to the browser through a null sink called "radio-input".

However, the issue her is that WSJT-X is mostly not able to decode the data
when it's using "radio-output.monitor" as audio input. Sometimes it works
and sometimes it does not. As a technical detail, I'm trying to decode FT8
digital mode traffic and I've confirmed that the reason is not related to
bad time sync (which FT8 requires), because I can even play the browser
audio through laptop speakers and let WSJT-X use the laptop microphone as
audio input and it decodes the data just fine -- the audio sounds clean
and strong with no audible artifacts.

By looking at the waterfall display of WSJT-X when using "radio-output.monitor"
as audio input, I can see some artifacts appearing randomly in the frequency
domain data -- I would call this distortion, but it's hard to know as I cannot
hear it. I can set up a loopback module to feed "radio-output.monitor" to the
speakers and the audio sounds fine. Lowering the incoming volume
radically, e.g. to 10-20% of the full volume, does not help. And occasionally,
couple of times a minute -- and sometimes for a longer period of time --
these artifacts disappear and WSJT-X is able to decode all data flawlessly.

Please see this screenshot for details: https://ibb.co/eiEo0A

I'm using a powerful PC (a quad-core Xeon with 48GB RAM) running Fedora 28
with latest updates applied and CPU usage is quite low (20-30%) during
decoding. PulseAudio version is 12.2-rebootstrapped packaged by Fedora 28.

Pulseaudio daemon.conf has default settings, except for the sample rate:

default-sample-format = s16le
default-sample-rate = 48000

Also, I have the following null sink / loopback setup in default.pa file:

# Loopback devices
load-module module-null-sink sink_name=radio-output sink_properties=device.description="radio-output"
load-module module-null-sink sink_name=radio-input sink_properties=device.description="radio-input"
load-module module-loopback source=radio-output.monitor latency_msec=100 adjust_time=0 rate=48000
load-module module-loopback source=radio-input.monitor latency_msec=100 adjust_time=0 rate=48000

The latter loopback modules are there so that I can hear what is being fed into
the null sinks, but I've confirmed the same behavior even *WITHOUT* the
loopback modules.

I've also set up a fixed latency range for the hardware sound cards, but
I believe this should not have any effect on the null sinks or loopback modules:

load-module module-udev-detect tsched=yes tsched_buffer_size=65536 fixed_latency_range=yes

I am not sure if these audio artifacts are caused by PulseAudio, WSJT-X
or some specific configuration issue in my system. Any ideas?
Alexander E. Patrakov
2018-11-08 09:56:23 UTC
Permalink
Post by Mikael Nousiainen
I've got a very weird issue with PulseAudio when trying to route audio
from one application (Firefox 64.0b7 (64-bit)) to another one (WSJT-X v1.9.1).
I'm experiencing the same issue with different browsers (Chrome and Chromium too).
The browser is receiving audio from a radio transceiver through a WebRTC
connection and I'm feeding it to WSJT-X to decode the data in the audio signal.
I'm using two module-null-sink modules to transfer the audio between
the browser and WSJT-X. I use pavucontrol to make the browser play audio to
null sink called "radio-output" and then let WSJT-X listen to the audio
via "radio-output.monitor". The kind of setup exists for transmitted audio
where WSJT-X feeds audio to the browser through a null sink called "radio-input".
However, the issue her is that WSJT-X is mostly not able to decode the data
when it's using "radio-output.monitor" as audio input. Sometimes it works
and sometimes it does not. As a technical detail, I'm trying to decode FT8
digital mode traffic and I've confirmed that the reason is not related to
bad time sync (which FT8 requires), because I can even play the browser
audio through laptop speakers and let WSJT-X use the laptop microphone as
audio input and it decodes the data just fine -- the audio sounds clean
and strong with no audible artifacts.
We need to figure out whether this is due to a monitor or due to a
null sink. Could you please let the browser play to your speakers, and
WSJT-X record from the monitor of the sound card that the browser is
playing to? Does it work?

Is the webrtc feed public? I.e., can I run WSJT-X locally in order to
reproduce the issue?
--
Alexander E. Patrakov
Tanu Kaskinen
2018-11-08 14:44:52 UTC
Permalink
Post by Alexander E. Patrakov
Post by Mikael Nousiainen
I've got a very weird issue with PulseAudio when trying to route audio
from one application (Firefox 64.0b7 (64-bit)) to another one (WSJT-X v1.9.1).
I'm experiencing the same issue with different browsers (Chrome and Chromium too).
The browser is receiving audio from a radio transceiver through a WebRTC
connection and I'm feeding it to WSJT-X to decode the data in the audio signal.
I'm using two module-null-sink modules to transfer the audio between
the browser and WSJT-X. I use pavucontrol to make the browser play audio to
null sink called "radio-output" and then let WSJT-X listen to the audio
via "radio-output.monitor". The kind of setup exists for transmitted audio
where WSJT-X feeds audio to the browser through a null sink called "radio-input".
However, the issue her is that WSJT-X is mostly not able to decode the data
when it's using "radio-output.monitor" as audio input. Sometimes it works
and sometimes it does not. As a technical detail, I'm trying to decode FT8
digital mode traffic and I've confirmed that the reason is not related to
bad time sync (which FT8 requires), because I can even play the browser
audio through laptop speakers and let WSJT-X use the laptop microphone as
audio input and it decodes the data just fine -- the audio sounds clean
and strong with no audible artifacts.
We need to figure out whether this is due to a monitor or due to a
null sink. Could you please let the browser play to your speakers, and
WSJT-X record from the monitor of the sound card that the browser is
playing to? Does it work?
Is the webrtc feed public? I.e., can I run WSJT-X locally in order to
reproduce the issue?
The problem is most likely due to this bug regarding monitor sources:
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/304

Whenever the monitored sink has a rewind, a chunk of audio is
apparently duplicated in the monitor source. It would be great if
someone could figure out what goes wrong in the monitor rewinding code.
--
Tanu

https://www.patreon.com/tanuk
https://liberapay.com/tanuk
Alexander E. Patrakov
2018-11-08 16:31:52 UTC
Permalink
[resending to the list, really this time]
Post by Tanu Kaskinen
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/304
Whenever the monitored sink has a rewind, a chunk of audio is
apparently duplicated in the monitor source. It would be great if
someone could figure out what goes wrong in the monitor rewinding code.
* The latency is stored in \a *r_usec. In case the stream is a
* monitoring stream the result can be negative, i.e. the captured
* samples are not yet played. In this case \a *negative is set to 1.
I.e., the design mistake is that monitor sources allow one to capture
samples that have not yet been played. This is always wrong, as those
samples can be overwritten by a rewind, and there is no "uncapture" to
compensate. So the fix would be to make sure that monitor sources
capture not what was just written to them, but what was actually played
and can no longer be overwritten. I.e., change the latency from negative
to small positive.
--
Alexander e. Patrakov
Mikael Nousiainen
2018-11-08 14:41:55 UTC
Permalink
Send pulseaudio-discuss mailing list submissions to
To subscribe or unsubscribe via the World Wide Web, visit
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
or, via email, send a message with subject or body 'help' to
You can reach the person managing the list at
When replying, please edit your Subject line so it is more specific
than "Re: Contents of pulseaudio-discuss digest..."
1. PulseAudio null sink monitor gives distorted audio randomly
(Mikael Nousiainen)
2. Re: PulseAudio null sink monitor gives distorted audio
randomly (Alexander E. Patrakov)
----------------------------------------------------------------------
Message: 1
Date: Thu, 08 Nov 2018 11:00:50 +0200
Subject: [pulseaudio-discuss] PulseAudio null sink monitor gives
distorted audio randomly
Content-Type: text/plain; charset="utf-8"
I've got a very weird issue with PulseAudio when trying to route audio
from one application (Firefox 64.0b7 (64-bit)) to another one (WSJT-X
v1.9.1).
I'm experiencing the same issue with different browsers (Chrome and
Chromium too).
The browser is receiving audio from a radio transceiver through a WebRTC
connection and I'm feeding it to WSJT-X to decode the data in the audio
signal.
I'm using two module-null-sink modules to transfer the audio between
the browser and WSJT-X. I use pavucontrol to make the browser play audio
to
null sink called "radio-output" and then let WSJT-X listen to the audio
via "radio-output.monitor". The kind of setup exists for transmitted
audio
where WSJT-X feeds audio to the browser through a null sink called
"radio-input".
However, the issue her is that WSJT-X is mostly not able to decode the data
when it's using "radio-output.monitor" as audio input. Sometimes it works
and sometimes it does not. As a technical detail, I'm trying to decode FT8
digital mode traffic and I've confirmed that the reason is not related to
bad time sync (which FT8 requires), because I can even play the browser
audio through laptop speakers and let WSJT-X use the laptop microphone as
audio input and it decodes the data just fine -- the audio sounds clean
and strong with no audible artifacts.
By looking at the waterfall display of WSJT-X when using "radio-output.monitor"
as audio input, I can see some artifacts appearing randomly in the frequency
domain data -- I would call this distortion, but it's hard to know as I cannot
hear it. I can set up a loopback module to feed "radio-output.monitor" to the
speakers and the audio sounds fine. Lowering the incoming volume
radically, e.g. to 10-20% of the full volume, does not help. And occasionally,
couple of times a minute -- and sometimes for a longer period of time --
these artifacts disappear and WSJT-X is able to decode all data flawlessly.
Please see this screenshot for details: https://ibb.co/eiEo0A
I'm using a powerful PC (a quad-core Xeon with 48GB RAM) running Fedora 28
with latest updates applied and CPU usage is quite low (20-30%) during
decoding. PulseAudio version is 12.2-rebootstrapped packaged by Fedora 28.
default-sample-format = s16le
default-sample-rate = 48000
# Loopback devices
load-module module-null-sink sink_name=radio-output
sink_properties=device.description="radio-output"
load-module module-null-sink sink_name=radio-input
sink_properties=device.description="radio-input"
load-module module-loopback source=radio-output.monitor latency_msec=100
adjust_time=0 rate=48000
load-module module-loopback source=radio-input.monitor latency_msec=100
adjust_time=0 rate=48000
The latter loopback modules are there so that I can hear what is being fed into
the null sinks, but I've confirmed the same behavior even *WITHOUT* the
loopback modules.
I've also set up a fixed latency range for the hardware sound cards, but
load-module module-udev-detect tsched=yes tsched_buffer_size=65536
fixed_latency_range=yes
I am not sure if these audio artifacts are caused by PulseAudio, WSJT-X
or some specific configuration issue in my system. Any ideas?
------------------------------
Message: 2
Date: Thu, 8 Nov 2018 14:56:23 +0500
To: General PulseAudio Discussion
Subject: Re: [pulseaudio-discuss] PulseAudio null sink monitor gives
distorted audio randomly
Content-Type: text/plain; charset="UTF-8"
Post by Mikael Nousiainen
I've got a very weird issue with PulseAudio when trying to route audio
from one application (Firefox 64.0b7 (64-bit)) to another one (WSJT-X v1.9.1).
I'm experiencing the same issue with different browsers (Chrome and Chromium too).
The browser is receiving audio from a radio transceiver through a WebRTC
connection and I'm feeding it to WSJT-X to decode the data in the audio signal.
I'm using two module-null-sink modules to transfer the audio between
the browser and WSJT-X. I use pavucontrol to make the browser play audio to
null sink called "radio-output" and then let WSJT-X listen to the audio
via "radio-output.monitor". The kind of setup exists for transmitted audio
where WSJT-X feeds audio to the browser through a null sink called "radio-input".
However, the issue her is that WSJT-X is mostly not able to decode the data
when it's using "radio-output.monitor" as audio input. Sometimes it works
and sometimes it does not. As a technical detail, I'm trying to decode FT8
digital mode traffic and I've confirmed that the reason is not related to
bad time sync (which FT8 requires), because I can even play the browser
audio through laptop speakers and let WSJT-X use the laptop microphone as
audio input and it decodes the data just fine -- the audio sounds clean
and strong with no audible artifacts.
We need to figure out whether this is due to a monitor or due to a
null sink. Could you please let the browser play to your speakers, and
WSJT-X record from the monitor of the sound card that the browser is
playing to? Does it work?
Is the webrtc feed public? I.e., can I run WSJT-X locally in order to
reproduce the issue?
--
Alexander E. Patrakov
Ok, so I recorded audio with Audacity from both the null sink monitor and speaker monitor and the results are clear: null sink monitor audio contains distorted (buffer underrun-like?) artifacts, while speaker monitor audio does not.

I also recorded the samples using two sample rates (44.1 kHz and 48 kHz) just to see if it made a difference -- and the artifacts were certainly worse with 44.1 kHz capture, when PulseAudio has to do sample rate conversion (all devices are set to use 48 kHz). However, the artifacts are there also in the 48 kHz recording as you can hear.

One thing was interesting, though: I could not first reproduce the issue, but after restarting PulseAudio with "pulseaudio -k", the artifacts appeared again! I restarted WSJT-X after restarting PulseAudio, but did _not_ restart Firefox. After recording the samples, I restarted Firefox and WSJT-X both and I seem to be getting clean audio again. Not sure if NOT restarting Firefox while PulseAudio gets killed/restarted has something to do with this. I'll have to repeat these tests a couple of times at least to see if there is a pattern.

Here's a link to a ZIP file containing the recordings as WAV files: https://we.tl/t-QE6Cixchay
(one of them contains some quiet audio from microphone in the beginning, forgot to cut it out)

-Mikael
Mikael Nousiainen
2018-11-09 21:52:06 UTC
Permalink
Message: 4
Date: Thu, 8 Nov 2018 21:31:52 +0500
To: General PulseAudio Discussion
Subject: Re: [pulseaudio-discuss] PulseAudio null sink monitor gives
distorted audio randomly
Content-Type: text/plain; charset=utf-8; format=flowed
[resending to the list, really this time]
Post by Tanu Kaskinen
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/304
Whenever the monitored sink has a rewind, a chunk of audio is
apparently duplicated in the monitor source. It would be great if
someone could figure out what goes wrong in the monitor rewinding code.
* The latency is stored in \a *r_usec. In case the stream is a
* monitoring stream the result can be negative, i.e. the captured
* samples are not yet played. In this case \a *negative is set to 1.
I.e., the design mistake is that monitor sources allow one to capture
samples that have not yet been played. This is always wrong, as those
samples can be overwritten by a rewind, and there is no "uncapture" to
compensate. So the fix would be to make sure that monitor sources
capture not what was just written to them, but what was actually played
and can no longer be overwritten. I.e., change the latency from negative
to small positive.
--
Alexander e. Patrakov
Thanks for digging into this!

Some questions:

1. Is there any workaround for this without a proper bugfix and a new release?
2. Is this a question of buffer underrun / jitter bcause of CPU usage? What is the cause for "monitor rewinds", why is it needed?
3. Why are the artifacts gone sometimes and sometimes the appear after PulseAudio restart?

-Mikael
Alexander E. Patrakov
2018-11-10 05:54:03 UTC
Permalink
Post by Mikael Nousiainen
Message: 4
Date: Thu, 8 Nov 2018 21:31:52 +0500
To: General PulseAudio Discussion
Subject: Re: [pulseaudio-discuss] PulseAudio null sink monitor gives
distorted audio randomly
Content-Type: text/plain; charset=utf-8; format=flowed
[resending to the list, really this time]
Post by Tanu Kaskinen
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/304
Whenever the monitored sink has a rewind, a chunk of audio is
apparently duplicated in the monitor source. It would be great if
someone could figure out what goes wrong in the monitor rewinding code.
* The latency is stored in \a *r_usec. In case the stream is a
* monitoring stream the result can be negative, i.e. the captured
* samples are not yet played. In this case \a *negative is set to 1.
I.e., the design mistake is that monitor sources allow one to capture
samples that have not yet been played. This is always wrong, as those
samples can be overwritten by a rewind, and there is no "uncapture" to
compensate. So the fix would be to make sure that monitor sources
capture not what was just written to them, but what was actually played
and can no longer be overwritten. I.e., change the latency from negative
to small positive.
--
Alexander E. Patrakov
Thanks for digging into this!
1. Is there any workaround for this without a proper bugfix and a new release?
2. Is this a question of buffer underrun / jitter bcause of CPU usage? What is the cause for "monitor rewinds", why is it needed?
3. Why are the artifacts gone sometimes and sometimes the appear after PulseAudio restart?
1. No.
2. This is unlikely to be related to CPU usage. Rewinds typically
happen when new streams appear, or when something changes the volume.
To figure out for sure, please run PulseAudio with very very verbose
logging, see below. It will then announce the reason for each rewind.
3. No idea, see the log.

Actually, it is still only a speculation (or, if you prefer, educated
guess) that your problem is related to rewinds. If PulseAudio does not
log anything about a rewind, then that's not it.

Here is how to run PulseAudio with very very verbose logging;

1. Edit ~/.config/pulse/client.conf, so that it contains exactly one line:
autospawn=no

2. systemctl --user stop pulseaudio.socket pulseaudio.service

3. pulseaudio -vvv 2>&1 | tee -i pulseaudio.log

4. Reproduce the problem

5. Ctrl+C, revert the change to ~/.config/pulse/client.conf, systemctl
--user start pulseaudio.socket pulseaudio.service

6. Send the log here.
--
Alexander E. Patrakov
Mikael Nousiainen
2018-11-11 15:47:33 UTC
Permalink
Message: 2
Date: Sat, 10 Nov 2018 10:54:03 +0500
To: General PulseAudio Discussion
Subject: Re: [pulseaudio-discuss] PulseAudio null sink monitor gives
distorted audio randomly
Content-Type: text/plain; charset="UTF-8"
Post by Mikael Nousiainen
Message: 4
Date: Thu, 8 Nov 2018 21:31:52 +0500
To: General PulseAudio Discussion
Subject: Re: [pulseaudio-discuss] PulseAudio null sink monitor gives
distorted audio randomly
Content-Type: text/plain; charset=utf-8; format=flowed
[resending to the list, really this time]
Post by Tanu Kaskinen
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/304
Whenever the monitored sink has a rewind, a chunk of audio is
apparently duplicated in the monitor source. It would be great if
someone could figure out what goes wrong in the monitor rewinding code.
* The latency is stored in \a *r_usec. In case the stream is a
* monitoring stream the result can be negative, i.e. the captured
* samples are not yet played. In this case \a *negative is set to 1.
I.e., the design mistake is that monitor sources allow one to capture
samples that have not yet been played. This is always wrong, as those
samples can be overwritten by a rewind, and there is no "uncapture" to
compensate. So the fix would be to make sure that monitor sources
capture not what was just written to them, but what was actually played
and can no longer be overwritten. I.e., change the latency from negative
to small positive.
--
Alexander E. Patrakov
Thanks for digging into this!
1. Is there any workaround for this without a proper bugfix and a new release?
2. Is this a question of buffer underrun / jitter bcause of CPU usage? What is the cause for "monitor rewinds", why is it needed?
3. Why are the artifacts gone sometimes and sometimes the appear after PulseAudio restart?
1. No.
2. This is unlikely to be related to CPU usage. Rewinds typically
happen when new streams appear, or when something changes the volume.
To figure out for sure, please run PulseAudio with very very verbose
logging, see below. It will then announce the reason for each rewind.
3. No idea, see the log.
Actually, it is still only a speculation (or, if you prefer, educated
guess) that your problem is related to rewinds. If PulseAudio does not
log anything about a rewind, then that's not it.
Here is how to run PulseAudio with very very verbose logging;
autospawn=no
2. systemctl --user stop pulseaudio.socket pulseaudio.service
3. pulseaudio -vvv 2>&1 | tee -i pulseaudio.log
4. Reproduce the problem
5. Ctrl+C, revert the change to ~/.config/pulse/client.conf, systemctl
--user start pulseaudio.socket pulseaudio.service
6. Send the log here.
--
Alexander E. Patrakov
Four takes on verbose logs here: https://we.tl/t-a94jpZtBnN

During the first run (the files are accordingly named), I did not get artifacts and WSJT-X was decoding the audio signal fine. For runs 2-4 I got distorted audio only and was not able to get clean audio even after starting PulseAudio "normally" through systemctl and restarting all browsers and other PulseAudio clients.

I noticed "Scheduling delay" / "Underrun" messages even during the first "successful" run and they did not seem to affect audio. The same messages continued even when listening through speakers briefly and I couldn't hear any popping / distortion.

-Mikael
Mikael Nousiainen
2018-11-22 09:44:27 UTC
Permalink
Post by Mikael Nousiainen
Message: 2
Date: Sat, 10 Nov 2018 10:54:03 +0500
To: General PulseAudio Discussion
Subject: Re: [pulseaudio-discuss] PulseAudio null sink monitor gives
distorted audio randomly
Content-Type: text/plain; charset="UTF-8"
Post by Mikael Nousiainen
Message: 4
Date: Thu, 8 Nov 2018 21:31:52 +0500
To: General PulseAudio Discussion
Subject: Re: [pulseaudio-discuss] PulseAudio null sink monitor gives
distorted audio randomly
Content-Type: text/plain; charset=utf-8; format=flowed
[resending to the list, really this time]
Post by Tanu Kaskinen
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/304
Whenever the monitored sink has a rewind, a chunk of audio is
apparently duplicated in the monitor source. It would be great if
someone could figure out what goes wrong in the monitor rewinding code.
* The latency is stored in \a *r_usec. In case the stream is a
* monitoring stream the result can be negative, i.e. the captured
* samples are not yet played. In this case \a *negative is set to 1.
I.e., the design mistake is that monitor sources allow one to capture
samples that have not yet been played. This is always wrong, as those
samples can be overwritten by a rewind, and there is no "uncapture" to
compensate. So the fix would be to make sure that monitor sources
capture not what was just written to them, but what was actually played
and can no longer be overwritten. I.e., change the latency from negative
to small positive.
--
Alexander E. Patrakov
Thanks for digging into this!
1. Is there any workaround for this without a proper bugfix and a new release?
2. Is this a question of buffer underrun / jitter bcause of CPU usage? What is the cause for "monitor rewinds", why is it needed?
3. Why are the artifacts gone sometimes and sometimes the appear after PulseAudio restart?
1. No.
2. This is unlikely to be related to CPU usage. Rewinds typically
happen when new streams appear, or when something changes the volume.
To figure out for sure, please run PulseAudio with very very verbose
logging, see below. It will then announce the reason for each rewind.
3. No idea, see the log.
Actually, it is still only a speculation (or, if you prefer, educated
guess) that your problem is related to rewinds. If PulseAudio does not
log anything about a rewind, then that's not it.
Here is how to run PulseAudio with very very verbose logging;
autospawn=no
2. systemctl --user stop pulseaudio.socket pulseaudio.service
3. pulseaudio -vvv 2>&1 | tee -i pulseaudio.log
4. Reproduce the problem
5. Ctrl+C, revert the change to ~/.config/pulse/client.conf, systemctl
--user start pulseaudio.socket pulseaudio.service
6. Send the log here.
--
Alexander E. Patrakov
Four takes on verbose logs here: https://we.tl/t-a94jpZtBnN
During the first run (the files are accordingly named), I did not get
artifacts and WSJT-X was decoding the audio signal fine. For runs 2-4 I
got distorted audio only and was not able to get clean audio even after
starting PulseAudio "normally" through systemctl and restarting all
browsers and other PulseAudio clients.
I noticed "Scheduling delay" / "Underrun" messages even during the first
"successful" run and they did not seem to affect audio. The same
messages continued even when listening through speakers briefly and I
couldn't hear any popping / distortion.
-Mikael
Do you have insight into this issue? This is very much a blocker for many use cases...

-Mikael

Loading...