Files
BaC/content/2021-02-26-Lincroyable-aventure-de-pulseaudio-et-la-carte-nvidia.md
2025-02-27 12:52:48 +01:00

190 lines
15 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

+++
title = "Lincroyable aventure de Pulseaudio et la carte Nvidia"
date = 2021-02-26
[taxonomies]
tags = [ "système" ]
+++
«Et le magicien changea alors la configuration dAlsa pour le rendre compatible avec cette sortie HDMI de merde! »
<!-- more -->
# Bon, cest quoi encore ton problème?
Depuis un certain temps, ma carte graphique Nvidia a décidé de ne plus fonctionner correctement en sortie audio: de temps en temps, à la sortie de veille, plus de son; à dautre moment, les sortie stéréo HDMI sinverse (il y a deux écrans branchés dessus et de temps en temps le son part sur lun, de temps en temps sur lautre).
En fait, jai découvert que cette conne de carte avait un comportement assez bizarre:
* elle affiche 7 sorties (!) alors quelle nen a que 4 (1 DisplayPort, un HDMI, 2 DVI);
* elle désactive les sorties audio lors de la sortie de veille du PC;
* elle inverse régulièrement les sorties en question.
Donc, sous Alsa, au lieu de voir 4 sorties avec des dénominations bien précises, jen vois un paquet qui ont des numéros et bien évidemment rien nest vraiment consistant:
```
$ aplay -l | grep -i carte
carte 0: PCH [HDA Intel PCH], périphérique 0: VT1708S Analog [VT1708S Analog]
carte 0: PCH [HDA Intel PCH], périphérique 2: VT1708S Alt Analog [VT1708S Alt Analog]
carte 0: PCH [HDA Intel PCH], périphérique 3: VT1708S Digital [VT1708S Digital]
carte 1: NVidia [HDA NVidia], périphérique 3: HDMI 0 [HDMI 0]
carte 1: NVidia [HDA NVidia], périphérique 7: HDMI 1 [HDMI 1]
carte 1: NVidia [HDA NVidia], périphérique 8: HDMI 2 [HDMI 2]
carte 1: NVidia [HDA NVidia], périphérique 9: HDMI 3 [HDMI 3]
carte 1: NVidia [HDA NVidia], périphérique 10: HDMI 4 [HDMI 4]
carte 1: NVidia [HDA NVidia], périphérique 11: HDMI 5 [HDMI 5]
carte 1: NVidia [HDA NVidia], périphérique 12: HDMI 6 [HDMI 6]
carte 3: Mic [Samson Meteor Mic], périphérique 0: USB Audio [USB Audio]
```
La carte 0 est une carte son intégrée à la carte mère que je ne souhaite pas forcément utiliser. Mon idée est de tout faire passer en HDMI pour pouvoir branche les enceintes/le casque sur lécran et donc brancher éventuellement dautres choses dessus (ma console, un autre PC, etc…) sans avoir à tout recâbler à chaque fois. La carte 2 (qui ne se voit pas ici) est une Webcam: cest donc seulement une entrée, pas une sortie, doù son absence ici.
La carte 3 est un micro USB qui se trouve aussi avoir une sortie audio.
Le problème vient donc de la carte 1. Pour une raison que jignore complètement, elle indique 7 sorties (comme marqué plus haut) alors quelle nen a physiquement que 4. Le plus étrange, cest que `xrandr` aussi mindique 6 sorties:
```
$ xrandr | grep connected
DVI-I-0 disconnected (normal left inverted right x axis y axis)
DVI-I-1 disconnected (normal left inverted right x axis y axis)
HDMI-0 connected 1080x1920+0+0 left (normal left inverted right x axis y axis) 344mm x 194mm
DP-0 disconnected (normal left inverted right x axis y axis)
DP-1 disconnected (normal left inverted right x axis y axis)
DVI-D-0 connected primary 1920x1080+1080+0 (normal left inverted right x axis y axis) 509mm x 286mm
```
Il y a donc des sorties factices ou des sorties internes (?) qui sont captés par Alsa et derrière par Pulseaudio comme étant des sorties réelles mais qui ne font en réalité rien du tout. Les deux écrans que jai (HDMI-0 et DVI-D-0) ont la capacité de faire sortir du son (via des petits hauts-parleurs et une sortie jack).
Voilà, le problème est posé: comment faire pour que cette putain de carte de merde sorte du son seulement sur lécran en DVI et y compris lors de la sortie de veille du PC et de manière consistante si possible?
# Lapproche par Pulseaudio
La vision côté Alsa, tu peux la voir plus haut. La vision côté Pulseaudio nest pas beaucoup plus complexe en réalité:
```
$ pacmd list-cards
4 card(s) available.
index: 0
name: <alsa_card.pci-0000_01_00.1>
driver: <module-alsa-card.c>
owner module: 5
properties:
[…]
profiles:
output:hdmi-stereo: Sortie Digital Stereo (HDMI) (priority 5900, available: unknown)
output:hdmi-stereo-extra1: Sortie Digital Stereo (HDMI 2) (priority 5700, available: unknown)
output:hdmi-stereo-extra2: Sortie Digital Stereo (HDMI 3) (priority 5700, available: no)
output:hdmi-surround-extra2: Sortie Digital Surround 5.1 (HDMI 3) (priority 600, available: no)
output:hdmi-surround71-extra2: Sortie Digital Surround 7.1 (HDMI 3) (priority 600, available: no)
output:hdmi-stereo-extra3: Sortie Digital Stereo (HDMI 4) (priority 5700, available: no)
output:hdmi-surround-extra3: Sortie Digital Surround 5.1 (HDMI 4) (priority 600, available: no)
output:hdmi-surround71-extra3: Sortie Digital Surround 7.1 (HDMI 4) (priority 600, available: no)
output:hdmi-stereo-extra4: Sortie Digital Stereo (HDMI 5) (priority 5700, available: no)
output:hdmi-surround-extra4: Sortie Digital Surround 5.1 (HDMI 5) (priority 600, available: no)
output:hdmi-surround71-extra4: Sortie Digital Surround 7.1 (HDMI 5) (priority 600, available: no)
output:hdmi-stereo-extra5: Sortie Digital Stereo (HDMI 6) (priority 5700, available: no)
output:hdmi-surround-extra5: Sortie Digital Surround 5.1 (HDMI 6) (priority 600, available: no)
output:hdmi-surround71-extra5: Sortie Digital Surround 7.1 (HDMI 6) (priority 600, available: no)
output:hdmi-stereo-extra6: Sortie Digital Stereo (HDMI 7) (priority 5700, available: no)
output:hdmi-surround-extra6: Sortie Digital Surround 5.1 (HDMI 7) (priority 600, available: no)
output:hdmi-surround71-extra6: Sortie Digital Surround 7.1 (HDMI 7) (priority 600, available: no)
off: Éteint (priority 0, available: unknown)
active profile: <alsa_output.pci-0000_01_00.1.hdmi-stereo>
sinks:
alsa_output.pci-0000_01_00.1.hdmi-stereo/#0: GM204 High Definition Audio Controller Digital Stereo (HDMI)
alsa_output.pci-0000_01_00.1.hdmi-stereo-extra1/#3: GM204 High Definition Audio Controller Digital Stereo (HDMI 2)
alsa_output.pci-0000_01_00.1.hdmi-stereo-extra2/#4: GM204 High Definition Audio Controller Digital Stereo (HDMI 3)
[…]
```
Il y a donc pas mal de profils disponibles: pour chaque sortie physique, un profil Surround, un profil Surround 7.1 et un profil Stéréo. Il y a également un profil `off` qui permet déteindre complètement la carte et dempêcher toute sortie son par là.
Lapproche naïve consiste donc à se dire: il suffit dutiliser un petit logiciel comme `pavucontrol` pour régler lensemble des sorties et entrées de la carte, déteindre les sorties qui ne nous intéressent pas, et le tour est joué. Et en effet, dans un premier temps, ça a marché: jai choisi le profil qui va bien pour sortir le son sur lécran principal et le tour était joué.
Ça na pas réglé mon souci de son absent en sortie de veille (on y reviendra), mais effectivement ça «marche». Sauf quau premier redémarrage, sans rien toucher physiquement évidemment, Pulseaudio semmêle les saucisses et la sortie HDMI3 devient la sortie HDMI2, la sortie HDMI4 devient la 1, etc…
**Impossible davoir un résultat probant avec cette méthode!!**
## Forcer le hardware
Ma première idée était donc de forcer une corrélation stricte entre le *hardware* (les sorties audio telle quelles sont vues par Alsa) et la partie Pulseaudio. Pour ce faire, on peut passer par le fichier `/etc/pulse/default.pa`. Première chose, repérer quelle sortie correspond à lécran. Pour cela, on utilise la commande `aplay` avec les bonnes options:
```
$ aplay -D plughw:1,3 /usr/share/sounds/alsa/Front_Right.wav
```
Voilà, tu fais ça avec chaque sortie (voire la sortie de la commande `aplay -l` plus haut) jusquà ce que tu trouves la sortie de ton écran. À partir de là, tu peux ajouter la commande suivante dans le fichier `/etc/pulse/default.pa`:
```
load-module module-alsa-sink device=hw:1,7
```
Ce fichier est le fichier de configuration par défaut de Pulseaudio, qui prend uniquement des commandes `pacmd`, et qui est lu par Pulseaudio à chaque fois quil crée un profil utilisateur. Ça, ça veut dire que cest juste une configuration par défaut et pas autre chose. Pour la prendre en charge, il faut donc arrêter `pulseaudio`, supprimer la configuration utilisateur et redémarrer `pulseaudio`. Ça se fait comme ça:
```
$ pulseaudio --kill; sleep 1; rm -rf .config/pulse; pulseaudio --start
```
Bien évidemment toute configuration personnalisée via `pavucontrol` ou autre sera perdue :niais:.
Je te coupe tout de suite le suspense: ça ne résiste pas à un redémarrage. Cest assez étonnant dailleurs parce que les indices hardware ne semblent pas particulièrement changer: Alsa détecte toujours la sortie 7 comme étant la sortie 7.
Mais bien sûr, côté Pulseaudio, il y a une sorte de renumérotation qui fait que `alsa_output.pci-0000_01_00.1.hdmi-stereo` va changer de sortie vis-à-vis dAlsa (et pareil pour `alsa_output.pci-0000_01_00.1.hdmi-stereo-extra1` et ainsi de suite).
## Un simple problème de persmission
Visiblement, il traîne dans les archives du code de Pulseaudio un certain nombre de bêtises et notamment le fait quun groupe serait codé en dur dedans: si lutilisateur nest pas dans le groupe `audio`, ya plein de trucs qui ne marcheraient pas.
Bon, on ne va pas se cacher: ça ne marche pas forcément mieux.
## Premières conclusions
À partir de ce moment, jen ai conclu quil nétait pas possible de fixer véritablement la sortie audio: Pulseaudio ne détecte pas les sorties dans le bon ordre et même en le forçant, visiblement il fait un peu ce quil veut (soit au démarrage, soit en sortie de veille). Jaurais tendance à penser que le processus de détection nest malheureusement pas déterministe.
**Clairement, le souci vient de Pulseaudio cependant**, Alsa semble vraiment détecter les sorties audio toujours dans le même ordre. Il est aussi possible que le problème vienne des pilotes Nvidia qui ferait nimporte quoi avec la détection des sorties. Ou il est encore possible que ce soit une combinaison des deux. Quoiquil arrive, il est clair que je narriverai pas à solutionner le problème avec juste de la configuration.
# Et si on sortait le son partout sans réfléchir?
À partir de ce moment, je pense avoir essayé toutes les possibilités «rationnelles» sur ce problème. Et quand on a essayé toutes les possibilités rationnelles, il faut commencer à penser autrement. Je me suis donc dit: pourquoi ne pas sortir le son sur toutes les sorties HDMI en même temps? Finalement, ce serait le plus simple: quel que soit la configuration de Pulseaudio, la détection, lordre des sorties, etc… tout sera de toutes manières capables de sortir du son et il ny aura plus quà rendre les sorties inutiles muettes manuellement.
Sauf que par défaut, Pulseaudio na pas de profil pour sortir sur toutes les sorties HDMI en même temps.
## Profil Pulseaudio
Du coup, il faut aller dans le fichier `/usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf`, à la toute fin, il y a un exemple impliquant un profil multi-sorties, cest donc de celui-ci quon va se servir:
```
[Profile forced-hdmi-stereo]
description = Foobar
output-mappings = hdmi-stereo hdmi-stereo-extra1 hdmi-stereo-extra2
input-mappings =
```
Cest assez bête basiquement: ce profil dit simplement que toutes les sorties Pulseaudio peuvent être utilisées en même temps. Maintenant, ce nest pas parce quelles peuvent être utilisées en même temps quelles le seront. En fait, si tu sélectionnes le profil `Foobar` dans longlet Configuration de `pavucontrol`, tu peux alors zapper entre les différentes sorties sans repasser par un profil particulier.
Sauf que pour le moment, cest tout ce que ça permet de faire: nous avons un profil qui peut interagir avec toutes les sorties mais pas sortir simultanément le son sur toutes ces sorties.
## Ajout dune sortie multiple
Pour arriver à faire une sortie multiple, il faut utiliser un autre module Pulseaudio: `combined-sink`. Dans Pulseaudio un `sink` est une sortie. Ce que nous avons fait précédemment, cest créer un profil disposant de plusieurs `sinks`. Il faut donc se débrouiller pour les combiner. Encore une fois, ça se passe dans le fichier `/etc/pulse/default.pa`:
```
set-card-profile 0 forced-hdmi-stereo
load-module module-combine-sink sink_name=combined slaves=alsa_output.pci-0000_01_00.1.hdmi-stereo,alsa_output.pci-0000_01_00.1.hdmi-stereo-extra1,alsa_output.pci-0000_01_00.1.hdmi-stereo-extra2
set-default-sink combined
```
La première ligne sert simplement à indiquer à Pulseaudio que la carte Nvidia (qui est détectée systématiquement comme carte 0 dans mon cas) est la carte part défaut. La seconde ligne crée un nouveau `sink` (une sortie donc) qui combine toutes les sorties de la carte (pour obtenir le nom des différents sorties, il suffit dutiliser la commande `pactl list-sinks`). De cette manière, si les sorties sont interverties par Pulseaudio, quelque soit la condition, toutes les sorties HDMI de la machine recevront du son. Voilà, cest à peu près aussi con que ça.
La dernière ligne sert juste à sélectionner cette sortie par défaut.
# Bon OK, tas du son mais est-ce que ten as toujours en sortie de veille?
Non toujours pas :/
Cétait un peu prévisible: jai deux problèmes en fait. Le premier est maintenant réglé, pour le second voilà ce quil en est… Pulseaudio semble refaire une détection complète à la sortie de veille (dans le cadre dun PC Portable, ça paraît logique en fait) et la carte Nvidia nest donc pas détectée suffisamment vite.
En fait, si à la sortie de veille, je vais dans `pavucontrol`, je peux très bien la rallumer là et elle marche parfaitement bien après. Le souci, cest que je nai pas du tout envie de faire ça.
De là, je me suis dit que ce nétait pas forcément un souci de bascule mais peut-être de détection détat: à la sortie de veille, la carte vidéo met peut-être un peu de temps à redétecter les écrans (en HDMI, ça ne serait pas surprenant) et Pulseaudio part donc du principe quil faut quil bascule les sources et les sorties ailleurs pour éviter de couper le son. Lintention est louable mais en loccurence, cest un peu inutile pour mon cas.
Jai donc simplement désactivé le module qui soccupe de ça, en loccurence `module-switch-on-port-available`. Pour le désactiver, il suffit de le commenter dans le fichier `/etc/pulse/default.pa`.
# Conclusage définitif
Putain, ça fait quand même beaucoup de bordel pour arriver à faire fonctionner les choses correctement. Je comprends le principe de faire de la détection dynamique systématiquement, je pense que cest une bonne chose dans labsolu, mais je pense quil faut aussi laisser la possibilité à lutilisateur de fixer un certain nombre de choses si ça foire ou si ça nest pas adapté à la situation.
Ce que jai fait là ressemble quand même largement plus à du hack quà de la vraie configuration (surtout la partie multiple sorties à vrai dire), mais je suis assez satisfait du résultat: ça fonctionne à tous les coups et sans faire des pieds et des mains ou sagiter dans la conf ou dans les menus ou commandes à chaque sortie de veille.