Virtual Sink Creation and Loopback on Linux
How to Create, Manage, and Remove Virtual Sinks in Linux (PulseAudio/PipeWire)
When working on live streams, podcasts, or complex audio setups, having the ability to separate and control audio streams is essential. In Windows I have used Elgato WaveLink3 software to perform this tasks. One way to do this on Linux is by creating virtual sinks (null sinks) and assigning different applications to them. This post will show you how to automatically create virtual sinks, remap specific applications, and remove those sinks when you’re done—using simple Bash scripts.
Note: This was tested on Linux Mint 22 Cinnamon
1. Creating Virtual Sinks and Configuring Loopbacks
Purpose
The first script automates the creation of virtual (null) sinks named Audio1
, Audio2
, and Audio3
. It also automatically sets up loopbacks to your real hardware sink (for example, alsa_output.pci-0000_0d_00.4.analog-stereo
).
This setup allows you to:
- Separate different application audio (e.g., game audio, voice chat, music) without affecting your primary system audio.
- Replicate functionality similar to Elgato WaveLink3 software by splitting and isolating audio streams for recording or streaming.
- Exclude certain channels from recordings (e.g., exclude music from VODs).
Why Use It
- Live Streaming: Direct your game, voice chat, and system audio to different channels, making it easier to adjust levels or exclude certain sources from your stream.
- Audio Mixing: Combine or isolate multiple audio inputs (games, music, voice) in OBS or other digital audio workstation software.
- Debugging: Diagnose audio issues by isolating specific applications to a single sink.
Identifying Your Default Output Device
Before creating the virtual sinks, it’s often helpful to confirm which hardware sink is currently being used by default. You can do this by running:
pactl list short sources
pactl info | grep "Default Source"
pactl info | grep "Default Sink"
For example, the default sink might be alsa_output.pci-0000_0d_00.4.analog-stereo
. Use that value in your configuration for the loopbacks.
Script 1: create_sinks.sh
#!/usr/bin/env bash
# Function to check if a sink already exists
sink_exists() {
local sink_name=$1
pactl list short sinks | grep -q "$sink_name"
}
# Function to create a null sink and its loopback
create_sink_and_loopback() {
local sink_name=$1
local description=$2
local sink=$3
# Check and create the sink
if sink_exists "$sink_name"; then
echo "Sink $sink_name already exists. Assuming loopback is already configured."
else
echo "Creating sink: $sink_name with description: $description"
pactl load-module module-null-sink sink_name=$sink_name sink_properties=device.description="$description"
echo "Creating loopback for source: $sink_name.monitor to sink: $sink"
pactl load-module module-loopback source="$sink_name.monitor" sink="$sink"
fi
}
# List current sinks
echo "Checking existing sinks:"
pactl list short sinks
# Create new sinks and loopbacks
create_sink_and_loopback "Audio1" "Audio1" "alsa_output.pci-0000_0d_00.4.analog-stereo"
create_sink_and_loopback "Audio2" "Audio2" "alsa_output.pci-0000_0d_00.4.analog-stereo"
create_sink_and_loopback "Audio3" "Audio3" "alsa_output.pci-0000_0d_00.4.analog-stereo"
# List all sinks after configuration
echo "Sinks after configuration:"
pactl list short sinks
echo "Audio sources configured successfully."
How to Use It
- Make the script executable:
chmod +x create_sinks.sh
- Run it:
./create_sinks.sh
- After it finishes, you should see the new sinks (
Audio1
,Audio2
,Audio3
) in your audio manager or by runningpactl list short sinks
again.
2. Remapping Specific Applications to Virtual Channels
Purpose
Once you’ve created these virtual sinks, you’ll likely want to route specific applications to them. The second script finds active sink inputs based on application names and reassigns them to the sink of your choice.
Why Use It
- Fine-Grained Control: Send game audio to
Audio1
, VoIP apps toAudio2
, and background music toAudio3
for easier independent control. - Selective Recording: Only capture your game audio and mic, while leaving out other system sounds.
- On-the-Fly Changes: Adjust audio routing in real time without closing or restarting the applications.
Script 2: remap_audio.sh
#!/usr/bin/env bash
# Function to get the sink input ID for a specific application
get_sink_input_id() {
local app_name=$1
pactl list sink-inputs | awk -v app_name="$app_name" '
$1 == "Sink" && $2 == "Input" { sink_id = $3 }
/application.name/ && $0 ~ app_name { sub(/^#/, "", sink_id); print sink_id }
'
}
# Function to move an application to a specified sink
move_application_to_sink() {
local app_name=$1
local sink_name=$2
echo "Looking for sink input ID for application: $app_name"
sink_input_id=$(get_sink_input_id "$app_name")
if [ -z "$sink_input_id" ]; then
echo "No active sink input found for application: $app_name"
return 1
fi
echo "Moving $app_name (Sink Input ID: $sink_input_id) to sink: $sink_name"
pactl move-sink-input "$sink_input_id" "$sink_name"
}
# Move specific applications to the desired sink
move_application_to_sink "World of Warcraft" "Audio2"
move_application_to_sink "FINAL FANTASY V" "Audio2"
move_application_to_sink "Google Chrome" "Audio1"
move_application_to_sink "Firefox" "Audio1"
move_application_to_sink "Microsoft Edge" "Audio1"
move_application_to_sink "WEBRTC VoiceEngine" "Audio3" # e.g., Discord
How to Use It
- Make the script executable:
chmod +x remap_audio.sh
- Adjust the application names in the script to match the ones you actually use. For instance, replace
"World of Warcraft"
with the name of your game or"WEBRTC VoiceEngine"
with your chat app’s process name. - Run the script to move the targeted applications to their respective sinks:
./remap_audio.sh
- If your application refuses to switch sinks, or if its name doesn’t match what’s in the script, open
pavucontrol
to manually assign it.
3. Removing All Virtual Sinks and Loopbacks
Purpose
If you need to reset your audio configuration, or if you just want to remove the virtual sinks once you’re done, the third script cleans everything up by unloading the modules associated with the null sinks and loopbacks.
Why Use It
- Cleanup/Reset: Easily revert to your default audio setup when you’re finished.
- Troubleshooting: If something breaks or you suspect a misconfiguration, start fresh by removing all custom sinks.
Script 3: remove_sinks.sh
#!/usr/bin/env bash
# Function to unload all modules by name pattern
unload_modules() {
local pattern=$1
echo "Finding modules matching pattern: $pattern"
pactl list modules short | grep "$pattern" | while read -r module; do
module_id=$(echo "$module" | awk '{print $1}')
module_name=$(echo "$module" | awk '{print $2}')
echo "Unloading module $module_id ($module_name)"
pactl unload-module "$module_id"
done
}
# Remove all sinks and loopbacks created for Audio1, Audio2, Audio3
unload_modules "module-null-sink"
unload_modules "module-loopback"
# Verify removal
echo "Remaining modules:"
pactl list modules short
echo "Audio sources and loopbacks removed successfully."
How to Use It
- Make the script executable:
chmod +x remove_sinks.sh
- Run the script to unload the virtual sinks and loopbacks:
./remove_sinks.sh
- Confirm the sinks and loopbacks have been removed either by checking
pavucontrol
or runningpactl list modules short
.
Additional Tips
- Permissions: Make sure each script has executable permissions via
chmod +x
. - Order of Operations:
- Create Sinks (via
create_sinks.sh
). - Remap Applications (via
remap_audio.sh
). - Remove Sinks (via
remove_sinks.sh
) when done.
- Create Sinks (via
- Manual Adjustments with pavucontrol: If you run into issues—such as an application not appearing in the script—use the GUI tool
pavucontrol
to make changes on the fly.
Conclusion
These three scripts provide a flexible foundation for advanced audio routing on Linux systems, whether you’re a professional broadcaster, a podcaster, or just an enthusiast who wants finer control over your system’s audio. By creating and assigning specific null sinks, you can isolate, record, and manage different audio streams with ease—and then remove everything just as quickly when you’re finished.
- Script 1: Virtual Sink Creation – Set up null sinks and loopbacks automatically.
- Script 2: Remapping Applications – Dynamically move audio streams to your virtual sinks.
- Script 3: Removal – Quickly revert to your default system audio configuration.
Take advantage of these scripts to simplify your workflow, capture only what you want in recordings or streams, and tailor your system’s audio exactly to your needs. If you found this helpful, share it with friends or colleagues who might benefit from better audio control on Linux!