How do I configure PulseAudio for 7.1 Surround Sound over HDMI?

I have my machine connected over HDMI to a receiver. But when I try to use more than two channels with PulseAudio, I only get two. pacmd list cards shows the card, but does not show an HDMI profile with more than two channels.

I have confirmed that 7.1 sound works via ALSA:

pasuspender -- speaker-test -D hdmi -c 8 -m FL,FC,FR,RR,RRC,RLC,RL,LFE

Produces static that goes around the room.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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:

  1. 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.
  2. 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.
  3. 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).


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x