This is an old question, so maybe you have already solved your problem. But in case you have not or in case others are running into this issue and not finding solutions which work for them (as was the case with me recently), here is another thing one can try.
This is mostly taken from the suggestion here, but slightly expanded/modified. It seems PulseAudio has a bug which can cause it to fail to automatically detect hdmi audio outputs ("sinks" in its language), so you can fix things by manually telling it about your hdmi device.
Step 1: Make sure PulseAudio hasn't detected your hdmi sink
You can list all sinks loaded into PulseAudio with pactl list short sinks
. This should produce a list of things of the form
0 alsa_output.pci-0000_06_00.6.HiFi__hw_Generic__sink module-alsa-card.c s16le 2ch 48000HzIDLE
If your hdmi audio does not show up in your list, then we may have found the problem, so keep reading. If you are not sure if it does or not, you can also run pactl list sinks | grep description
for more human-readable descriptions of the devices detected. I think hdmi sinks will have a description of the form "blah High Definition Audio Controller" while non-hdmi sinks might have a description like "blah blah blah Speaker + Headphone".
Step 2: Make sure your computer can output audio to hdmi
Run aplay -l
to get a list of hardware playback devices. For me, the output looks like
**** List of PLAYBACK Hardware Devices ****
card 0: NVidia [HDA NVidia], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 7: HDMI 1 [HDMI 1]
Subdevices: 0/1
Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 8: HDMI 2 [HDMI 2]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 9: HDMI 3 [HDMI 3]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 10: HDMI 4 [HDMI 4]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 11: HDMI 5 [HDMI 5]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: Generic [HD-Audio Generic], device 0: ALC245 Analog [ALC245 Analog]
Subdevices: 0/1
Subdevice #0: subdevice #0
In particular, there are many sorts of hdmi devices available. We want to find the one that actually corresponds to the hdmi port you have a cable plugged in to.
The first thing to do is to run alsamixer
to make sure your hdmi device isn't muted. You should see a screen like the one below.
Use F6
to select the correct sound card. If you see MM
in any of the slots, that means it's muted. Select it and press M
to unmute. Hit Esc
when you're done.
Really, you probably should only need to unmute one of these slots (the one actually associated with your hdmi port which is probably the first one), but it doesn't hurt to unmute them all.
With that taken care of, we can now test your audio. Run
speaker-test --channels 2 --test wav --device hw:[card],[device]
where [card],[device] refers to the numbers from the output of aplay -l
, e.g. I'd first use hw:0,3
. You'll do this for every hdmi hardware device listed previously until one of them actually produces an audible sound.
Step 3: Add HDMI sink to PulseAudio and make sure it works (can skip if you want)
Now that you have identified and card and device number associated to your hdmi port, simply run
pactl load-module module-alsa-sink device=hw:[card],[device]
You should now be able to go to your sound settings and see a new selectable output device (Mine's called TU116 High Definition Audio Controller
). Select it and see if your hdmi audio works now. If not, I can't help you. But if it does, congrats.
Step 4: Make this change (almost) permanent
At the moment, if you restart your computer, you'd have to rerun this load_module
command in order for hdmi to work again. To make things a little better, edit `/etc/pulse/default.pa' (as root), and near the end of the file, add the line
load-module module-alsa-sink device=hw:[card],[device]
After this (especially if you skipped step 3), you might want to run
rm -r ~/.config/pulse
killall pulseaudio
pulseaudio --start
to restart PulseAudio.
Lastly, a few hiccups/remarks
- For me, even after doing this, I still need to run
killall pulseaudio; pulseaudio --start
after rebooting my computer in order for PulseAudio to load in the hdmi sink. I don't know how to fix this.
- For me, the hdmi device is still listed as an option in Ubuntu's sound settings even when my cable isn't plugged in. I don't know how to fix this.
- The link from the beginning of this answer mentions a script for automatically switching to hdmi audio when a cable is plugged in. I don't know enough about linux to follow what's going on in that script, so I haven't tried this myself.
Edit: A Bash Script that Carries out this Answer
In response to the last bullet point above, I recently wrote a bash script that will automatically carry out the steps described here. You can find it on github. Compared to the script in the referenced link, the one I wrote (tries to) make fewer assumptions about the machine it is being run on; in particular, it does not assume PulseAudio has already (manually) been configured to detect your hdmi cable. If this has not happened, it runs the process described above, and then switches your audio to hdmi.
This script can be configured to run whenever your hdmi cable is plugged in or out by using udev. To do this, in the folder /etc/udev/rules.d
, add a file with the following line
KERNEL=="card*", SUBSYSTEM=="drm", ACTION=="change", RUN+="[path-to-script]"
(on my machine, I saved the script in /usr/local/bin/hdmi.sh
). After creating this file, run udevadm control --reload-rules
. Once you've done this, you should just be able to plug in an hdmi cable and have things work. When you unplug the cable, audio should switch back to your computer.
New hiccups/remarks
- You may need to restart your computer once after adding this udev rule for the first time before the change can take effect.
- If the udev rule is being iffy, you can always manually run the script. This is a bit more reliable if a bit more effort.
- For me, if I plug and unplug my hdmi cable like 5 times in a row without restarting, then the audio becomes extremely distorted. I have no idea what causes this.
- The script really is just carrying out the above process. In particular, at some point is runs
speaker-test
to figure out which card/device to load in PulseAudio. Thus, when run, you'll likely hear an audible "Left/Right" (or whatever sound speaker-test
defaults to).
- In the script, there's a
ENABLE_DESKTOP_NOTIFICATIONS
variable. Set this to 1 if you want notifications whenever it runs.