Disable Pipewire Suspend on Idle to avoid audio pops, delays, and white noise

Disable Pipewire Suspend on Idle to avoid audio pops, delays, and white noise

In case you're experiencing a sound pop whenever sound is played after a a certain amount of time – or a little while after sound has played. Or perhaps you have more sensitive hearing or headphones/speakers and can notice white noise coming from your computer after a little while. If you experience something like this, it might be worth considering disabling Pipewire's "Suspend on Idle" feature, which is enabled (and set to 5 seconds) by default.

While there's unfortunately no way of doing this through a GUI, it is fortunately not too challenging to do. Let's get started.

Note: This quick guide is written with the assumption that your system is already fully configured to use Pipewire and Wireplumber for audio. This is the default for Fedora (Since 35 I believe), and an increasing amount of other flavor distributions are switching over too. If your setup is not yet using Wireplumber, this guide might not be for you.

Configuring Wireplumber is seemingly mostly done through LUA scripts, so that's what we'll do here too. Let's start by copying an existing alsa config script over to the right place, after which we can make our own modifications to it:

❯ sudo cp -a /usr/share/wireplumber/main.lua.d/50-alsa-config.lua /etc/wireplumber/main.lua.d/50-alsa-config.lua

When we open up the file we just copied over using your favorite text editor, you'll find something that looks like this (note: I have abbreviated parts of the file contents for legibility):

alsa_monitor.enabled = true

alsa_monitor.properties = {
  -- (...abbreviated for legibility...)
}

alsa_monitor.rules = {
  
  -- (...abbreviated for legibility...)
  
  {
    matches = {
      {
        -- Matches all sources.
        { "node.name", "matches", "alsa_input.*" },
      },
      {
        -- Matches all sinks.
        { "node.name", "matches", "alsa_output.*" },
      },
    },
    apply_properties = {
      --["node.nick"]              = "My Node",
      --["priority.driver"]        = 100,
      --["priority.session"]       = 100,
      --["node.pause-on-idle"]     = false,
      --["resample.quality"]       = 4,
      --["channelmix.normalize"]   = false,
      --["channelmix.mix-lfe"]     = false,
      --["audio.channels"]         = 2,
      --["audio.format"]           = "S16LE",
      --["audio.rate"]             = 44100,
      --["audio.allowed-rates"]    = "32000,96000"
      --["audio.position"]         = "FL,FR",
      --["api.alsa.period-size"]   = 1024,
      --["api.alsa.headroom"]      = 0,
      --["api.alsa.disable-mmap"]  = false,
      --["api.alsa.disable-batch"] = false,
      --["session.suspend-timeout-seconds"] = 5,  -- 0 disables suspend
    },
  },
}

Any line that starts with -- is commented out. Basically this configuration file we just copied over shows what all the default settings are in a way that you can easily un-comment-out the line you care about and modify its value to whatever you want it to be instead of its default.

At the very end of this file, you'll notice the session.suspend-timout-seconds value that, by default, is set to 5 seconds. There's a note there that already mentions what we want to achieve, so let's un-comment-out that line and change its value to read 0 instead:

alsa_monitor.rules = {
  
  -- (...abbreviated for legibility...)
  
  {
    apply_properties = {
      -- (...abbreviated for legibility...)
      ["session.suspend-timeout-seconds"] = 0, -- default is 5
    },
  },
}

And that should do it. You can now restart the wireplumber service and it should immediately pick up on this new configuration:

❯ systemctl --user restart wireplumber

That's it! Not too bad, right? If you've been dealing with these kinds of audio issues, I hope this can help you solve those problems.

Thank you.