Monday, July 25, 2016

[Solved] Arch ALSA configuration (HDMI, nVidia PCIe card) minus PulseAudio

$ xrandr [get displays]
$ xrandr --output HDMI1 --mode "1280x800"
$ xrandr --output HDMI1 --off

I currently maintain an unlucky system with respect to HDMI audio: two sound chips -- nVidia PCIe video card(w sound chip), and an Intel sound chip on the motherboard. One must choose between connecting the HDMI cable at the motherboard and having low-res motherboard chip video, or connecting the HDMI cable to the nVidia board. Of course, we connect the HDMI cable to the nVidia board for better video, but this then led (in my case) to conflicting motherboard and video card audio functions. This post is the result.


The system OS is Arch w/Nouveau drivers (minus proprietary nVidia modules), and without PulseAudio. Eventually, I removed the Nouveau drivers and reluctantly installed the proprietary nVidia drivers: the Nouveau drivers could not seem to manage the audio on the nVidia card.

Avoiding PulseAudio was successful -- the steps for that begin below. The steps are entirely accomplished inside Runlevel 2/3 or a terminal, but I included one optional Xorg step at the bottom of the post.

HDMI complexity

HDMI sound requires at least four reconciled systems -- Xorg, ALSA, kernel modules and, of course EDID -- and some of these have subfiles. That's too many variables for consistently easy sound configuration, and sound is already one of the more challenging aspects of Linux. One bit of Arch-specific luck is ALSA modules are nowadays compiled into the Arch kernel.

First steps

  • ALSA kernel modules present?
    $ systemctl list-unit-files |grep alsa
    alsa-restore.service static
    alsa-state.service static
    "Static", because compiled into the kernel. If not present, fundamental ALSA must be installed and the dynamic loading of its modules verified.
  • after the above, pacman all additional ALSA stuff in the repo, avoiding ALSA-PulseAudio libs (and other applications which automatically install PulseAudio) and, if feasible, also avoiding ALSA-OSS libs. Generally, the less non-ALSA audio libs the better.
  • verify (in an already-working system) one has a good HDMI cable and then connect it between the the nVidia card and one's desired monitor/TV. Once we connect to nVidia video, we're obviously committed to nVidia's sound chip (since HDMI cable carries both audio and video).
  • reboot
  • $ lsmod |grep soundcore :: soundcore must be present.

module load order --> default audio card

In a multi-card/chip sound system, the order the kernel loads the modules for the cards determines the default audio card. Specific to my system is an additional complexity: both the motherboard and nVidia audio chips load the same module, snd_hda_intel. This prevented me from determining which chip was the default sound chip with a simple module check...
$ cat /proc/asound/modules
0 snd_hda_intel
1 snd_hda_intel
Which card is the default "0", the motherboard chip or the nVidia card chip? Use ALSA's "aplay" to distinguish:
$ aplay -L |grep :CARD
default:CARD=PCH
sysdefault:CARD=PCH
front:CARD=PCH,DEV=0
surround21:CARD=PCH,DEV=0
surround40:CARD=PCH,DEV=0
surround41:CARD=PCH,DEV=0
surround50:CARD=PCH,DEV=0
surround51:CARD=PCH,DEV=0
surround71:CARD=PCH,DEV=0
iec958:CARD=PCH,DEV=0
hdmi:CARD=NVidia,DEV=0
hdmi:CARD=NVidia,DEV=1
hdmi:CARD=NVidia,DEV=2
hdmi:CARD=NVidia,DEV=3

ALSA has loaded the motherboard chip "PCH" as the audio default, which is not the NVidia audio we need (for HDMI audio). And a 3rd issue is apparent: a device designation of "0" is being used for both sound card/chips. These numbers are supposed to be unique for each card, but two cards are using the same number, "0". This may be related to the dual use of snd_hda_intel. Regardless of how it happened, dual-use of a (supposedly) card-specific number across two pieces of hardware is likely to lead to conflicts. If desired, one could detour and verify IRQ issues with say,lscpi -v, or get more information about the module, eg....

$ modinfo -p snd_hda_intel

...and do conflict tests. In my case, I made note of the overlap and pressed on.

So far: No sound yet, since default audio is going to PCH, not to nVidia. However there is progress: we know ALSA assigned unique names for the two audio chips -- "PCH" and "NVidia". We know both audio chips rely on module snd_hda_intel, that the PCH chip is loading as the default, that the nVidia chip has four available devices (0,1,2,3), and that a good HDMI cable has been connected between the nVidia HDMI port and my monitor. How to control the load order (default)?

Some users control load order problems by creating an /etc/moprobe.d/[somename].conf file, then setting options inside the file, or using creative blacklisting. This didn't work for me: both audio cards relied on the same module, snd_hda_intel so that blocking this module would block both cards (chips).

I tried however. I created the file...

# nano /etc/modprobe.d/customsettings.conf

...and attempted various "option" and "install" lines within it. Option and install lines have helped other users (see appendix at bottom), but none of them solved my problem. In the end, my only use for the custom file was to blacklist Nouveau modules, in case I had not removed all of them properly, after I had settled on nVidia drivers

# nano /etc/modprobe.d/customsettings.conf
blacklist nouveau

If kernel manipulation fails, we can turn to making modifications within ALSA. For ALSA customization,four ALSA files are possible:

  • /etc/modprobe.d/(somename).conf :: kernel manipulation, as just noted above.
  • /etc/asound.conf in Arch, the file does not exist by default, but can be created by apps (like PulseAudio) or by the user.
  • ~/asound.rc home directory version of asound/conf, if one does not desire global settings.
  • /usr/share/alsa/alsa.conf a default file, installed with ALSA. To narrow troubleshooting variables, I do any ALSA customization only in this default /usr/share/alsa/alsa.conf file. The first modification is to prevent the other two files above from being sourced. Some users simply delete /etc/asound.conf and ~/.asoundrc entirely or rename them to backup files. We need ELD information before we can modify this file entirely however.

ELD verfication

ELD information is critical to complete HDMI modifications inside /usr/share/alsa/alsa.conf. Be sure the HDMI cable is connected to the NVidia HDMI output and to the monitor to which you're connecting.
$ grep eld_valid /proc/asound/NVidia/eld*
/proc/asound/NVidia/eld#0.0:eld_valid 0
/proc/asound/NVidia/eld#0.1:eld_valid 1
/proc/asound/NVidia/eld#0.2:eld_valid 0
/proc/asound/NVidia/eld#0.3:eld_valid 0
Here, only nVidia audio card (chip) 1 is validated for HDMI audio. However, these "card" numbers 0,1,2,3, are not the actual hardware numbers. We need hardware numbers for ALSA.
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC892 Analog [ALC892 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 1: ALC892 Digital [ALC892 Digital]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: NVidia [HDA NVidia], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: NVidia [HDA NVidia], device 7: HDMI 1 [HDMI 1]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: NVidia [HDA NVidia], device 8: HDMI 2 [HDMI 2]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: NVidia [HDA NVidia], device 9: HDMI 3 [HDMI 3]
Subdevices: 1/1
Subdevice #0: subdevice #0
So, for HDMI 1, the ELD validated sound card/chip with my monitor, the hardware number will be hw:1,7. Now I can return to /usr/share/alsa/alsa.conf and make the necessary HDMI modifications.
# nano /usr/share/alsa/alsa.conf
defaults.ctl.card 1 #default 0
defaults.pcm.card 1 #default 0
defaults.pcm.device 7 #default 0
This means I've swapped the cards' default order from "0" to "1", and specified the ELD-authorized device by its hardware number, "7". Reboot, and unmute card PDIF 1 in alsamixer.
For non-NVidia cards, the process is similar...
$ grep eld_valid /proc/asound/HDMI/eld*
/proc/asound/HDMI/eld#0.0:eld_valid 0
/proc/asound/HDMI/eld#0.1:eld_valid 0
/proc/asound/HDMI/eld#0.2:eld_valid 0
/proc/asound/HDMI/eld#0.3:eld_valid 1
/proc/asound/HDMI/eld#0.4:eld_valid 0
... and then determine which setting is associated with ELD 3, using "$ aplay -l" again, and then making the change inside /usr/share/alsa/alsa.conf.

Next steps

  1. reboot
  2. power on the tv/monitor and verify volume is hearable level
  3. $ alsamixer :: unmute "S/PDIF 1" on the NVidia card. F6 switches between cards.
  4. $ aplay -D plughw:1,7 /usr/share/sounds/alsa/Front_Center.wav
    Should hear "Center" from TV's speakers. Aplay won't do MP3's to my knowledge -- use this ALSA player with a WAV.
  5. enjoy. I must manually unmute S/PDIF 1 each reboot, or modify some other file, but that's another day/process.

troubleshooting - post alsa update

Following any system update that changes ALSA, (eg, following pacman -Syu) sound may be lost. First, open alsamixer to verify it wasn't re-muted. Secondly, the update may have overwritten /usr/share/alsa/alsa.conf. Re-enter the modifications (scroll down) and device settings in alsa.conf, resave, and log out and back in, or reboot.

troubleshooting- vlc issues

1.) deleting ~.config/vlc as a fix. When sound comes OK from ALSA ($ aplay -D plughw:1,7 /usr/share/sounds/alsa/Front_Center.wav, as above), but VLC is soundless, try deleting~/.config/vlc, and let VLC respawn the file.

2.) no sound from media files with MP3 or AAC tracks. Movies and MP3's play with audio in other software, but no sound from VLC, if it's MP3 or AAC. The fail will appear to be ALSA, eg, if you attempt to VLC the MP3 file from the command line, you'll see errors including...

alsa audio output error: cannot set buffer duration: Invalid argument

... yet MP3's play fine with other players. Without PulseAudio, they are getting their input from ALSA, so we know it's not ALSA, it's VLC. The fix for me has been the SPDIF function, which sends audio directly to the device, without decoding, which it can't always handle. Make sure it's unchecked as seen below.



Incidentally, beneath the quality of lossless (flac and wav), apparently the compression quality proceeds: Opus better than AAC, with AAC better than MP3.

Nouveau

One of the sound cards is an nVidia graphics card.
$ nvidia-xconfig --no-use-edid-dpi $ nano /etc/X11/xorg.conf Option "DPI" "100 x 100"

appendix 1
possible /etc/moprobe.d/[somename].conf settings

At the kernel level, I was unable to do more than blacklist nouveau drivers. I could have instead blacklisted nvidia drivers, had I ever been able to activate sound within nouveau. However, many were able to solve their configuration settings in this file using such options as
install sound-slot-0 modprobe snd-card-1
install sound-slot-1 modprobe snd-card-0
or...
options snd-hda-intel enable=1,0
Note that, in this second example, the underscores in the module name are changed to hyphens.

appendix 2

If a person has old 32-bit Windows programs and wants to run Wine, what are the concerns? You'll first have to uncomment the two multilib lines in /etc/pacman.conf to access 32-bit libs. Wine itself then becomes roughly a 600MB kludge install due to all the attached 32-bit libs.

Most importantly here, one of the 32 bit choices affects the nVidia card. During Wine install, users must select either the lib32-mesa-libgl or lib32-nvidia-gl. I have th nVidia card in my system, so it seems like the safe choice. What about compatibility though? So many things use Mesa.

3 comments:

lhoqvso said...

I really would like to thank you for this article. Perfectly explained. Much appreciated :)

pangolinpork said...

Only error -- and it's a big one -- is your claim that: 'device' numbers may not overlap." NOT TRUE
Look at any alsa setup with multiple cards, and the devices will typically start at 0. (but sometimes they do not). It's normal to see different cards with an identical series of device numbers, just like different streets can have houses numbered 4, 5, 6...

There is no conflict when both card 0 and card 1 both have a "device 0".. the device is a subcategory of card...

xbasket said...

@lhoqvso - thanks. Info sharing seems to save sanity during these types of issues.

@pangolinpork - good catch. I changed the one (I hope) typo where I'd written "device" where I meant "card". Can you provide/explain a faster solution to this dual chip problem? Post it up here or drop us a link. Thx.