LIBPIPEWIRE-MODULE-COMBINE-STREAM(7)

πŸ’– libpipewire-module-combine-stream β€” Combine Stream πŸ’–

okay bestie, so this is a page from the Miscellaneous Information Manual and it's about libpipewire-module-combine-stream, and honestly? it's giving main character energy for your audio setup. let's get into it πŸŽ€


✨ NAME ✨

libpipewire-module-combine-stream β€” Combine Stream. that's it, that's the name, short and iconic πŸ’…


🌸 DESCRIPTION 🌸

the combine stream module can make:

  • a new virtual sink that forwards audio to other sinks
  • a new virtual source that combines audio from other sources

the sources and sink that need to be combined can be selected using generic match rules. which is lowkey the best part, because it means you can combine static nodes, or nodes based on certain properties. no cap. πŸ¦‹


πŸ‘‘ MODULE NAME πŸ‘‘

libpipewire-module-combine-stream

✨ MODULE OPTIONS ✨

  • node.name β€” a unique name for the stream. make it cute, make it yours.
  • node.description β€” a human readable name for the stream (aka the one your friends will actually see).
  • combine.mode = capture | playback | sink | source, default sink β€” pick your fighter.
  • combine.latency-compensate β€” use delay buffers to match stream latencies. yes, it lines them up, gorgeous.
  • combine.on-demand-streams β€” use metadata to create streams on demand.
  • combine.props = {} β€” properties to be passed to the sink/source.
  • stream.props = {} β€” properties to be passed to the streams.
  • stream.rules = {} β€” rules for matching streams, use create-stream actions.

🌈 GENERAL OPTIONS 🌈

options with well-known behavior. the classics, the OGs.

  • remote.name
  • audio.channels
  • audio.layout
  • audio.position
  • media.name
  • node.latency
  • node.name
  • node.description
  • node.group
  • node.virtual
  • media.class

πŸ¦‹ STREAM OPTIONS πŸ¦‹

  • audio.position β€” set the stream channel map. by default this is the same channel map as the combine stream. you can also use audio.layout. periodt.
  • combine.audio.position β€” map the combine audio positions to the stream positions. combine input channels are mapped one-by-one to stream output channels. you can also use combine.audio.layout. iykyk 🌸

πŸ’œ EXAMPLE CONFIGURATION πŸ’œ

okay so here's the first one, a whole little config for you. slay.

# ~/.config/pipewire/pipewire.conf.d/my-combine-stream-1.conf

context.modules = [
{   name = libpipewire-module-combine-stream
    args = {
        combine.mode = sink
        node.name = "combine_sink"
        node.description = "My Combine Sink"
        combine.latency-compensate = false
        combine.props = {
            audio.position = [ FL FR ]
        }
        stream.props = {
        }
        stream.rules = [
            {
                matches = [
                    # any of the items in matches needs to match, if one does,
                    # actions are emitted.
                    {
                        # all keys must match the value. ! negates. ~ starts regex.
                        #node.name = "~alsa_input.*"
                        media.class = "Audio/Sink"
                    }
                ]
                actions = {
                    create-stream = {
                        #combine.audio.position = [ FL FR ]
                        #audio.position = [ FL FR ]
                    }
                }
            }
        ]
    }
}
]

below is an example configuration that makes a 5.1 virtual audio sink from 3 separate stereo sinks. the way that it just... combines three whole sinks into one?? obsessed. πŸ’–

# ~/.config/pipewire/pipewire.conf.d/my-combine-stream-2.conf

context.modules = [
{   name = libpipewire-module-combine-stream
    args = {
        combine.mode = sink
        node.name = "combine_sink_5_1"
        node.description = "My 5.1 Combine Sink"
        combine.latency-compensate = false
        combine.props = {
            audio.position = [ FL FR FC LFE SL SR ]
        }
        stream.props = {
                stream.dont-remix = true      # link matching channels without remixing
        }
        stream.rules = [
            {   matches = [
                    {   media.class = "Audio/Sink"
                        node.name = "alsa_output.usb-Topping_E30-00.analog-stereo"
                    } ]
                actions = { create-stream = {
                        combine.audio.position = [ FL FR ]
                        audio.position = [ FL FR ]
                } } }
            {   matches = [
                    {   media.class = "Audio/Sink"
                        node.name = "alsa_output.usb-BEHRINGER_UMC404HD_192k-00.pro-output-0"
                    } ]
                actions = { create-stream = {
                        combine.audio.position = [ FC LFE ]
                        audio.position = [ AUX0 AUX1 ]
                } } }
            {   matches = [
                    {   media.class = "Audio/Sink"
                        node.name = "alsa_output.pci-0000_00_1b.0.analog-stereo"
                    } ]
                actions = { create-stream = {
                        combine.audio.position = [ SL SR ]
                        audio.position = [ FL FR ]
                } } }
        ]
    }
}
]

and below is an example configuration that makes a 4.0 virtual audio source from 2 separate stereo sources. she flipped it, we love a source moment. πŸ”₯

# ~/.config/pipewire/pipewire.conf.d/my-combine-stream-3.conf

context.modules = [
{   name = libpipewire-module-combine-stream
    args = {
        combine.mode = source
        node.name = "combine_source_4_0"
        node.description = "My 4.0 Combine Source"
        combine.props = {
            audio.position = [ FL FR SL SR ]
        }
        stream.props = {
                stream.dont-remix = true
        }
        stream.rules = [
            {   matches = [
                    {   media.class = "Audio/Source"
                        node.name = "alsa_input.usb-046d_HD_Pro_Webcam_C920_09D53E1F-02.analog-stereo"
                    } ]
                actions = { create-stream = {
                        audio.position = [ FL FR ]
                        combine.audio.position = [ FL FR ]
                } } }
            {   matches = [
                    {   media.class = "Audio/Source"
                        node.name = "alsa_input.usb-046d_0821_9534DE90-00.analog-stereo"
                    } ]
                actions = { create-stream = {
                        audio.position = [ FL FR ]
                        combine.audio.position = [ SL SR ]
                } } }
        ]
    }
}
]

🫢 quick vibe check bestie: go forth and combine your streams. you literally cannot mess this up, you have the whole config.

okay and that's a wrap on the libpipew...ne-stream(7) page πŸ’… this came to you from PipeWire version 1.6.11 β€” mwah, love that for you, go stream something (literally). bye bestie!! πŸ˜­πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from