Today I finally managed to get lossless HD audio working from my Linux media PC over HDMI! I’ll probably update this post as time goes, but for now it’s a quick recipe of what I did:
Configure a PulseAudio ALSA sink to use the HDMI output
Video cards present HDMI audio interfaces in an interesting way. There appears to be one audio device per digital display connector on the GPU (yes, you really can transport audio over a DVI connector!). For some reason, sending audio to any of the output devices on the GPU will work – although you only get two channels unless you select the correct device! I suspect this is related to buffer sharing amongst the output devices, but I digress…
To find the correct output device, run a few iterations of
speaker-test -c8 -twav -D[hdmi:CARD=NVidia,DEV=3]
replacing the part in square brackets with an available output as shown by
Here’s a sample of what the aplay output looks like on my system:
media@ro ~ $ aplay -L null Discard all samples (playback) or generate zero samples (capture) pulse PulseAudio Sound Server sysdefault:CARD=PCH HDA Intel PCH, ALC892 Analog Default Audio Device front:CARD=PCH,DEV=0 HDA Intel PCH, ALC892 Analog Front speakers surround40:CARD=PCH,DEV=0 HDA Intel PCH, ALC892 Analog 4.0 Surround output to Front and Rear speakers surround41:CARD=PCH,DEV=0 HDA Intel PCH, ALC892 Analog 4.1 Surround output to Front, Rear and Subwoofer speakers surround50:CARD=PCH,DEV=0 HDA Intel PCH, ALC892 Analog 5.0 Surround output to Front, Center and Rear speakers surround51:CARD=PCH,DEV=0 HDA Intel PCH, ALC892 Analog 5.1 Surround output to Front, Center, Rear and Subwoofer speakers surround71:CARD=PCH,DEV=0 HDA Intel PCH, ALC892 Analog 7.1 Surround output to Front, Center, Side, Rear and Woofer speakers iec958:CARD=PCH,DEV=0 HDA Intel PCH, ALC892 Digital IEC958 (S/PDIF) Digital Audio Output sysdefault:CARD=pcsp pcsp, pcsp Default Audio Device front:CARD=pcsp,DEV=0 pcsp, pcsp Front speakers hdmi:CARD=NVidia,DEV=0 HDA NVidia, HDMI 0 HDMI Audio Output hdmi:CARD=NVidia,DEV=1 HDA NVidia, HDMI 1 HDMI Audio Output hdmi:CARD=NVidia,DEV=2 HDA NVidia, HDMI 2 HDMI Audio Output hdmi:CARD=NVidia,DEV=3 HDA NVidia, HDMI 3 HDMI Audio Output
Turns out the correct device on my system is hdmi:CARD=NVidia,DEV=3. Piece of cake! The hard part is over, right? It is if you’re a PulseAudio guru… which I’m not. After wading around some forums and delving into man pages for a few hours, here’s what I found solved the issue:
Add this line to /etc/pulse/default.pa to create the new sink:
load-module module-alsa-sink device=hw:2,7 rate=192000 channels=8 tsched=0 sink_properties=device.description=HDMI sink_name=HDMI channel_map=front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
Also, you’ll want to comment out the lines that automatically load other modules. Find the lines below and insert a pound sign to disable them:
#load-module module-udev-detect #load-module module-detect
Now that the sink is created, configure output settings and sample rates for any PulseAudio instances!
Configure PulseAudio Defaults
Edit the file /etc/pulse/daemon.conf and add a block like this to the end:
default-sample-channels = 8 default-sample-rate = 192000 enable-remixing = no enable-lfe-remixing = no flat-volumes = no resample-method = src-sinc-best-quality
A little explanation is in order – here’s what those parameters do:
- default-sample-channels – Informs PulseAudio clients that they should prefer 8 channel streams. The default is 2, which is rather bland when you’ve got 6 to spare!
- default-sample-rate – Informs PulseAudio clients that they should prefer 192,000kHz sample rate, which sounds spectacular. (Sometimes considered “studio quality”!) Be aware that a lot of audio equipment won’t support this sample rate. If yours doesn’t, try 96000 or 48000 instead.
- enable-remixing – Disables (or enables) up- and down-mixing of source streams. This means that a 2-channel stream would be up-mixed to 7.1 channels, or a 32-channel stream would be down-mixed to 8 channels. I disable this because there is too much bass when a 2-channel signal is duplicated to 7 channels. You should test it both ways to see which you prefer. (I’m hoping a future version of PulseAudio will give more control over this functionality, I’d really like to up-mix post-processed signals with the low end removed to avoid this problem!)
- enable-lfe-remixing – Basically the same as enable-remixing but PulseAudio will pull the low end of all played channels and route it to the lfe channel. Essentially useless on any system that has crossover functionality in the DSP. (Of course, this might be useful for analog outputs but who does that anymore?)
- flat-volumes – Causes PulseAudio to adjust the output volume for a particular sink to the highest of all the sources on that sink. I disable this because it’s frustrating for the output volume to change when I don’t expect it.
- resample-method – Selects what method PulseAudio will use to resample sources on playback. The default is probably okay, but I prefer to use the highest quality option for my home theatre application. You can see what methods are available by running pulseaudio –dump-resample-methods.
Now that PulseAudio is configured, you can test the setup by running
speaker-test -c8 -twav
Assuming everything is in order, sit back and enjoy! Any application using PulseAudio for output will understand that 8 channels are available and should output properly.