Change Audio Output to HDMI in the Terminal


Here's a way to change audio output to HDMI from within the terminal.

The Discovery

I've tried to do this for some time. The missing link was the fact that each sound card has profiles that define which of their inputs are used. HDMI is one such input.

Now... enjoy the journey.

List Sound Cards

A sound card in a computer is a device that converts digital signals to analog audio signals that a speaker can play.

Let's see what sound cards are available

aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC256 Analog [ALC256 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [BenQ EW3270U]
  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
card 0: PCH [HDA Intel PCH], device 9: HDMI 3 [HDMI 3]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

In this output, there is one card, "card 0". It has multiple "devices" listed. These represent audio ports on the sound card.

aplay doesn't show us all the details about these audio ports that we need. pactl list cards is what we want. It displays a ton of info, though, so get your eyes ready to parse output. For our purposes, I'll abbreviate and explain the output.

pactl list cards
Card #59
	Name: alsa_card.usb-046d_0821_A225DF90-00
    ...

Card #60
	Name: alsa_card.pci-0000_00_1f.3
	Properties:
		api.alsa.card = "0"
		api.alsa.card.name = "HDA Intel PCH"
		device.bus = "pci"
		device.description = "Built-in Audio"
    ...

Card #1072
	Name: bluez_card.B1_1F_25_16_95_95
    ...
	Properties:
        ...
		device.bus = "bluetooth"
    ...

There are three sound cards listed. One is the built-in audio card, another is a webcam (over usb, only with a mic) and finally, a bluetooth speaker.

Which one of these cards is the sound card of the computer, that HDMI is connected to? It's "Card #60". There are a few things to look for. Which one is built-in? These properties are indicative:

api.alsa.card = "0"
api.alsa.card.name = "HDA Intel PCH"
device.bus = "pci"
device.description = "Built-in Audio"

Common Intel hardware name. On the PCI bus. It even says "Built-in Audio". It also matches "card 0" in aplay -l. The fact that cards are numbered differently is not helpful. These are different IDs for the same device.

Change Audio Device Profile

Now we found the internal sound card. How do we get it to play over HDMI? The key is in Profiles. A profile defines which audio outputs the device will use, for either output (speaker) or input (mic). These profiles are set up like templates with different combinations of outputs and inp7uts.

Now we'll look at some of the pactl list cards output for Card #60 that I left out previously:

Profiles:
	off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
	output:analog-stereo+input:analog-stereo: Analog Stereo Duplex (sinks: 1, sources: 1, priority: 6565, available: yes)
	output:hdmi-stereo+input:analog-stereo: Digital Stereo (HDMI) Output + Analog Stereo Input (sinks: 1, sources: 1, priority: 5965, available: yes)
    ...
	output:hdmi-surround-extra1+input:analog-stereo: Digital Surround 5.1 (HDMI 2) Output + Analog Stereo Input (sinks: 1, sources: 1, priority: 665, available: no)
	input:analog-stereo: Analog Stereo Input (sinks: 0, sources: 1, priority: 65, available: yes)
	pro-audio: Pro Audio (sinks: 5, sources: 1, priority: 1, available: yes)
Active Profile: output:analog-stereo+input:analog-stereo

There are many configurations. How do I parse this?

  • First, Profiles are the choices on configuration. Active Profile is the one currently in use.
  • output: shows how the sound is output in that config. input: shows how sound is input.
  • analog-* means physical sound waves in the real world, like thumping speakers or yelling at your mic.
  • sink is output. source is input.
  • *-stereo means a two channel audio, like computer speakers or headphones. *-surround is going to set you up for watching Jurassic Park on your computer. Lucky.
  • available: yes means that an audio hardware device (like a speaker) is plugged into that port. Switching to this profile will lead to output going somewhere you can hear.

So, which do we want to switch to? The available HDMI that is the simplest and still allows mic use. That seems to be output:hdmi-stereo+input:analog-stereo.

To change the profile, use the alsa card number (60), with the profile name:

pactl set-card-profile 60 output:hdmi-stereo+input:analog-stereo

Now what audio outputs are available? Instead of what used to be there (analog-stereo), we see hdmi-stereo:

pactl list short sinks
1073	bluez_output.B1_1F_25_16_95_95.1	PipeWire	s16le 2ch 48000Hz	SUSPENDED
1193	alsa_output.pci-0000_00_1f.3.hdmi-stereo	PipeWire	s32le 2ch 48000Hz	SUSPENDED

Now set your audio output to use that device:

pactl set-default-sink alsa_output.pci-0000_00_1f.3.hdmi-stereo