[HowTo] Troubleshoot crackling in PipeWire

Difficulty: ★★☆☆☆

This tutorial will help you get rid of crackling/popping issues in PipeWire and PipeWire-Pulse, as well as replace PulseAudio with PipeWire.

Note: This guide was written for pipewire with pipewire-media-session, not wireplumber, if you have wireplumber installed some of the configs will be at different locations, under different names using different formatting (For instance /usr/share/pipewire/media-session.d/alsa-monitor.conf would now be at /usr/share/wireplumber/main.lua.d/50-alsa-config.lua and formatted in LUA rather than being a regular config file). I might update the guide at a later date to properly include instructions for wireplumber, but currently the guide does not have them.

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 pipewire-media-session
    
  • PipeWire has it’s own wiki that contains a lot of useful information.

  • To replace PulseAudio with PipeWire on Manjaro run:

    pamac remove manjaro-pulse pulseaudio-equalizer pulseaudio-jack pulseaudio-lirc pulseaudio-rtp && pamac install manjaro-pipewire
    
  • To replace PipeWire with PulseAudio (undo the above):

    pamac remove manjaro-pipewire && pamac install pulseaudio-bluetooth manjaro-pulse
    
  • If you accidentally uninstalled your volume controls for pulse while trying to install PipeWire, just reinstall them after installing PipeWire. I.E. for KDE users it’s:

    pamac install plasma-pa
    
  • 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.

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 ]    # This is not default because: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PipeWire#setting-global-sample-rate    

in pipewire-pulse.conf set:

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

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. Try upgrading/downgrading pipewire

    At this time, pipewire is still under active and heavy development, updates are pushed to it frequently and regressions often slip through the cracks. It has happened for me that some trick that solved all my crackling problems for one pipewire version suddenly seemed to do nothing after an update, sometimes i’ve updated pipewire and started experiencing new problems that weren’t there before too. Usually when this kind of thing happens it’s fixed quite fast as the developers tend to respond quickly to bug reports.

    Therefore the first thing you might want to do is try an older or newer version of pipewire, and if none of the fixes suggested in this guide seem to be working for you, it could just be a regression in your pipewire release thwarting your efforts.

    Don’t let this keep you away from trying though, this is one of the reasons why so many potential solutions are provided, at least some of them are bound to stick in spite of regressions. Manually configuring the playback buffer with environment variables is at least an almost surefire way to eliminate crackling assuming the problem isn’t ALSA or hardware deep.

  2. Create the config files for pipewire (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/media-session.d/ && sudo cp /usr/share/pipewire/*.conf /etc/pipewire/ && sudo cp /usr/share/pipewire/media-session.d/*.conf /etc/pipewire/media-session.d/
    

    Create User Config Files:

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

    Note: If you’re using wireplumber cp /usr/share/pipewire/*.conf /etc/pipewire/ or cp /usr/share/pipewire/*.conf ~/.config/pipewire/

  3. Disable Suspend

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

    • In alsa-monitor.conf change
    #session.suspend-timeout-seconds = 5 
    

    to

    session.suspend-timeout-seconds = 0
    
    • Restart pipewire to apply
  4. 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.
  5. Try setting 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-monitor.conf change
      #api.alsa.headroom      = 0
      
      to
      api.alsa.headroom      = 1024    # See: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-ALSA#alsa-buffer-properties
      
    • Restart pipewire to apply.
    • If setting headroom to 1024 has an effect but doesn’t entirely solve the issue, try setting it to 2048.
    • If setting headroom to 1024 completely solves the issue, see if lower values work (512, 256, 128, 64, 32) and use the lowest value that works.
  6. Try changing the alsa period size
    If the problem still isn’t resolved, try changing the alsa period size.

    • In alsa-monitor.conf change
      #api.alsa.period-size   = 1024
      #api.alsa.headroom      = 0
      
      to
      # See: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-ALSA#alsa-buffer-properties
      api.alsa.period-size   = 256
      api.alsa.headroom      = 1024
      
    • 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 does solve your issue, try to find the lowest setting combination that does work.
    • If this does not affect your issue, comment out both settings to reset them to default before continuing.
  7. 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.

  8. 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), 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, some things supposedly can already break when this setting is set to 1024, but I have not personally experienced it (probably only applies to professional audio applications.)

    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:

17 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

Last I checked manjaro also uses pulse by default still (pipewire was installed by default, however pulseaudio was also installed and preferred over pipewire by default). Then again last I checked was maybe half a year ago, maybe something’s changed by now. Good luck with your headphones man :slight_smile:

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.