Published the 2026-06-13 on Willow's site

How to have a decent microphone input?

Most of the video and audio meetup programs embed some audio cleanup utilities, echo canceling, rnoise, etc. But I prefer to have this configured system-wide, so that every piece of program can benefit from this.

For years, I have worked with multiple seat configuration, and different peripheral combination. I have a bunch of Pipewire configurations to use for most of the situations. Pipewire module configuring still lack a pool of examples, and how’s-to. So here is my experience and tips.

The main module I’m using almost everywhere is the echo cancel one. This module help reducing the echo feedback, but it actually does even more. It also reduces the ambient noise, without relying on voice detection, without gate keeping laugh noises, or other sound you may make, and without much extra latency. It is purely the WebRTC module, made available directly in Pipewire.

# ~/.config/pipewire/pipewire.conf.d/echo-cancel.conf
context.modules = [
  {   name = libpipewire-module-echo-cancel
      args = {
          # Uncomment when using external speakers
          # sink.props = {
          #     filter.smart = true
          #     filter.smart.name = echo-cancel-sink
          # }
          source.props = {
              filter.smart = true
              filter.smart.name = echo-cancel-source
          }
      }
  }
]

You can just put this file in the folder ~/.config/pipewire/pipewire.conf.d/. Then restart the Pipewire service, and you should see the module output and input devices in Pavucontrol.

Smart Filter is a mostly recent feature of Wireplumber. This makes the Sink and Source “smart filters”, meaning they act as gateway for you application, without altering the Sinks/Sources defined as default for your system.

You can launch a program to record, by example pw-record, and you should note that it records from the Echo-Cancel Source, and not your actual device. This also means you volume control keybind will continue to handle the actual device, and not this intermediary node.

You can chain the smart filters, and even specify which one have to come first and after the other ones. This feature permit you to build complex chains, let’s keep it simple here, but you can check the full documentation.

You also noted I have commented the smart filter configuration for the sink. In my situation, I am using earpieces on this desktop machine, meaning I don’t suffer any echo feedback. I am using it purely for its noise suppression feature. But you should uncomment this if you audio output on some loud external speakers, or if you unfortunately use a bad headphone that produce loopback. Every audio output will go through the module, and this helps to reduce this echo loopback.

Another cheap module to build custom chains is the loopback module. I’m generally using it directly to produce a microphone-to-earpieces loopback. This allows you to immediately ear what the application is actually recording. Generally considered as a mandatory feature for professional streamers of content, it can also be used just to de-isolate your audio peripheral, and to correctly ear your own voice as you talk.

# ~/.config/pipewire/pipewire.conf.d/ears-loopback.conf
context.modules = [
    {   name = libpipewire-module-loopback
        args = {
            node.description = "Ears Loopback"
            audio.position = [ FL FR ]
            playback.props = {
               stream.dont-remix = true
               node.max-latency = 480/48000
            }
        }
    }
]

Obviously be careful to add this only on setups that don’t produce audio loopback, or Larsen effect.

I’m keeping an eye on the Wireplumber media role improvements. This could be used to mix programs volumes based on their role, and complex rule-sets. For example, to reduce the volume of your music program when someone is talking through Mumble. From recent experiments, this was behaving poorly with smart filters, but soon enough this could be impressive. This feature is still poorly documented, but you can have a glance at this example.

RSS feed

If this post inspired you, feels free to leave a comment!

Reach me