How to configure PulseAudio for playing on multiple devices at the same time on Ubuntu

This guide was produced in Ubuntu 18.04.1 LTS

Disclaimer: This guide was produced for Ubuntu Bionic 18.04.1, but it supposedly works for previous versions including the same PulseAudio daemon architecture.

You should at least be able to use the terminal to follow this guide.

The combined sink

A (single) sink is an audio channel; and thus a combined sink is one made of multiple different other sinks (called slave sinks). Our objective is to output directly to this master sink, which will, in turn, play the audio to it’s children slave sinks — your headphone’s sink, your TV’s sink, your home-theater sink — all at the same time!

By changing this combined sink’s audio output properties (e.g. using an equalizer filter or changing the volume), you‘re changing the “master channel” and therefore the effects will also reflect indirectly into it’s slave sinks.


The easy way — paprefs

After installing, you just literally (literally) have to click this option and it automatically creates the combined sink for you.

paprefs is a utility that provides the option to create this combined sink we discussed before, but here’s the catch: as the option exactly says, it will create this unified sink for all cards available in the system. It means that if you’re running with a single card made up of different devices like in my case, paprefs will not help you.

You can check which story it is for you by executing in the terminal:

aplay -l

And seeing if it reports the same card identifier (highlighted in red) for all of your listed sources.

Notice how my devices are all tied to the same card 0, and therefore I won’t be able to play on them at the same time using paprefs’ automatically generated sink.

Now, if the output is not like that and your devices are not tied to the same card, your work likely ends here. Install paprefs, mark the checkbox in the “Simultaneous Output” tab, close the app. Your sink has already been created at this point and you didn’t even see it. It’s that simple.

sudo apt-get install paprefs

Additionally, you’ll need to check if this combined sink it created for you is the currently default audio device — but it should already be. Now you need to restart your system (just to be sure) or just PulseAudio’s daemon instead, by running:

pulseaudio --kill && pulseaudio --start

Now… If your desired target devices are all tied to the same card like the image above, paprefs won’t solve your problem. Proceed to the next step: Manually configuring your combined sink.

You’ll probably find multiple other answers and explanations including this solution over at the AskUbuntu forums @ AskUbuntu.com. Some examples:


Manually configuring your combined sink

Since paprefs doesn’t work for you, the solution will be to create separate individual sinks for each of our devices in the pulseaudio’s startup script, and then tie those sinks into our combined sink through their name identifiers.

Before starting, make a backup of /etc/pulse/default.pa in case your changes don’t go well. You can make a copy of this file to your home directory by typing the following in the terminal:

cp /etc/pulse/default.pa ~/default.pa

Having created the backup, run again:

aplay -l

That will give us list of the devices we’re trying to create sinks for. The most important attributes for each item will be the card number and the device number.

We’ll use both of those numbers to create our individual sinks with the following commands:

load-module module-alsa-sink device="hw:[card number],[device number]" sink_name=[your_sink_name] sink_properties="[some useful sink properties for the sound panel]"

Replace those descriptions inside the brackets and you have the command to create your sink. Here is a working example from my configuration:

load-module module-alsa-sink device="hw:0,0" sink_name=audio_jack sink_properties="device.description='Audio Jack' device.icon_name='audio-card'"

hw:0,0 means card 0, device 0 (Generic Analog from the image above).
audio_jack is the name I chose for it. Choose a name with no spaces or special characters and glue_separate_words_with_underline.
sink_properties contains some properties for the sinks to show up nicely in the sound options panel.
device.description=Audio Jack’ is the name that will show up in the sound panel.
device.icon_name=audio-card’ is the icon I chose to display for it in the sound panel.

You can pass more options other than device, sink_name and sink_properties. Visit this link for more information. And yes, you’ll of course need to type each one of those commands for each particular device (soon-to-be a sink) that you intend to tie into the combined sink.

Having done all that, now it’s time to create the combined sink. The command follows the same syntax.

load-module module-combine-sink sink_name=[your_sink_name] slaves=[the names you chose before] sink_properties="[some useful properties for the sound panel]"

And again, the working example from my configuration:

load-module module-combine-sink sink_name=combined_output slaves=hdmi_output,audio_jack sink_properties="device.description='Combined HDMI + Audio Jack' device.icon_name='audio-card-symbolic'"

combined_output is the name I chose for the combined sink.
hdmi_output,audio_jack are the sinks I created and named before with load-module module-alsa-sink.
sink_properties contains some properties for the sink to show up nicely in the sound options panel.
device.description=’Combined HDMI + Audio Jack is the name that will show up in the sound panel.
device.icon_name=‘audio-card-symbolic is the icon I chose to display for it in the sound panel.

Finally, you should have some code like this:

I chose to create sinks for Generic Analog (0,0) and HDMI-0 (0,3). Having them named, respectively, audio_jack and hdmi_output, I put those names in the slaves field for my final command. Preview made with Carbon.

Here is the configuration in action from my Ubuntu Budgie 18.04.1 LTS sound panel, including the custom icons I chose in the sink_properties field.

Hopefully it will look similar to this after you put your configuration into practice.

Replacing your configuration

The current configuration is at that path we made a backup for: /etc/pulse/default.pa. This system file requires root access so you’ll need to edit it with sudo. I’m on Gnome so I chose Geany as my text editor.

sudo geany /etc/pulse/default.pa

Assuming you use Ubuntu, your default configuration probably has a section like this:

### Load audio drivers statically
### (it's probably better to not load these drivers manually, but instead
### use module-udev-detect -- see below -- for doing this automatically)
#load-module module-alsa-sink
...
...

That’s likely where you want to paste your created configuration. If it’s not there, you can just put it at the start of the file. We’ll verify that it works when we run the command again anyway so don’t worry about the placement too much, as long as it’s near the top.

Pasted your code? Good. Now search for module-udev-detect inside of this same file. We’ll need to comment out the whole module-udev-detect shenanigans because it will automatically try to configure everything by itself, including what we are doing manually, and we don’t want that. Put comment hashtags in front at the start of every line that relates to it, like this:

### Automatically load driver modules depending on the hardware available
#.ifexists module-udev-detect.so
#load-module module-udev-detect
#.else
### Use the static hardware detection module (for systems that lack udev support)
#load-module module-detect
#.endif

Finally, at the bottom of the file, you want to define what’s your new default sink, since it’s not sorted out by module-udev-detect anymore.

set-default-sink [your_sink_name_here]

Save the file and restart pulseaudio in the command line:

pulseaudio --kill && pulseaudio --start

It should work. Should. But if something doesn’t work, it will error right there in your face. You can keep tinkering with the file until it finally starts again without complaining. In case something hairy comes up, search for possible solutions on AskUbuntu.com.

In the terrible case where something goes terribly wrong, you can always fall back to your backup configuration. Changing this file won’t completely dismantle your whole system or anything like that so it’s very likely that you can keep butting your head into the wall until it works.


The final stop

You have created your combined sink, selected it as your output channel in the sound panel, everything is loading fine… But it might just barely not work still. Chances are that something is muted in the AlsaMixer menu and you don’t know (yet).

Run the following command:

alsamixer

Press F5 to see all of the available controls. You can mute/unmute stuff by navigating to the them to with your arrow keys and pressing M, among other actions (F1 to open the help menu).

Keep a music track going in your favorite audio player and start messing around with those controls to figure out what means what. For me, I had to unmute specifically <S/PDIF> for my configuration to work.

Move with the right/left arrow keys to the control and press M to mute/unmute. Press the up/down arrow keys to change it’s volume.

The final final stop

  • Go to your system’s sound panel (should be accessible through the system tray) and see if your combined sink is correctly selected as the current output device.
  • If you can’t change things from there for whatever reason, install PulseAudio’s own control panel to know exactly what’s going on. You can even assign different output devices for each running audio application.
sudo apt-get install pavucontrol

Happy ending — It works!

Sad ending — It still doesn’t work…

Sorry, I got a bit excited. That’s pretty lame. I’m not an expert on PulseAudio or anything but here are some links I’ve used that might help you:

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade