[HowTo] Troubleshoot crackling in PipeWire

Difficulty: ★★☆☆☆

This tutorial will help you get rid of crackling/popping issues in PipeWire and PipeWire-Pulse.

Edit: The guide now assumes that you are using wireplumber, pipewire-media-session instructions removed.

Tips:

Click to expand
  • In the vast majority of PipeWire crackling cases, it occurs in applications designed for PulseAudio, which is why you can (and should) generally solve these issues with PipeWire’s Pulse specific options and variables.

  • Try using ALSA without PulseAudio or PipeWire and see if you still have issues on ALSA (if you do, it’s unlikely that any setting you set in PipeWire is going to solve the issue) if you are using PipeWire and want to switch to ALSA, the command to stop Pipewire is:

    systemctl --user stop pipewire.socket
    
  • The command to restart PipeWire is:

    systemctl --user restart pipewire pipewire-pulse wireplumber
    
  • PipeWire has it’s own wiki that contains a lot of useful information., the alsa buffer page may be of particular interest, and covers content not in this guide.

  • So does wireplumber, the alsa page should be of particular interest.

  • Run

    inxi -A
    

    to confirm that you are running PipeWire and not pulse, it should output something like:

    Audio:    Device-1: Intel Cannon Lake PCH cAVS driver: snd_hda_intel 
              Device-2: NVIDIA TU106 High Definition Audio driver: snd_hda_intel 
              Sound Server-1: ALSA v: k5.14.2-1-MANJARO running: yes 
              Sound Server-2: PipeWire v: 0.3.35 running: yes 
    

    With the PipeWire version being whatever version you happen to be running. If Pulseaudio is shown to be running then you are not using pipewire even if it says pipewire is running.

  • Run

    pw-top
    

    to see all open audio streams (can be useful to double check if an application is ignoring your settings)

  • QUANT = Quantum = Latency = Buffer Size.
    Quantum divided by clock rate equals latency in seconds
    (E.G. 1024/48000=0.02s or 21ms)

  • Worst case scenario for below settings is setting the system’s minimum latency to ~40ms, this is not good for professional audio, but it is perfectly solid for consumer audio. In most cases though you will only have ~20ms min latency which is a lot better.

  • The default max latency in PipeWire is 170ms (8192/48000), it is probably safe to reduce to 85ms (4096/48000) which is still an acceptable latency for consumer audio, but wait with that until after you solve your initial crackling problem first.

  • For reference, standard audio on Windows, DirectSound normally has around 50-80ms latency. (WASAPI has around 10-30ms latency, ASIO has 1-10ms)

  • You can use pw-metadata to force a system-wide clock rate or quantum setting with:

    pw-metadata -n settings 0 clock.force-rate
    pw-metadata -n settings 0 clock.force-quantum
    

    (where 0 is the id of your sound card, you can see the IDs of all PipeWire detected sound cards by running the command without arguments), this can be quite useful to test different latency and frequency settings on the fly.

  • If you are unsure whether your application is using pipewire or pipewire-pulse, you can combine the commands to set the sound buffer size like so:

    PULSE_LATENCY_MSEC=83 PIPEWIRE_LATENCY=1024/48000 <COMMAND>
    

    You could set the above as a bash alias or even make it a bash script:

    #!bin/sh
    PULSE_LATENCY_MSEC=83 PIPEWIRE_LATENCY=1024/48000 "$@"
    

    which you can use so you do not have to type or remember the values every single time, this might be helpful if you find yourself using this a lot (the script approach could be very handy for steam games, because if you place the script under /usr/bin/ you can very use it as a launch option without using the full path).

Short Guide:

A much less detailed version of this guide meant for people who more or less know what they’re doing, but are feeling too lazy to be thorough about troubleshooting the issue. The full guide has better potential solutions, but this is the best ‘quick & easy’ solution i could find.

Click to expand

Note: variable sample rates might be on by default now making this step obsolete
In pipewire.conf set:

default.clock.allowed-rates = [ 44100 48000 ]      

in pipewire-pulse.conf set:

pulse.min.req = 1024/48000              # 21ms, see: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PulseAudio

For applications that the above two settings do not solve, use environment variables:

PULSE_LATENCY_MSEC=[INT]              # Example: PULSE_LATENCY_MSEC=128
PIPEWIRE_LATENCY=[QUANT]/[RATE]       # Example: PIPEWIRE_LATENCY=2048/48000

To manually set the buffer size on a per application basis.

Note: PIPEWIRE_LATENCY does not work for pipewire-pulse, use PULSE_LATENCY_MSEC instead.
Note: PULSE_LATENCY_MSEC currently does not work as cleanly as it does in pulseaudio, when using this setting, confirm that the correct latency is being set with pw-top.

Full Guide:

  1. Create the config files for pipewire and wireplumber (If they don’t exist)

    You only need one set of config files. User config files will override system config files for your user account if the user config files exist.

    Create System Config Files:

    sudo mkdir -p /etc/pipewire/ && sudo mkdir -p /etc/wireplumber/wireplumber.conf.d/ && sudo cp /usr/share/pipewire/*.conf /etc/pipewire/ && sudo cp /usr/share/wireplumber/wireplumber.conf.d/* /etc/wireplumber/wireplumber.conf.d/ 
    

    Or create User Config Files:

    mkdir -p ~/.config/pipewire/ && mkdir -p ~/.config/wireplumber/wireplumber.conf.d/ && cp /usr/share/pipewire/*.conf ~/.config/pipewire/ && cp /usr/share/wireplumber/wireplumber.conf.d/* ~/.config/wireplumber/wireplumber.conf.d/ 
    

    Note: alsa-vm.conf which we will edit later in the guide should be placed in .../wireplumber/wireplumber.conf.d directory that we just created.

  2. Disable Suspend

    Some soundcards become problematic when suspend is enabled, disabling it could fix all problems for some users.

    • In alsa-vm.conf add session.suspend-timeout-seconds = 0
      like so:
    actions = { 
      update-props = { 
        session.suspend-timeout-seconds = 0
    
    • Restart pipewire to apply
  3. Enable sample rate switching

    Note: This setting might actually be set by default now making this step obsolete.
    Some applications need to be able to run at 44.1khz or they will have crackling (common issue for instance for games run through Wine). This is easy to fix.

    • In pipewire.conf change
      #default.clock.allowed-rates = [ 48000 ]
      
      to:
      default.clock.allowed-rates = [ 44100 48000 ]    # This is not default because: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PipeWire#setting-global-sample-rate
      
    • Restart pipewire to apply.
    • Now these applications should be allowed to run at 44.1khz instead of the default 48khz clock rate thus reducing likelihood of issues such as crackling.
  4. Try tweaking alsa headroom
    If enabling sample rate switching was not enough to solve the issue, try changing the alsa headroom setting next to see if that solves the issue.

    • In alsa-vm.conf change
      api.alsa.headroom      = 1024    # See: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/alsa.html       ```
      

    to

       api.alsa.headroom      = 0
    
    • Restart pipewire to apply.
    • If setting headroom to 0 makes it worse, try setting it to 2048
    • Other settings to try: 512, 256, 128, 64, 32
    • It is recommended to use the lowest value that works well.
  5. Try tweaking the alsa period size
    If the problem still isn’t resolved, try changing the alsa period size.

    • In alsa-vm.conf change
      api.alsa.period-size   = 1024
      
      to
      # See: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/alsa.html
      api.alsa.period-size   = 256
      
    • Restart pipewire to apply.
    • If this does not solve your issue, try setting it to different values (512, 128, 64 and maybe 2048).
    • If it still doesn’t solve your issues, try different combinations of period-size and headroom configurations until you find a good combination or give up.
  6. Set the playback buffer size
    If none of the above solved the issue, you should try setting the audio buffer size/latency.

    When an application has it’s own audio buffer size setting you will want to use that to do this, for example:

    chromium --audio-buffer-size=2048 # Sets latency to about 40ms"
    

    For applications that do not support configuring their audio buffer size, we can use system variables.

    Try setting the latency to about 20ms by running:

    PULSE_LATENCY_MSEC=83 COMMAND # Works for pipewire-pulse (most applications use this!)
    #or
    PIPEWIRE_LATENCY=1024/48000 COMMAND # Works for pipewire, pipewire-alsa & pipewire-jack.
    

    Where COMMAND is the executable for the program you’re having problems with.

    Confirm with pw-top that the latency is correct (QUANT should be between 1024 and 1050)


    If that was not enough, try setting the latency to about 40ms by running:

    PULSE_LATENCY_MSEC=126 COMMAND  # Works for pipewire-pulse (most applications use this!)
    #or
    PIPEWIRE_LATENCY=2048/48000 COMMAND # Works for pipewire, pipewire-alsa & pipewire-jack.
    

    Where COMMAND is the executable for the program you’re having problems with.

    Confirm with pw-top that the latency is correct (QUANT should be between 2048 and 2100)


    The vast majority of applications use pulseaudio, and therefore pipewire-pulse, which means that you will almost always use the PULSE_LATENCY_MSEC variable rather than PIPEWIRE_LATENCY.

    When in doubt, always use pw-top to check the quant values of running audio streams to make sure that the command worked.


    Why am I saying it’s 20ms when PULSE_LATENCY_MSEC is to set it to 86? or that it’s 40ms when set to 128?

    Click to expand

    The reason is that if I look at the application in pw-top and see the QUANT and RATE values and do the math for total latency as mentioned in the tips above, that’s the actual latency the application seems to be getting set to. Remember, this is pipewire, not pulse. It seems that this variable simply behaves differently here, but if I am actually wrong about this, I invite anyone who knows better to inform me about it in the comments below.


    If this solves your issue, then I suggest you just stick to setting the PULSE_LATENCY_MSEC variable as needed for individual applications, and just edit the .desktop file shortcuts used by your DE/Launcher, or create aliases in .bashrc for all offending applications.

  7. Set minimum playback buffer size
    If you would rather have the audio buffer size set systemwide instead of applying it on a per-application basis, in pipewire-pulse.conf change:

    #pulse.min.req = 256/48000              # 5ms
    

    to

    pulse.min.req = 1024/48000              # 21ms, see: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PulseAudio#playback-buffering-options
    

    Restart pipewire to apply.

    I would advise against setting this any higher as it can cause some issues, if there are applications that need 40ms latency, you really should just set those manually instead.

    The above only requests 21ms latency though, applications can still force a lower latency so this is a sort of soft setting for the minimum buffer size. Even then, on my system this setting helped a lot.

    To truly force it (I would advise against this as it can cause issues in some applications), in pipewire-pulse.conf:

    #pulse.min.quantum      = 256/48000     # 5ms
    

    to

    pulse.min.quantum      = 1024/48000     # 21ms, see: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PulseAudio#scheduling-options
    

    Restart pipewire to apply.


    I very strongly(!!) advise against this, but if you want to set systemwide latency for everything (not just pipewire-pulse), change in pipewire.conf:

    #default.clock.min-quantum   = 32
    

    to

    default.clock.min-quantum   = 1024  # You preferably should not use this setting! See: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PipeWire#setting-buffer-size
    

    Never(!!) set this higher than 1024, stuff will start breaking, even when set to 1024 some applications can break, but it’s not very common unless you go higher.)

    Restart pipewire to apply.

    I highly suggest though that instead of doing this, you would rather use the PIPEWIRE_LATENCY variable on a per-application basis instead of facing the risks of using this setting.

If you have any additional tips for this tutorial, please leave them below.

:slightly_smiling_face:

22 Likes

This also fixes a problem in parole player (on old hardware) where a click on the timeline would mute the audio until the next track. Thanks.

A post was split to a new topic: Crackling Audio when watching video; disappears when minimizing

Hey mate where’s this file at? I didn’t find anything, if I have to create it, where is it supposed to be?

❯ pacman -F alsa-monitor.conf
extra/pipewire-media-session 1:0.4.1-2 [installed]
    usr/share/pipewire/media-session.d/alsa-monitor.conf

:wink:

Thank youuuuuuuuu :smiley:

FYI, you should…

Copy the default configuration of alsa-monitor.conf for pipewire-media-session into either /etc/pipewire/media-session.d or ~/.config/pipewire/media-session.d .

Then edit it.

PipeWire - ArchWiki

You must have missed step one :slight_smile:

No, it’s just that the folder didn’t exist for me, I was using wireblumper, something like that, I don’t remember the name, but then I got to Archwiki and figured out how to install mediasession, anyway, great tutorial, just solved my problem

1 Like

Ah I see, so /usr/share/pipewire/media-session.d just didn’t exist? I’ve never used wireplumber before so i didn’t know it would do that, but now that i think about it it shoulda been pretty obvious that it’d do that :smiley: thanks for letting me know about this, i’ll add a note to the OP about this.

1 Like

It’s apparently (at least) part of pipewire-alsa and pipewire-pulse, so it should exist if any of those is installed.

$ pacman -Qo /usr/share/pipewire/media-session.d
/usr/share/pipewire/media-session.d/ is owned by pipewire-alsa 1:0.3.53-2
/usr/share/pipewire/media-session.d/ is owned by pipewire-pulse 1:0.3.53-2
1 Like

Even if it were to exist, if you’re using wireplumber it wouldn’t do anything. since these are pipewire-media-session files and you can only use either pipewire-media-session or wireplumber, not both at once.

But I wouldn’t be surprised if that directory is listed as owned by pipewire-alsa and pipewire-pulse because both of them depend on a session manager (e.g. pipewire-media-session or wireplumber), so if wireplumber was installed before you installed pipewire-alsa and pipewire-pulse the folder would not exist.

Still it’s interesting that it’s listed as owned by these packages.

I am reading this because in my Dell Netflix lappy running Mint Vanessa 21, the bluetooth headphones suddenly stopped working. Grrr. One post in the Mint forums said the solution is to install Pipewire, (which Manjaro uses.) I believe Mint is currently using Pulse.
Seems straight forward. … I may switch the system over tonight.

1 Like

In any case, I have it installed on my system. The clitch on the Netflix laptop turned out to be a Clang package it wanted to install. Long story. But it is fixed, so no worries.

Thanks, this is very helpful. I couldn’t find the alsa config file mentioned (running Debian 12). In the Debian repositories, it’s part of the pipewire-media-session package, but installing that package would delete WirePlumber; not a good idea.
On my system the alsa headroom and period-size values are in /usr/share/wireplumber/main.lua.d/50-alsa-config.lua . The syntax is a bit different but it’s clear how to make the changes you suggest.
I have intermittent audio stuttering problems playing over bluetooth. The audio starts out fine, but after an unpredictable time, the stuttering comes back. I thought your advice about alsa headroom resolved it, but nope. I am now trying your Step 5; we’ll see how it goes.

pipewire-media-session is deprecated.

I dont know how much of this guide as a whole is still accurate.

Hi and thank you for your extended How-To.

I have a bit issues setting suspend to 0, since the alsa-monitor.conf isn’t located where it should be:

 /usr/share/pipewire/media-session.d  tree
.
├── with-alsa
└── with-pulseaudio

my inxi -Fazy looks like that:

Audio:
  Device-1: NVIDIA TU104 HD Audio vendor: Gigabyte driver: snd_hda_intel
    v: kernel pcie: gen: 3 speed: 8 GT/s lanes: 16 bus-ID: 07:00.1
    chip-ID: 10de:10f8 class-ID: 0403
  Device-2: AMD Starship/Matisse HD Audio vendor: ASRock
    driver: snd_hda_intel v: kernel pcie: gen: 4 speed: 16 GT/s lanes: 16
    bus-ID: 09:00.4 chip-ID: 1022:1487 class-ID: 0403
  Device-3: Creative Pebble Pro driver: hid-generic,snd-usb-audio,usbhid
    type: USB rev: 1.1 speed: 12 Mb/s lanes: 1 mode: 1.1 bus-ID: 5-4.2.2:16
    chip-ID: 041e:3287 class-ID: 0102 serial: <filter>
  Device-4: Kingston HyperX Cloud Flight S
    driver: hid-generic,snd-usb-audio,usbhid type: USB rev: 2.0 speed: 12 Mb/s
    lanes: 1 mode: 1.1 bus-ID: 5-4.2.3:9 chip-ID: 0951:16ea class-ID: 0300
    serial: <filter>
  API: ALSA v: k6.9.3-3-MANJARO status: kernel-api with: aoss
    type: oss-emulator tools: alsactl,alsamixer,amixer
  Server-1: JACK v: 1.9.22 status: off tools: N/A
  Server-2: PipeWire v: 1.0.7 status: active with: 1: pipewire-pulse
    status: active 2: wireplumber status: active 3: pipewire-alsa type: plugin
    tools: pactl,pw-cat,pw-cli,wpctl

The issue I am having that I sometimes get crackling sound AFTER suspend.

Should I just create the BLANK /etc/pipewire/media-session.d/ directory with alsa-monitor.conf in it?

There is, however, alsa-vm.conf in

/usr/share/wireplumber/wireplumber.conf.d  tree
.
└── alsa-vm.conf

My current solution is to always Turn off/on the speakers, another person found out exact same thing but with bind/unbind (Crackling / distorted sound after waking up the PC with USB external audio device)

How can I set the alsa to not go to sleep, since, as @cscs said, the media.session is deprecated?

Thank you!

Thank you very much. I can confirm that worked fine on my RX 550.

Recently I was trying to play “Hellblade - Senua’s Sacrifice” through wine but it was almost impossible due to the amount of crackling sound via HDMI output.

All I did was to declare these variables and values you came up with before launching wine:
PULSE_LATENCY_MSEC=83 PIPEWIRE_LATENCY=1024/48000 wine program.exe

I was surprised it not just solved the crackling sound but the performance boost was huge. I can’t explain why, not a specialist.

I defined these values in the ~/.profile file and for my surprise there was a huge performance boost on most (if not all) the games I tried.

Again, thank you very much for sharing your knowledge.