Once again, some notes for my own personal reference, which may help others as well. And if something is wrong, let me know.
Written only from the user’s perspective.
What is it?
Quoting from the description:
PulseAudio is a sound system for POSIX OSes, meaning that it is a proxy for your sound applications. It allows you to do advanced operations on your sound data as it passes between your application and your hardware. Things like transferring the audio to a different machine, changing the sample format or channel count and mixing several sounds into one are easily achieved using a sound server.
PulseAudio is designed for Linux systems. It has also been ported to and tested on Solaris, FreeBSD, NetBSD, MacOS X, Windows 2000 and Windows XP.
PulseAudio is an integral part of all relevant modern Linux distributions and used in various mobile devices by multiple vendors.
It’s running as a daemon. My understanding is that it runs in userspace.
Main concepts
PulseAudio is an audio graph. It uses a variety of modules to expose sinks and sources. Sinks and sources seem to be what Apple’s Core Audio, another audio graphing system, would all be “audio units”, where there could be some inputs, and some outputs. Here, sinks seem to be intended as playback devices, and input devices such as microphones are sources.
Clients can create sink inputs.
Main tools
As a user, main CLI tools used to interact will be pactl
and pacmd
. I’m fine with pactl
, but pacmd
seems to expose more options.
To view all objects known to PulseAudio, use pactl list
.
Module #0
Name: module-device-restore
Argument:
Usage counter: n/a
Properties:
module.author = "Lennart Poettering"
module.description = "Automatically restore the volume/mute state of devices"
module.version = "4.0"
Module #1
Name: module-stream-restore
Argument:
Usage counter: n/a
Properties:
module.author = "Lennart Poettering"
module.description = "Automatically restore the volume/mute/device state of streams"
module.version = "4.0"
....
Module #21
Name: module-filter-apply
Argument:
Usage counter: n/a
Properties:
module.author = "Colin Guthrie"
module.description = "Load filter sinks automatically when needed"
module.version = "4.0"
Sink #0
State: SUSPENDED
Name: alsa_output.pci-0000_05_00.1.hdmi-stereo
Description: GF108 High Definition Audio Controller Digital Stereo (HDMI)
Driver: module-alsa-card.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Owner Module: 5
Mute: no
Volume: 0: 84% 1: 84%
0: -4.39 dB 1: -4.39 dB
balance 0.00
Base Volume: 100%
0.00 dB
Monitor Source: alsa_output.pci-0000_05_00.1.hdmi-stereo.monitor
Latency: 0 usec, configured 0 usec
Flags: HARDWARE DECIBEL_VOLUME LATENCY SET_FORMATS
Properties:
alsa.resolution_bits = "16"
device.api = "alsa"
...
device.vendor.id = "10de"
device.vendor.name = "NVIDIA Corporation"
device.product.id = "0bea"
device.product.name = "GF108 High Definition Audio Controller"
device.string = "hdmi:2"
device.buffering.buffer_size = "65536"
device.buffering.fragment_size = "32768"
device.access_mode = "mmap+timer"
device.profile.name = "hdmi-stereo"
device.profile.description = "Digital Stereo (HDMI)"
device.description = "GF108 High Definition Audio Controller Digital Stereo (HDMI)"
alsa.mixer_name = "Nvidia GPU 14 HDMI/DP"
alsa.components = "HDA:10de0014,10de0101,00100100"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card-pci"
Ports:
hdmi-output-0: HDMI / DisplayPort (priority: 5900, not available)
Active Port: hdmi-output-0
Formats:
pcm
Sink #1
State: SUSPENDED
Name: alsa_output.pci-0000_00_1b.0.analog-stereo
Description: Built-in Audio Analog Stereo
...
Source #2
State: SUSPENDED
Name: alsa_input.pci-0000_00_1b.0.analog-stereo
Description: Built-in Audio Analog Stereo
Driver: module-alsa-card.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
...
Client #5
Driver: protocol-native.c
Owner Module: 11
Properties:
application.name = "GNOME Volume Control Media Keys"
native-protocol.peer = "UNIX socket client"
native-protocol.version = "28"
application.id = "org.gnome.VolumeControl"
application.icon_name = "multimedia-volume-control"
application.version = "1.0"
application.process.id = "30127"
application.process.user = "ivucica"
application.process.host = "MYHOSTNAME"
application.process.binary = "unity-settings-daemon"
application.language = "en_US.UTF-8"
window.x11.display = ":0"
application.process.machine_id = "MYMACHINEID"
application.process.session_id = "c14"
...
Card #1
Name: alsa_card.pci-0000_00_1b.0
Driver: module-alsa-card.c
Owner Module: 6
Properties:
alsa.card = "0"
alsa.card_name = "HDA Intel PCH"
alsa.long_card_name = "HDA Intel PCH at 0xef340000 irq 86"
alsa.driver_name = "snd_hda_intel"
...
Sink Input #0
Driver: protocol-native.c
Owner Module: 11
Client: 7
Sink: 1
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Format: pcm, format.sample_format = "\"s16le\"" format.rate = "44100" format.channels = "2" format.channel_map = "\"front-left,front-right\""
Corked: no
Mute: no
Volume: 0: 100% 1: 100%
0: 0.00 dB 1: 0.00 dB
balance 0.00
Buffer Latency: 60408 usec
Sink Latency: 21966 usec
Resample method: n/a
Properties:
application.icon_name = "google-chrome"
media.name = "Playback"
application.name = "Chrome"
native-protocol.peer = "UNIX socket client"
native-protocol.version = "28"
application.process.id = "13436"
application.process.user = "ivucica"
application.process.host = "MYHOSTNAME"
application.process.binary = "chrome (deleted)"
application.language = "en_US.UTF-8"
window.x11.display = ":0"
application.process.machine_id = "MYMACHINEID"
application.process.session_id = "c14"
module-stream-restore.id = "sink-input-by-application-name:Chrome"
Using pactl list short
, the output will be more ambiguous. Let’s filter it to show only sink-inputs using pactl list short sink-inputs
.
0 1 7 protocol-native.c s16le 2ch 44100Hz
Changing default output
When an app starts playing an audio stream, it gets sent to the default sink. Let’s change it to go from the current output to ‘hdmi-stereo’.
$ pactl list short sinks
0 alsa_output.pci-0000_05_00.1.hdmi-stereo module-alsa-card.c s16le 2ch 44100Hz SUSPENDED
1 alsa_output.pci-0000_00_1b.0.analog-stereo module-alsa-card.c s16le 2ch 44100Hz RUNNING
$ pactl set-default-sink 0
Moving existing sink inputs to another sink
If an application is already playing audio, it will not switch over to the new sink.
$ pactl list short sink-inputs
0 1 7 protocol-native.c s16le 2ch 44100Hz
// move sink input 0 to sink 1:
$ pactl move-sink-input 0 1
// alternatively:
$ pactl move-sink-input 0 alsa_output.pci-0000_00_1b.0.analog-stereo
GUI for the above operations
One of the more lightweight GUI solutions seems to be pavucontrol
.
Setting up equalizer
The modules may not be loaded. (Optionally verify with pactl list modules
.)
$ pactl load module-equalizer-sink
$ pactl load module-dbus-protocol
This creates a new sink.
Upstream documentation claims the equalizer should already set itself as the default. Existing sink inputs definitely didn’t move over to the new sink. I’m using Ubuntu 14.04; YMMV.
None of the arguments mentioned by upstream docs (sink_name=equalized master=alsa_output.pci-0000_00_1b.0.analog-surround-51 set_default=true
) worked for me. I would suspect they are simply post-trusty additions.
Instead, here’s my manual steps. (This could be more automated simply by using variables. Still, given that these are semi-educational notes, I’m opting for showing how to interpret outputs.)
// Find the ID of the first equalizer sink.
// If you suspect you may have more, skip everything after 'grep equalizer' and manually handle.
$ pactl list short sinks | grep equalizer | head -n1 | awk '{print $1;}'
4
$ pactl set-default-sink 4
$ pactl list short sink-input | awk '{print $1;}'
2
6
7
$ pactl move-sink-input 2 4
$ pactl move-sink-input 6 4
$ pactl move-sink-input 7 4
Adjusting equalizer settings using qpaeq
Qt PulseAudio Equalizer or qpaeq is available from PulseAudio source tree. For example, take it from a mirror on GitHub, make it executable and run it. (Before running it, of course, read through this code you’re grabbing from a random website on the Internet.)
$ wget https://raw.githubusercontent.com/pulseaudio/pulseaudio/master/src/utils/qpaeq
$ chmod 755 qpaeq
$ ./qpaeq
Dealing with issues
If something doesn’t go right, kill the PulseAudio daemon pulseaudio -k
. Your desktop environment is probably going to restart it by itself. Otherwise, something like nohup pulseaudio &
should probably help. Then, reload the modules.
Upstream docs also say you may want to disable tsched
, for example in /etc/default/pulse.pa
:
### Automatically load driver modules depending on the hardware available
.ifexists module-udev-detect.so
load-module module-udev-detect tsched=0
.else
### Alternatively use the static hardware detection module (for systems that
### lack udev support)
load-module module-detect tsched=0
.endif
I’m thinking, that may be also the right place for loading the equalizer and dbus module. Although, ~/.config/pulse/default.pa
may be an even saner one. Not sure yet.
Good luck!