PipeWire 0.3.65
PipeWire Module: Combine Stream

The combine stream can make:

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

Module Options

  • node.name: a unique name for the stream
  • node.description: a human readable name for the stream
  • combine.mode = capture | playback | sink | source, default sink
  • combine.props = {}: properties to be passed to the sink/source
  • stream.props = {}: properties to be passed to the streams

General options

Options with well-known behavior.

Stream options

  • audio.position: Set the stream channel map. By default this is the same channel map as the combine stream.
  • combine.audio.position: map the combine audio positions to the stream positions. combine input channels are mapped one-by-one to stream output channels.

Example configuration

context.modules = [
{ name = libpipewire-module-combine-stream
args = {
combine.mode = sink
node.name = "combine_sink"
node.description = "My Combine Sink"
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 emited.
{
# all keys must match the value. ~ in value 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.

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.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 ]
} } }
]
}
}
]

Below is an example configuration that makes a 4.0 virtual audio source from 2 separate stereo sources.

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 ]
} } }
]
}
}
]