Showing posts with label hdmi. Show all posts
Showing posts with label hdmi. Show all posts

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.

Monday, February 21, 2022

[solved] pulseaudio complete, minimal, and cripple installs

Even though "solved", it's really a failure, a failure to avoid PulseAudio After 2 week's work down the drain (see prior post) attempting to eliminate PulseAudio and, at this point, I have to get back to my life. I had a good plan but what ultimately defeated it is ALSA's latest complication of run-time language interactions with /usr/share/alsa/alsa.conf. For me to reverse engineer the many C++ attribute and function calls to the libalsa binary would take me a year to understand and document. They've finally made ALSA impossible. All that ever needed to happen in Linux audio was for OSS to be further developed 15 years ago, but that's probably a DRM casualty of some sort.

At any rate, I did manage to at least cripple PulseAudio so this is what I'll deal with first. With a couple of segues to failures even within the cripple process. Linux sound, man....

Cripple PA

In the simplest 3-step terms...

1. install libpulse normally

Alternatively, simply install one (eg. ffmpeg) of the now tens of programs that check for PulseAudio as a dependency! Lol, but we can see it is now a dependency if we try to *remove* PulseAudio...

2. symlink libpulse binaries to /dev/null

Other than for Google applications (eg, Chromium), PulseAudio is not technically a dependency. Rather applications verify PulseAudio's presence but do not need to use it. Accordingly, we can leave PulseAudio libraries in place, and symlink them to /dev/null. The libraries pass applications' tests for their presence, but do not interfere with our OS, since they are linked to nothing. So...

ln -sf /dev/null /usr/lib/libpulse.so
ln -sf /dev/null /usr/lib/libpulse-simple.so
ln -sf /dev/null /usr/lib/libpulse-mainloop-glib.so
...but leave these two alone...
/usr/lib/pulseaudio/libpulsedsp.so
/usr/lib/pulseaudio/libpulsecommon-15.0.so
These last are left as-is due to Chromium. During each start-up, Chromium checks for the size of at least one of these two libraries. Since /dev/null is "0" in size, Chromium will fail to start-up if, say common-15 is linked to /dev/null.

3. enjoy with one caveat

With this configuration, I've never had the pulse daemon auto-spawn, nor had my ALSA configurations overwritten (unless upgrading ALSA directly), nor had failures inside multi-media applications. This includes ffmpeg, OBS, vlc, Chromium, Ocenaudio, and the standard ALSA apps.

HOWEVER. At one point I broke/unlinked /dev/null from these three libs above to see what would happen. The delinking went smoothly, eg...

ln -sf /usr/lib/libpulse-sismple.so.0 /usr/lib/libpulse-simple.so
...yet the results were suboptimal. That's because /dev/null does not operate like other files, and it was deleted along with the symlink. Then, without /dev/null in the OS, I encountered random operational failures by applications which rely upon its presence.

So, in cases where I have to delete the symlinks, I:
  1. reinstall libpulse. # pacman -S libpulse.
  2. restart. during every startup, the kernel propagates /dev/null wherever needed in the system.

apulse - another failure

Apulse is on the AUR and looked promising. It emulated PulseAudio to placate applications which called PulseAudio, and even installs a small libpulse dummy which might do the same /dev/null moves I did above manually.

Although apulse installed fine and I was able to go back to ALSA I was still stuck with the problem that, eg, obs-studio could not detect my ALSA devices. For those without multi-media requirements such as those of obs-studio, apulse might be a solution.

jack? no

Not unless a dedicated machine for recording. Otherwise too many apps require PA. Two things learned when installing JACK however: stackex: change output card, and requires PAM modification, as I describe in this post.

complete PA install

Running as a user, pactl and pacmd are your friends, and the file ~/.config/pulse/client.conf. There's also more here, and also Arch's T-Shooting Guide. A typical issue are multiple cards detected in ALSA, but not by PA. You'll also want to clean out logs.

Is PA installed and running? Even though it's not technically a daemon (see below), it's usually running at starup from some unknown spawner. Check alsamixer and see if it's been superseded by PulseAudio's single volume bar.

After changes to any setup, we can restore ALSA with...

# systemctl restart alsa-restore.service
...and PulseAudio (for changes, kill it first, then restart it) with...
$ pulseaudio -k
$ pulseaudio -D

As noted here, PulseAudio is typically not a running service nor daemon from startup. Programs call it on a per-use basis. Some applications, eg Chromium, operate with a minimal /usr/bin/libpulse. Cleanest minimal install for pa_context_connect calls (basic libpulse install enough otherwise). I'm not sure, but to stream (eg. OBS), pulseaudio-rtp (only 200Kb) might be added.

# pacman -S pulseaudio-alsa

Packages (3) alsa-plugins-1:1.2.6-3 pulseaudio-15.0-4 pulseaudio-alsa-1:1.2.6-3

Total Download Size: 1.25 MiB
Total Installed Size: 6.19 MiB
Optional dependencies for alsa-plugins
dbus: for maemo plugin [installed]
jack: for pcm_jack plugin [installed]
libavtp: for pcm_aaf plugin [installed]
libsamplerate: for rate_samplerate plugin [installed]
libpulse: for conf_pulse, ctl_pulse and pcm_pulse plugins [installed]
speexdsp: for pcm_speex and rate_speexrate plugins [installed]
ffmpeg: for pcm_a52 plugin [installed]

pavucontrol

For ease of selecting devices (recording, streaming). It's big however, due to dependencies.
# pacman -S pavucontrol

Packages (7) atkmm-2.28.2-2 cairomm-1.14.3-2 glibmm-2.66.2-1 gtkmm3-3.24.5-2 libsigc++-2.10.8-1 pangomm-2.46.2-1 pavucontrol-1:5.0-1

Total Download Size: 2.95 MiB
Total Installed Size: 18.63 MiB

detection issue

configuration files

/etc/pulse/default.pa [detection issues]
/etc/pulse/client.conf [autospawn]
~/.config/pulse/client.conf

Wednesday, February 16, 2022

[FAIL] ALSA, JACK, 2 x cards, no pulseaudio

Basically, it doesn't matter what a post is originally about. If it includes any sound portion, it will end up being pages long attempting to deal with PulseAudio -- attempts to keep it out, to control or limit it, or to circumvent it. Unless you are a retiree with at least a full year's free time, install PulseAudio. The three biggest failures which lead to a full PulseAudio install:

  1. pa_context_connect() calls from an application. These require a full PulseAudio install, not just libpulses.
  2. ALSA developer's decision to add runtime calls (in C++?) into the libalsa binary. OK within itself, but falls apart when it accesses the configuration file /usr/share/alsa/alsa.config. The configuration used to be a plain text file. Now it has to include named variables to respond to libalsa's runtime calls. Documentation is poor and would require a year of full-time work by a user to reverse engineer.
  3. multiple sound cards. If we still had a purely text ALSA config, without runtime calls, might be OK. But with runtime added, an inflexible default must be specified. This limits access to functionality from the other cards needed for eg, HDMI/ELD.

ALSA issues

Can we shrink our ALSA configuration to make it simpler to overlay JACK? Let's try some changes. To restart ALSA after changes....
# systemctl restart alsa-restore.service

1. capture (recording)

$ arecord -l
**** List of CAPTURE 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 2: ALC892 Alt Analog [ALC892 Alt Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0

*using alsa and jack over pulseaudio (10:42) Nomad Studio, 2016. About 8:00 describes using apulse on PulseAudio apps.


2. cards

$ cat /proc/asound/cards
0 [PCH ]: HDA-Intel - HDA Intel PCH
HDA Intel PCH at 0xf7f30000 irq 40
1 [HDMI ]: HDA-Intel - HDA ATI HDMI
HDA ATI HDMI at 0xf7e60000 irq 41

2. devices

Card 0 w/ 4 devices, Card 1 w/5 HDMI output devices...
$ ls -l /dev/snd
total 0
drwxr-xr-x 2 root root 80 Feb 15 17:46 by-path
crw-rw----+ 1 root audio 116, 14 Feb 15 17:46 controlC0
crw-rw----+ 1 root audio 116, 8 Feb 15 17:46 controlC1
crw-rw----+ 1 root audio 116, 13 Feb 15 17:46 hwC0D0
crw-rw----+ 1 root audio 116, 7 Feb 15 17:46 hwC1D0
crw-rw----+ 1 root audio 116, 10 Feb 15 17:46 pcmC0D0c
crw-rw----+ 1 root audio 116, 9 Feb 15 17:46 pcmC0D0p
crw-rw----+ 1 root audio 116, 11 Feb 15 17:46 pcmC0D1p
crw-rw----+ 1 root audio 116, 12 Feb 15 17:46 pcmC0D2c
crw-rw----+ 1 root audio 116, 6 Feb 15 17:46 pcmC1D10p
crw-rw----+ 1 root audio 116, 2 Feb 15 17:46 pcmC1D3p
crw-rw----+ 1 root audio 116, 3 Feb 15 18:23 pcmC1D7p
crw-rw----+ 1 root audio 116, 4 Feb 15 17:46 pcmC1D8p
crw-rw----+ 1 root audio 116, 5 Feb 16 03:40 pcmC1D9p
crw-rw----+ 1 root audio 116, 1 Feb 15 17:48 seq
crw-rw----+ 1 root audio 116, 33 Feb 15 17:46 timer

3. modules

$ lsmod |grep snd
snd_seq_dummy 16384 0
snd_seq 90112 1 snd_seq_dummy
snd_seq_device 16384 1 snd_seq
snd_hda_codec_realtek 163840 1
snd_hda_codec_generic 98304 1 snd_hda_codec_realtek
snd_hda_codec_hdmi 81920 1
ledtrig_audio 16384 1 snd_hda_codec_generic
snd_hda_intel 61440 0
snd_intel_dspcfg 32768 1 snd_hda_intel
snd_intel_sdw_acpi 20480 1 snd_intel_dspcfg
snd_hda_codec 180224 4 snd_hda_codec_generic,snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec_realtek
snd_hda_core 114688 5 snd_hda_codec_generic,snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec,snd_hda_codec_realtek
snd_hwdep 16384 1 snd_hda_codec
snd_pcm 163840 4 snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec,snd_hda_core
snd_timer 45056 2 snd_seq,snd_pcm
snd 126976 10 snd_hda_codec_generic,snd_seq,snd_seq_device,snd_hda_codec_hdmi,snd_hwdep,snd_hda_intel,snd_hda_codec,snd_hda_codec_realtek,snd_timer,snd_pcm
soundcore 16384 1 snd

default problems

Soundcard 0 has analog capture (mic) and playback (speaker, headpone) channels. Card 1 only plays back but it's a necessary card because has digital(HDMI) connection. So, I must capture through 0 and playback through 1. But how?
  • HDMI playback only works when Card 1 is the default ALSA card
  • Recording only works when Card 0 is the default ALSA card
  • Unable to dynamically change default card(s) using amixer (cset cget)
  • ALSA now includes run-time programming language in its config file (alsa.conf). Learning the ALSA library variables and commands necessary for config file (one year's work)
  • OBS detects audio devices only via JACK or PulseAudio, not ALSA

HDMI playback verfied

$ aplay -D plughw:1,9 /usr/share/sounds/alsa/Front_Center.wav

5. current sound configuration

All configuration files deleted except /usr/share/alsa/alsa.conf. I have an "audio" group with myself as a member in /etc/group.

hardware and ELD HDMI detection

Changing ALSA configurations has no effect on items 1-3 above or the ELD/HDMI connection. ALSA is now installed with the kernel as systemd modules -- its functions are upstream of our user-level configuration. ELD handshakes automatically if the HDMI cable is connected and both items are powered-on. ELD verification is simple: find the device with the "1":

$ grep eld_valid /proc/asound/HDMI/eld*

complete alsa.conf

Only one configuration file is necessary to configure ALSA at the user level, /usr/share/alsa/alsa.conf; all other configuration files may be deleted. However a complete alsa.conf is roughly 600 lines and has eight sections; HOOKS, DEFAULTS, PCM, CONTROL, RAW MIDI, SEQUENCER, HW DEPENDENCE, and TIMER. Furthermore, in 2022 these include run-time function calls to the libs which have a somewhat elaborate syntax. I find the 2022 version a kludge.

smallest alsa.conf

What then is the smallest ALSA configuration? I've gotten ALSA working normally with only about 120 lines: a DEFALUTS, small PCM (below), and CONTROL interface sections.

#
# ALSA library configuration file
# permissions are 644

# PCM interface

pcm.capture1 {
type hw
card 0
device 0
}
pcm.capture2 {
type hw
card 0
device 2
}
pcm.hdmi8 {
type hw
card 1
device 8
}
With this I could, eg, record with explicit commands.
]$ arecord -D capture1 test.wav
However, since ALSA installs muted, this wasn't enough for me. I want alsamixer so I can easily unmute, set levels, select outputs. After a few days' work, in order not to deconstruct every run-time function for a customized version, I reluctantly settled on the original 600 line configuration file. For now.

alsa.conf sites

The alsa.conf is fun and time consuming to play with, and I might do it again. Documentation was sparse however. I gleaned from several sites.

Again, we want a JACK connectioin to Card 0, but not make it the system default. Alternatively, we might, if possible make Card 0 the default, but configure card 1 as an HDMI hook.

jack install overview

First you want the smallest possible ALSA configuration. Least elaborate and simple. A default card is required for JACK can be pared down and the problems are few, some due to PAM's typical interference. Capture is more complicated than playback, so we can test our permissions first on card 1. Once we get a basic configuration, we'll get card 1 going then tweak the more finnicky capture settings until card 0 is able to detect and input a mic.

jack install

I typically install jack2, alsa-plugins, jack-example-tools for multi-card, libffado (less error messages), and qjackctl for a GUI.

basic setup

  1. verify there's an "audio" group and the user is in it. Jump to Step 2. Otherwise, create the group "audio" and add the user
    # groupadd audio
    # usermod -a -G audio user
  2. modify PAM memory permissions to group "audio" in /etc/security/limits.conf, for real-time audio processing.
    # nano /etc/security/limits.conf
    @audio - rtprio 95
    @audio - memlock unlimited
    Verify: logout, log back in, and then...
    $ ulimit -r
    ...should see "95"
  3. determine location of $ qjackctl called on command line.
    $ strace qjackctl
    You might have to save it to a file since so much crap will scroll.
    $ strace qjackctl 2>&1 | tee file.txt
    We only care about the first line in the tens of thousands of lines in the file.
    execve("/usr/bin/qjackctl", ["qjackctl"]....
  4. give audio group permissions to qjackctl and jackd2 and make it group executable (750).
    # chgrp audio /usr/bin/qjackctl
    chmod 750 /usr/bin/qjackctl
    chgrp audio /usr/bin/jackd
    chmod 750 /usr/bin/jackd

first verification - playback only (card 1)

$ jackd -d alsa -d hw:1
jackdmp 1.9.20
Copyright 2001-2005 Paul Davis and others.
Copyright 2004-2016 Grame.
Copyright 2016-2021 Filipe Coelho.
jackdmp comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions; see the file COPYING for details
jack_get_descriptor : dll
jack_get_descriptor returns null for 'jack_internal_metro.so'
no message buffer overruns
no message buffer overruns
jack_get_descriptor : dll
jack_get_descriptor returns null for 'jack_inprocess.so'
jack_get_descriptor : dll
jack_get_descriptor returns null for 'jack_intime.so'
no message buffer overruns
JACK server starting in realtime mode with priority 10
self-connect-mode is "Don't restrict self connect requests"
audio_reservation_init
Acquire audio card Audio1
creating alsa driver ... hw:1|hw:1|1024|2|48000|0|0|nomon|swmeter|-|32bit
ALSA: Cannot open PCM device alsa_pcm for capture. Falling back to playback-only mode
configuring for 48000Hz, period = 1024 frames (21.3 ms), buffer = 2 periods
ALSA: final selected sample format for playback: 32bit integer little-endian
ALSA: use 2 periods for playback

So JACK starts for playback, albeit with some probable PulseAudio garbage errors. However, the error message, "Cannot open PCM device alsa_pcm for capture" will cause a fatal error when attempting to capture, using Card0 next paragraph. What is alsa_pcm and where do we configure alsa_pcm to open for capture? These are likley to be tweaks inside of /usr/share/alsa/alsa.conf. If so, not trivial.

initial capture attempt (card 0)

We need to capture microphone, which can only be done on Card 0.
$ jackd -d alsa -d hw:0
jackdmp 1.9.20
[snip]
Acquire audio card Audio0
creating alsa driver ... hw:0|hw:0|1024|2|48000|0|0|nomon|swmeter|-|32bit
ALSA: Cannot open PCM device alsa_pcm for playback. Falling back to capture-only mode
Released audio card Audio0
audio_reservation_finish
Cannot initialize driver
JackServer::Open failed with -1
Failed to open server

Fail. PCM device alsa_pcm has no playback -- no problem, we don't need playback with Card 0. However, we also receive a capture-only mode failure. Jackd exits. This is large problem: we need Card 0 for mic input capture. So two things are different, we're on Card 0 and we need capture.

alsa.conf

Card 1 was detected, possibly because Card 1 is the default card inside alsa.conf. We want to leave the default configuration on Card 1 (needed for HDMI output), but specify Card 0 for JACK detection, capture only. Here is the relevant Card 1 information for HDMI/ELD detection.

defaults.ctl.card 1
defaults.pcm.card 1
defaults.pcm.device 9
defaults.pcm.subdevice -1
defaults.pcm.nonblock 1
### start - custom for JACK pcm.jack1 { type hw card 0 device 0 } pcm.jack2 { type hw card 0 device 2 } ### end - custom for JACK
pcm.plug0 {
type plug
slave {pcm "jack" }
}
}
pcm.jack {
type jack
slave { pcm "jack" }
playback_ports {
0 alsa_pcm:playback_1
1 alsa_pcm:playback_2
}
capture_ports {
0 alsa_pcm:capture_1
1 alsa_pcm:capture_2
}

Sunday, December 22, 2019

video card replacement - hdmi

Although it looks imposing and is potentially a solid choice, I became tired (2019) of the 2Gb nVidia GeForce GTX770 (GK104 Audio Controller onboard) that came with my system.
Maybe it's an nVidia thing, but it had the nasty habit of ramping-up sound instead of turning audio on immediately. This meant that, after any silence, sound always returned smoothly, however it made video editing impossible. Sound needs to match video precisely and, since we're not going to play back video on only this nVidia system, we need to know volumes exactly, not with system-specific audio ramping.

nVidia vs Radeon

According to the proprietary utility nvidia-settings (in the nVidia driver), my motherboard has a PCIe Gen3(16bit) slot. I'm not a gamer, but for Blender's sake, I doubled GPU RAM with a 4Gb Polaris based AMD Radeon RX560D.
Again, however, the main factor is having audio that works correctly. There was simply nothing I could do to stop the nVidia card audio ramping. All automuting, all of that was disabled, but the nVidia sound always ramped instead of immediate.

Remove nVidia software

Once replaced, i uninstalled the nVidia module in favor of amdgpu module.It's just sitting there and not being used so it doesn't really hurt anything, but it's a 200Mb of orphaned stuff. I ran # pacman -Ss nvidia to see what I had installed and removed all of them...
# pacman -Rdd libvdpau libxnvctrl nvidia nvidia-utils

audio

When I had the nVidia card, I was never able to pass the dreaded same-named sound card issue...
$ cat /proc/asound/modules
0 snd_hda_intel
1 snd_hda_intel
...which would sometimes provide sound and sometimes static.

libva v libvdpau

I still don't understand if I'm supposed to have both the Intel and the nVidia video hardware acceleration. I knew that va was intel and vdpau nVidia, so which/what to use on with the amdgpu and a Radeon. At some point, because Chromium appeared to favor vdpau, I installed vdpau, and did so by installing its utility, vdpauinfo...
# pacman -S vdpauinfo
... which also brought in libvdpau. Following this, Chromium opened normally, and YouTube functioned.

xorg

With the nVidia software removed and the amdgpu package installed, X refused to initialize. The error and the solution discussion are here. The solution required a change to /etc/mkinitcpio.conf...
MODULES=(amdgpu)
... and then
# mkinitcpio -p linux
After this, X loaded normally.

Sunday, December 15, 2019

sound and systemd, restart sound

Running HDMI means dealing with two audio chips -- the first on the motherboard and a second on the video card, where the A/V HDMI cable is connected. Many things can therefore derail the sound. In this case it was an Arch update, causing some conflict with the kernel. But each failure has to be solved by a process of elimination. ALSA is embedded into the kernel, so that systemd is the way to restart.
# systemctl restart alsa.restore.service
Should d

Let's suppose the connected HDMI device at the other end of the cable is putting out clean video. Now let's suppose the audio is also present, but that it sounds distorted: chipmunky or maybe raspy or fuzzy, like a bad AM radio connection. We know that at least one of the audio chips IS working if sound is present at the output. But solving the distortion many not be easy. Perhaps the wrong sound chip, both chips simultaneously, or that the correct chip has incorrect settings. You've done everything here and the gold standard...
$ aplay -D plughw:1,7 /usr/share/sounds/alsa/Front_Center.wav
...for your particular hardware, which you correctly determined with...
$ aplay -l

Suppose this is in spite of Pulseaudio being effectively disabled , /usr/share/alsa/alsa.conf successfully sterilized of hooks, and /etc/asound.conf, ~/.asoundrc, and ~/.config/asound.conf having been successfully deleted.

Suppose also that we have...
$ systemctl list-unit-files |grep alsa
alsa-restore.service static
alsa-state.service static

$ systemctl list-units |grep sound
sys-devices-pci0000:00-0000:00:01.0-0000:01:00.1-sound-card1.device loaded active plugged GK104 HDMI Audio Controller
sys-devices-pci0000:00-0000:00:1b.0-sound-card0.device loaded active plugged 7 Series/C216 Chipset Family High Definition Audio Controller
sound.target loaded active active Sound Card
... well then WTF is going on? We can see ALSA is properly "static" and therefore compiled into the kernel. We can see that both hardwares examine some of those systemd service modules inside /etc/systemd/system/, but this does not seem to be the problem.

possibility 1

Suppose you still have an unaddressed situation of both sound cards receiving the same name from the kernel
$ cat /proc/asound/modules
0 snd_hda_intel
1 snd_hda_intel

Tuesday, September 25, 2018

[solved] more hdmi sound hijinx

Whichever card is running the HDMI must be set as the default inside alsa, no matter whether or not there are secondary issues with pulseaudio. Your order of business when finding that, say, YouTube videos no longer have sound, or VLC is without audio, are
  • ye olde verify audio is unmuted in alsamixer (while you're in alsamixer, why not check your card for annoying "automute", and disable it. Select it and use the "+" or "-" keys to toggle it)
  • check sound with a specific command to the hardware card. If this doesn't work, go into a subroutine of verifying HDMI. For example, this MUST work, if this is the named card and HDMI channel
    $ aplay -D plughw:1,7 /usr/share/sounds/alsa/Front_Center.wav
  • assuming the above works, then the wrong default card is likely being assigned, so that YouTube is, say, attempting to play through [default] motherboard audio, instead of an HDMI authorized sound card. This means, particularly after an software update, doing the thing you've done for years now...
    # nano /usr/share/alsa/alsa.conf
    @hooks [
    {
    func load
    files [
    {
    @func concat
    strings [
    { @func datadir }
    "/alsa.conf.d/"
    ]
    }
    ]
    errors false
    }
    ]
    ... and then further down in the file change the defaults...
    # nano /usr/share/alsa/alsa.conf
    defaults.ctl.card 1 #default 0
    defaults.pcm.card 1 #default 0
    defaults.pcm.device 7 #default 0

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.