My problem is this: I'm talking to some friends via voice chat and at some point I'd also like to mix some music into it. So my current setup is this:

Microphone (Input device) -> Voice software
Music player -> Headphones (Output device)

I'd like to have this:

Music player -> Headphones

Music player -\
               -> ? -> Voice software
Microphone   -/

I've had a look at the Pipewire wiki quite a bit and especially the part about Virtual-Devices seemed to be very relevant but after playing around with a lot of pw-loopback I eventually gave up.

In the end, I think I'll need to end up with a virtual input device so that it's even selectable in my recording applications.

Is this even the right approach?


3 Answers 3


If you want to mix your voice input (mic) and the output of music player, then the setup would be like this:

Music player -\
               -> Combined Sink/Source -> Virtual Microphone -> Voice software
Microphone   -/

Here is the walktrough:

1. Create the combined-sink interface

pactl load-module module-null-sink media.class=Audio/Sink sink_name=my-combined-sink channel_map=stereo

2. Create a Virtual Microphone

pactl load-module module-null-sink media.class=Audio/Source/Virtual sink_name=my-virtualmic channel_map=front-left,front-right

3. Link your microphone & the music player output into the combined sink

Note: The microphone interface name & the music player output interface name may be different. Run pw-link -o to show list of the outputs.

pw-link spotify:output_FL my-combined-sink:playback_FL
pw-link spotify:output_FR my-combined-sink:playback_FR

pw-link alsa_input.pci-0000_00_1f.3.analog-stereo:capture_FL  my-combined-sink:playback_FL
pw-link alsa_input.pci-0000_00_1f.3.analog-stereo:capture_FR  my-combined-sink:playback_FR

4. Link your combined sink to the virtual microphone

pw-link my-combined-sink:monitor_FL my-virtualmic:input_FL
pw-link my-combined-sink:monitor_FR my-virtualmic:input_FR

Now you can tell the voice software to make use this virtual microphone or set the virtual microphone as the default voice input.

  • 1
    Please, change point 3 to mention both pw-link -o and pw-link -i. As it currently stands it confuses, because the -o won't show *playback* nodes, so it would look as if they're missing.
    – Hi-Angel
    Aug 11, 2022 at 10:25
  • 1
    You can link all your microphones and it will work just fine. You might save yourself an hour trying to find out why it does not work because you picked the wrong microphone, like I did.
    – sup
    Apr 24, 2023 at 22:24
  • 1
    While you still need the command-line to create the virtual devices, you can link them using a GUI. I personally recommend using qpwgraph, as it is very intuitive. There is also helvum, but I find it more difficult to use. Nov 5, 2023 at 7:08

use pw-link to conect stuff (check out "pw-link -h"). an alternative GUI way would be to use Carla. there is also the Helvum GUI created especificly for Pipewire

  • 1
    Thanks, however I'm still unclear as to how I'd even set up my devices in the first place. Which loopbacks do I need to accomplish what I want?
    – svenstaro
    Sep 16, 2021 at 18:17

Here's a scripted version of the answer from Pujianto. This will create a combined virtual mic with another application (which is assumed to be putting out stereo, uniquely named, and greppable).

e.g. combine_audio.sh spotify

The script will also remove any null sinks that are active, so be warned, but I think that isn't so common in normal use? I use this with Skype and OBS so I can chat with people and stream application/game audio as well as my mic, without looping their audio in. You may need to restart stuff to have the mic show up, but once it's there you can hot-swap applications without any problem.

You also need to check your mic's name, e.g. the script below uses my webcam.



results=$(pw-link -o | grep ${1})
IFS=$'\n' read -ra ADDR -d $'\0' <<< "$results"

# Unload if exists
pactl unload-module module-null-sink

# Make new sinks
pactl load-module module-null-sink media.class=Audio/Sink sink_name=$SINK_NAME channel_map=stereo >> /dev/null
pactl load-module module-null-sink media.class=Audio/Source/Virtual sink_name=$VIRTUAL_MIC_NAME channel_map=front-left,front-right >> /dev/null

# Extract app name
read -a APP_STR <<< ${ADDR[0]}
echo "Linking app ${APP_STR} to ${SINK_NAME}"
pw-link "${APP_STR}":output_FL $SINK_NAME:playback_FL
pw-link "${APP_STR}":output_FR $SINK_NAME:playback_FR

echo "Linking $MIC_SOURCE to ${SINK_NAME}"
pw-link $MIC_SOURCE:capture_FL  $SINK_NAME:playback_FL
pw-link $MIC_SOURCE:capture_FR  $SINK_NAME:playback_FR

echo "Creating virtual mic: $VIRTUAL_MIC_NAME"
pw-link $SINK_NAME:monitor_FL $VIRTUAL_MIC_NAME:input_FL
pw-link $SINK_NAME:monitor_FR $VIRTUAL_MIC_NAME:input_FR

Could combine with https://askubuntu.com/questions/355082/pulseaudio-loopback-unload-audio-output-devices to make unloading more intelligent.

  • So you just run this script automatically at system startup?
    – m1212e
    Oct 3, 2023 at 21:52
  • The app needs to be running before you create the interface I think. I run it on demand since I only need to use it for video calling.
    – Josh
    Oct 10, 2023 at 22:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .