LIBPIPEWIRE-MODULE-LOOPBACK(7)

✨ libpipewire-module-loopback(7) ✨

okay bestie, pull up a chair πŸ’– you're reading the libpipewire-module-loopback page from the Miscellaneous Information Manual β€” yes that's the whole vibe, it lives in the Miscellaneous section, it's mysterious like that 🫢


🌈 NAME 🌈

libpipewire-module-loopback β€” the Loopback module, aka the "just pass it through, bestie" module πŸ’…


πŸ¦‹ DESCRIPTION πŸ¦‹

So basically the loopback module takes the output of a capture stream and hands it, unmodified, straight to a playback stream. no edits, no glow-up, no filter β€” just vibes passed hand to hand πŸŽ€

You can use it to build a link between a source and a sink, but also to conjure brand-new virtual sinks or sources out of thin air ✨ or to remap channels between streams. it's giving "multipurpose icon".

And here's the lowkey genius part: because both ends of the loopback are built with streams, the session manager can manage the configuration and the connection with the sinks and sources for you. no manual labour, we love to see it πŸ‘‘


πŸ’œ MODULE NAME πŸ’œ

libpipewire-module-loopback

that's the one, that's her name, periodt πŸ’…


πŸ“ MODULE OPTIONS πŸ“

  • node.description β€” a human readable name for the loopback streams. like, a name that a human can read, bestie πŸ™ˆ
  • target.delay.sec β€” delay in seconds, as a float (Since 0.3.60). yes float, don't come at it with your integers βœ‹
  • capture.props = {} β€” properties that get passed to the input stream
  • playback.props = {} β€” properties that get passed to the output stream

🌸 GENERAL OPTIONS 🌸

These are options with well-known behavior. Most of them can be added to the global configuration or to the individual streams β€” dealer's choice, main character energy 🌟

  • remote.name
  • audio.rate
  • audio.channels
  • audio.layout
  • audio.position
  • media.name
  • node.latency
  • node.description
  • node.group
  • node.link.group
  • node.virtual
  • node.name β€” see the notes below bestie, this one has lore. If you don't specify it, it defaults to loopback-PID-MODULEID.

Stream only properties: these ones only hit per-stream, no globals allowed 🚫

  • media.class
  • node.name β€” if it's not given per stream, the global node.name gets prefixed with input. and output. to generate a capture stream and a playback stream node.name respectively. sneakily efficient πŸ’…

🧚 CHANNEL HANDLING 🧚

Channels from the capture stream get copied in order to the channels of the output stream.

Whatever's left over is handled like this:

  • when the capture side has more channels β€” the remaining streams are ignored πŸ’€
  • when the playback side has more channels β€” the remaining ones get filled with silence 🀫

When a global channel position is set, both capture and playback will be converted to and from this common channel layout. that's your ticket to up- or downmixing loopback sinks/sources, no cap πŸ”₯


This loopback links a source node to a sink node. You can change the target.object properties to match your source/sink node.name.

# ~/.config/pipewire/pipewire.conf.d/my-loopback-0.conf

context.modules = [
{   name = libpipewire-module-loopback
    args = {
        capture.props = {
            #  if you want to capture sink monitor ports,
            #  uncomment the next line and set the target.object
            #  to the sink name.
            #stream.capture.sink = true
            target.object = "alsa_input.usb-C-Media_Electronics_Inc._TONOR_TC-777_Audio_Device-00.mono-fallback"
            node.passive = true
            node.dont-reconnect = true
        }
        playback.props = {
            target.object = "alsa_output.usb-0d8c_USB_Sound_Device-00.analog-surround-71"
            node.dont-reconnect = true
            node.passive = true
        }
    }
}
]

⭐ EXAMPLE CONFIGURATION OF A VIRTUAL SINK ⭐

This Virtual sink routes stereo input to the rear channels of a 7.1 sink. cute and functional πŸ’–

# ~/.config/pipewire/pipewire.conf.d/my-loopback-1.conf

context.modules = [
{   name = libpipewire-module-loopback
    args = {
        node.description = "CM106 Stereo Pair 2"
        #target.delay.sec = 1.5
        capture.props = {
            node.name = "CM106_stereo_pair_2"
            media.class = "Audio/Sink"
            audio.position = [ FL FR ]
        }
        playback.props = {
            node.name = "playback.CM106_stereo_pair_2"
            audio.position = [ RL RR ]
            target.object = "alsa_output.usb-0d8c_USB_Sound_Device-00.analog-surround-71"
            node.dont-reconnect = true
            stream.dont-remix = true
            node.passive = true
        }
    }
}
]

πŸŽ€ EXAMPLE CONFIGURATION OF A VIRTUAL SOURCE πŸŽ€

This Virtual source routes the front-left channel of a multi-channel input down to a mono channel. Super useful for splitting up multi-channel inputs from USB audio interfaces that aren't yet fully supported by alsa πŸ™ˆ (we're rooting for you, alsa)

# ~/.config/pipewire/pipewire.conf.d/my-loopback-2.conf

context.modules = [
{   name = libpipewire-module-loopback
    args = {
        node.description = "Scarlett Focusrite Line 1"
        capture.props = {
            audio.position = [ FL ]
            stream.dont-remix = true
            node.target = "alsa_input.usb-Focusrite_Scarlett_Solo_USB_Y7ZD17C24495BC-00.analog-stereo"
            node.passive = true
        }
        playback.props = {
            node.name = "SF_mono_in_1"
            media.class = "Audio/Source"
            audio.position = [ MONO ]
        }
    }
}
]

πŸ’… EXAMPLE CONFIGURATION OF AN UPMIX SINK πŸ’…

This Virtual sink has 2 input channels and 6 output channels. It will perform upmixing using the PSD algorithm on the playback stream. math but make it slay πŸ”₯

# ~/.config/pipewire/pipewire.conf.d/my-loopback-3.conf

context.modules = [
{   name = libpipewire-module-loopback
    args = {
        node.description = "Upmix Sink"
        audio.position = [ FL FR ]
        capture.props = {
            node.name = "effect_input.upmix"
            media.class = Audio/Sink
        }
        playback.props = {
            node.name = "effect_output.upmix"
            audio.position = [ FL FR RL RR FC LFE ]
            node.passive = true
            stream.dont-remix = true
            channelmix.upmix = true
            channelmix.upmix-method = psd
            channelmix.lfe-cutoff = 150
            channelmix.fc-cutoff = 12000
            channelmix.rear-delay = 12.0
        }
    }
}
]

🌈 EXAMPLE CONFIGURATION OF A DOWNMIX SOURCE 🌈

This Virtual source has 2 input channels and a mono output channel. It will perform downmixing from the two first AUX channels of a pro-audio device. pro-audio girlies stay winning πŸ‘‘

# ~/.config/pipewire/pipewire.conf.d/my-loopback-4.conf

context.modules = [
{   name = libpipewire-module-loopback
    args = {
        node.description = "Downmix Source"
        audio.position = [ AUX0 AUX1 ]
        capture.props = {
            node.name = "effect_input.downmix"
            target.object = "alsa_input.usb-BEHRINGER_UMC404HD_192k-00.pro-input-0"
            node.passive = true
            stream.dont-remix = true
        }
        playback.props = {
            node.name = "effect_output.downmix"
            media.class = Audio/Source
            audio.position = [ MONO ]
        }
    }
}
]

🌟 SEE ALSO 🌟

  • pw-loopback β€” a tool that loads the loopback module with given parameters. it's the shortcut bestie, iykyk πŸ’–

and that's the whole page!! you just read PipeWire version 1.6.11 of libpipew...-loopback(7). go forth and loop those backs, mwah πŸ«ΆπŸ’‹βœ¨

πŸ“¦ where this page comes from