In PulseAudio, each sound card has a profile set associated with it. A profile set contains multiple profiles, and those are the profiles that you see when listing the cards (or when looking in the various PulseAudio GUIs).
There is a default profile, which primarily contains things useful for analog sound output. There is also an extra-hdmi profile that is automatically applied to some HDMI outputs, and will give options up to 5.1. Both of these profiles are unfortunately in /usr/share/pulseaudio/alsa-mixer/profile-sets, and thus you can't really edit them (I filed Debug bug 736708 about this.) According to the documentation, you could disable udev-based autodiscovery, and manually configure everything—that let's you specify the full path to a profile. But it turns out, that while it isn't documented, udev can specify a full path, too.
Set up a udev rule to assign a profile set
You assign a profile set in a udev rule by setting the PULSE_PROFILE_SET udev environment variable. Its documented to only take a file in the aforementioned /usr subdirectory, but a full path works as well. In my case, I created this rule:
# cat /etc/udev/rules.d/95-local-pulseaudio.rules
ATTRS{vendor}=="0x8086", ATTRS{device}=="0x1c20", ENV{PULSE_PROFILE_SET}="/etc/pulse/my-hdmi.conf"
You will need to use the appropriate PCI vendor and device numbers, which you can easily obtain from lspci -nn.
After creating the udev rule, you can apply it immediately with udevadm trigger -ssound. You will probably want to rebuild your initramfs as well (update-initramfs -u)
Confirm that the udev rule took effect with udevadm info --query=all --path /sys/class/sound/card0 (use the appropriate card number, of course). You should see E: PULSE_PROFILE_SET=/etc/pulse/my-hdmi.conf in the output. If not, do not continue. It won't work. Something is wrong with your udev rules (or maybe you didn't trigger them—you could always try rebooting).
Create the /etc/pulse/my-hdmi.conf file
Note: The channel map is apparently system-specific. You'll need to experiment to get it right for your system. I was lucky, my 7.1 layout just involves dropping the final items to build 5.1, 4.0, etc. Instructions are below.
This is a lot of copy & paste, mostly. Each section differs in (a) name, (b) description, (c) channel map, (d) [optional] priority.
[General]
auto-profiles = yes
[Mapping hdmi-stereo]
device-strings = hdmi:%f
channel-map = front-left,front-right
description = Digital Stereo (HDMI)
priority = 4
direction = output
paths-output = hdmi-output-0
[Mapping hdmi-surround-40]
device-strings = hdmi:%f
channel-map = front-left,front-right,rear-left,rear-right
description = Digital Quadrophonic (HDMI)
priority = 1
direction = output
paths-output = hdmi-output-0
[Mapping hdmi-surround-51]
device-strings = hdmi:%f
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
description = Digital Surround 5.1 (HDMI)
priority = 2
direction = output
paths-output = hdmi-output-0
[Mapping hdmi-surround-71]
description = Digital Surround 7.1 (HDMI)
device-strings = hdmi:%f
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
priority = 3
direction = output
paths-output = hdmi-output-0
Now, to test this:
- Restart PulseAudio:
pulseaudio -k, as your normal user, assuming you're using per-user daemons (the default). Start it up again, even a simple aplay -l will work.
- Switch to the 7.1 profile. Personally, I used
pactl set-card-profile 0 "output:hdmi-surround-71" to do this, but a GUI will work perfectly well, too.
- Run
speaker-test -c 8 -t w. It should start announcing speaker names, hopefully the correct name out of each speaker. If it the names don't come from the correct speaker, you'll have to change the channel-map to get them right. After each channel map change, you must restart PulseAudio again.
Bonus! More useful settings
In /etc/pulse/daemon.conf, there are a few settings you may want to change:
enable-remixing — If this is on, a stereo signal will have its left channel played out of all three of your left speakers, and its right channel out of your right speakers. If off, it'll only come out the front two. Note that you can also change the profile to stereo (to only send stereo sound out the HDMI port, and let your receiver decide how to map it to speakers).
enable-lfe-remixing — Similar, but for remixing to the LFE (subwoofer) channel.
default-sample-format — If your HDMI setup supports greater than 16-bit audio, you may want to increase this to s32le (from the default s16le).
default-sample-rate, alternate-sample-rate — You may want to swap these (and maybe even disable 44.1KHz entirely) if you mostly use DVD-source material which is typically 48KHz. Or, if your HDMI receiver supports it, you can go all the way up to 192KHz. Note that 176KHz has the nice property of being an even multiple of both 44.1 and 48KHz. See below for how to determine what your receiver supports
default-sample-channels — Doesn't really seem to matter. Profile probably overrides it...
Naturally, you'll have to restart PulseAudio after changing this file.
Bonus Again! Seeing What Your Receiver Supports
There are eld.* files in /proc/asound which tell you what the other end of an HDMI link claims to support. For example:
# cat /proc/asound/card0/eld#3.0
monitor_present 1
eld_valid 1
monitor_name TX-SR606
connection_type HDMI
eld_version [0x2] CEA-861D or below
edid_version [0x3] CEA-861-B, C or D
manufacture_id 0xcb3d
product_id 0x863
port_id 0x0
support_hdcp 0
support_ai 1
audio_sync_delay 0
speakers [0x4f] FL/FR LFE FC RL/RR RLC/RRC
sad_count 8
sad0_coding_type [0x1] LPCM
sad0_channels 2
sad0_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
sad0_bits [0xe0000] 16 20 24
sad1_coding_type [0x1] LPCM
sad1_channels 8
sad1_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
sad1_bits [0xe0000] 16 20 24
sad2_coding_type [0x2] AC-3
sad2_channels 8
sad2_rates [0xe0] 32000 44100 48000
sad2_max_bitrate 640000
sad3_coding_type [0x7] DTS
sad3_channels 8
sad3_rates [0xc0] 44100 48000
sad3_max_bitrate 1536000
sad4_coding_type [0x9] DSD (One Bit Audio)
sad4_channels 6
sad4_rates [0x40] 44100
sad5_coding_type [0xa] E-AC-3/DD+ (Dolby Digital Plus)
sad5_channels 8
sad5_rates [0xc0] 44100 48000
sad6_coding_type [0xb] DTS-HD
sad6_channels 8
sad6_rates [0x1ec0] 44100 48000 88200 96000 176400 192000
sad7_coding_type [0xc] MLP (Dolby TrueHD)
sad7_channels 8
sad7_rates [0x1480] 48000 96000 192000
So you can see my receiver supports LPCM (Linear PCM, i.e., uncompressed audio) at up to 8 channels, 192KHz, 24-bit sound. It also supports AC3, DTS, DSD, DD+, DTS-HD, and Dolby TrueHD. So if I have files encoded in those, I can pass-through those formats (if my media player supports it, of course. mpv probably does).