Sunday, September 10, 2023

[Solved: 7 hours] reliable HDMI configuration under PulseAudio

NB: solution only takes 20 mins, but it took me an entire NFL Sunday to troubleshoot. All of this is only if the pavucontrol box cannot be expanded to include "Configuration" or nothing is there.


As we know, PulseAudio is one of the worst solutions to a non-problem1 ever devised. It's so blatantly unhelpful that I suspect the two prior, more reliable and configurable, sound systems -- OSS and ALSA -- might have been sunk by DMCA (the usual supsect in crippled media reliability). Eg, are there any OSS drivers for newer hardware? Is there any documentation about inscrutable ALSA subroutine calls? We have little choice but to live with PulseAudio these days unless we're willing to fund a project to document ALSA or update OSS drivers.

two problems, two solutions

Problem 1: HDMI cable is disconnected, no sound in host

The HDMI cable is connnected and audio is coming from the monitor. But if I disconnect the HDMI cable, audio ceases entirely instead of switching/returning to the laptop speakers. So I lose audio entirely when I disconnect the HDMI cable.

I open pavucontrol. I see this...

  1. no sound from monitor of course, b/c HDMI cable is disconnected
  2. it appears there are menu options for "Port" but "HDMI/DisplayPort Unplugged" is the only option. The arrow produces no options to return sound to speakers.
  3. re-attaching the HDMI cable only randomly results in a return to a picture and sound at the monitors

solution

Port options are available but are hidden. Click the arrow circled in red to reveal an additional column, "Configurations".

Within "Configuration" (below), we can select different options in the drop-down menu of "Profile" ("Port" above only gave a false appearance of options). When I selected "Analog Stereo Output", audio returned to my laptop speakers.

Problem 2: HDMI cable is reconnected, no sound in monitor

Typically, our speaker audio will also stop when we reconnect the HDMI cable, so that we're once again entirely without audio. But this was a more complex problem to solve.

What worked for me was to gather device info and insert it into /usr/share/alsa/alsa.conf to make it less generic. During reconnection, my default configuration seemed unable to distinguish the correct hardware. It might have been too vague.

I first examined the HDMI connection in light of two programs.

part A -- gather aplay and xrandr info

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC3235 Analog [ALC3235 Analog]
Subdevices: 0/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 7: HDMI 1 [HDMI 1]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 8: HDMI 2 [HDMI 2]
Subdevices: 1/1
Subdevice #0: subdevice #0
$ xrandr
eDP1 connected primary 1366x768+0+0 (normal left inverted right x axis y axis) 280mm x 160mm
DP1 disconnected (normal left inverted right x axis y axis)
HDMI1 connected (normal left inverted right x axis y axis)
HDMI2 disconnected (normal left inverted right x axis y axis)
VIRTUAL1 disconnected (normal left inverted right x axis y axis)
So we can see that HDMI1, which is hw 0,7 in this system, is the subdevice we want to configure.

part B -- modify /usr/share/alsa/alsa.conf

Use the HDMI1 information gathered above to add subdevice 7 (in this case) into the alsa control file.

# nano /usr/share/alsa/alsa.conf
defaults.ctl.card 0
defaults.pcm.card 0
defaults.pcm.device 0
defaults.pcm.subdevice 7

Now when we reboot our system, and connect and reconnect HDMI cables, we should see the option (as in "1" above) in pavucontrol, AND we should see that we have an ELD handshake.

$ grep eld_valid /proc/asound/card0/eld*
/proc/asound/card0/eld#2.0:eld_valid 1
/proc/asound/card0/eld#2.1:eld_valid 0
/proc/asound/card0/eld#2.2:eld_valid 0
/proc/asound/card0/eld#2.3:eld_valid 0
/proc/asound/card0/eld#2.4:eld_valid 0
/proc/asound/card0/eld#2.5:eld_valid 0
/proc/asound/card0/eld#2.6:eld_valid 0
/proc/asound/card0/eld#2.7:eld_valid 0
/proc/asound/card0/eld#2.8:eld_valid 0

additional notes

Never works

This is a good page, however none of these work:
$ pacmd "set-default-source alsa_output.pci-0000_04_01.0.analog-stereo.monitor"
$ pacmd "set-default-sink alsa_output.pci-0000_04_01.0.analog-stereo.monitor"

slight digression

In addition to our ears, we can verify a successful EDID handshake between our laptop and the monitor (via the HDMI cable). With the HDMI cable plugged in, we have a valid HDMI connection wherever we have a "1" inside /proc/sound/. When there's no sound, it will be all zeros, such as this example...

$ grep eld_valid /proc/asound/card0/eld*
/proc/asound/card0/eld#2.0:eld_valid 0
/proc/asound/card0/eld#2.1:eld_valid 0
/proc/asound/card0/eld#2.2:eld_valid 0
/proc/asound/card0/eld#2.3:eld_valid 0
/proc/asound/card0/eld#2.4:eld_valid 0
/proc/asound/card0/eld#2.5:eld_valid 0
/proc/asound/card0/eld#2.6:eld_valid 0
/proc/asound/card0/eld#2.7:eld_valid 0
/proc/asound/card0/eld#2.8:eld_valid 0

If the HDMI cable is connected and we see the above, then either the cable is bad, or the computer is failing to detect that there's a good HDMI cable connection.

Either way, we should have sound in our (eg laptop) speakers in such cases. So back to our main story.

Sometimes works

This sometimes works to add a way to toggle between analog speakers and digital HDMI, with both plugged-in. Sometimes.

# nano /etc/pulse/default.pa
### Load analog device - must be first
load-module module-alsa-sink device=hw:0,0
load-module module-combine-sink sink_name=combined
set-default-sink combined

a few helpful commands

$ pulseaudio --kill
# alsactl restart

1 Both OSS and (subsequently) ALSA worked fine, but they needed more development as time progressed. Unfortunately, neither had enough DMCA protections to please the patent trolls. Enter PulseAudio, the *solution*, with the plausible patent deniability that it was designed to work "across platforms" LOL.