web-dev-qa-db-fra.com

Comment router un périphérique audio Pulse dans alsa loopback (microphone virtuel)?

Je veux une application flash qui veut enregistrer mon microphone (quelque chose comme https://online-voice-recorder.com/ ) pour enregistrer une source Pulse Audio.

J'ai pensé que le flash utilise ALSA. J'ai donc installé le périphérique de boucle Alsa Sudo modprobe snd-aloop, qui est clairement apparu à la fois dans pavucontrol et dans alplay -l (à la fin de la liste):

adam@adam-g551jm:~ 130 $ aplay -l **** List of PLAYBACK Hardware Devices **** card 0: HDMI [HDA Intel HDMI], device 3: HDMI 0 [HDMI 0] Subdevices: 0/1 Subdevice #0: subdevice #0 card 0: HDMI [HDA Intel HDMI], device 7: HDMI 1 [HDMI 1] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: HDMI [HDA Intel HDMI], device 8: HDMI 2 [HDMI 2] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: PCH [HDA Intel PCH], device 0: ALC668 Analog [ALC668 Analog] Subdevices: 0/1 Subdevice #0: subdevice #0 card 2: Loopback [Loopback], device 0: Loopback PCM [Loopback PCM] Subdevices: 7/8 Subdevice #0: subdevice #0 Subdevice #1: subdevice #1 Subdevice #2: subdevice #2 Subdevice #3: subdevice #3 Subdevice #4: subdevice #4 Subdevice #5: subdevice #5 Subdevice #6: subdevice #6 Subdevice #7: subdevice #7 card 2: Loopback [Loopback], device 1: Loopback PCM [Loopback PCM] Subdevices: 8/8 Subdevice #0: subdevice #0 Subdevice #1: subdevice #1 Subdevice #2: subdevice #2 Subdevice #3: subdevice #3 Subdevice #4: subdevice #4 Subdevice #5: subdevice #5 Subdevice #6: subdevice #6 Subdevice #7: subdevice #7

Puis j'ai confirmé que le son est routé vers le périphérique de bouclage: Screenshot of pavucontrol

Malheureusement, le plugin flash ne voit pas le son du tout - comme si j’enregistrais des zéros.

Le plugin flash voit toutes les sources sonores faisant face à ALSA:

Flash config

  1. Pourquoi il n'y a pas de son visible par le plugin flash?
  2. Que faire pour acheminer la sortie d’un Pulse Audio dans l’entrée ALSA?
2
Adam Ryczkowski

La réponse simple est à la fin. Mais pour aider à comprendre la solution, je vais essayer d’être aussi intelligible que possible. Mon hypothèse: "Périphérique de bouclage" est la carte n ° 2, les périphériques n ° 0 et n ° 1, donc, dans tous les exemples, cela est vrai (par exemple, /dev/snd/pcmC2D0p signifie "carte 2, périphérique 0, lecture"). Votre installation peut varier, donc modifiez les valeurs respectives.

D'abord, j'ai créé/modifié /etc/modprobe.d/alsa-aloop.conf pour n'avoir qu'une seule carte avec un seul sous-flux (juste pour simplifier):

user@desk:~$ cat /etc/modprobe.d/alsa-aloop.conf 
options snd-aloop index=2 pcm_substreams=1 id=Loopback

Après Sudo modprobe snd_aloop, aplay -l et arecord -l montrent

user@desk:~$ aplay -l
**** List of PLAYBACK Hardware Devices ****
.
.
card 2: Loopback [Loopback], device 0: Loopback PCM [Loopback PCM]
  Subdevices: 0/1
  Subdevice #0: subdevice #0
card 2: Loopback [Loopback], device 1: Loopback PCM [Loopback PCM]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

user@desk:~$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 2: Loopback [Loopback], device 0: Loopback PCM [Loopback PCM]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: Loopback [Loopback], device 1: Loopback PCM [Loopback PCM]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Maintenant, il y a un problème: les deux périphériques de la carte de bouclage sont la lecture ainsi que les périphériques d'enregistrement. Mais la fonction de snd_aloop consiste à router les entrées du périphérique 0 vers les sorties du périphérique 1 et inversement (voir par exemple https://www.alsa-project.org/main/index.php/Matrix : Module-aloop ). Vous pouvez les voir dans le répertoire /proc/asound:

user@desk:~$ ls /proc/asound/card2
cable#0  cable#1  id  pcm0c  pcm0p  pcm1c  pcm1p

où "pcm0c" est le périphérique de capture 0, "pcm0p" est le périphérique de lecture 0, etc.

Donc, pavucontrol affiche (et sélectionne) deux appareils en boucle, un en lecture (hw: 2,0) et un enregistrement (hw: 2,1):

Vous ne pouvez pas sélectionner le périphérique de lecture dans pavucontrol, il sélectionne donc le périphérique 0:

Vous verrez ceci en consultant le fichier du périphérique de lecture:

user@desk:~$ lsof | grep /dev/snd/pcmC2
pulseaudi 3314               user  mem       CHR             116,13                 556 /dev/snd/pcmC2D0p
pulseaudi 3314               user   48u      CHR             116,13      0t0        556 /dev/snd/pcmC2D0p
alsa-sink 3314 3320          user  mem       CHR             116,13                 556 /dev/snd/pcmC2D0p
alsa-sink 3314 3320          user   48u      CHR             116,13      0t0        556 /dev/snd/pcmC2D0p
.
.

Cela signifie donc que la capture de ce flux audio doit être effectuée via /dev/snd/pcmC2D1c; Si vous sélectionnez loopback comme périphérique d'entrée pour la mémoire flash, il utilisera /dev/snd/pcmC2D0cinstead (plugin-co signifie que le conteneur de plug-in flash est en cours d'exécution):

user@desk:~$ lsof | grep /dev/snd/pcmC2
pulseaudi 3314               user  mem       CHR             116,13                 556 /dev/snd/pcmC2D0p
pulseaudi 3314               user   48u      CHR             116,13      0t0        556 /dev/snd/pcmC2D0p
.
.
plugin-co 5093               user  mem       CHR             116,14                 557 /dev/snd/pcmC2D0c
plugin-co 5093               user   21u      CHR             116,14      0t0        557 /dev/snd/pcmC2D0c
.
.

Vous pouvez vérifier lorsque vous jouez explicitement du son via /dev/snd/pcmC2D1p, par exemple. avec

user@desk:~$ aplay -D hw:2,1 test1.wav
Playing WAVE 'test1.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Mono

Maintenant, le plugin flash enregistre le son et vous pouvez voir la différence:

user@desk:~$ lsof | grep pcmC2
.
.
aplay     7256               user  mem       CHR             116,15                  558 /dev/snd/pcmC2D1p
aplay     7256               user    4u      CHR             116,15       0t0        558 /dev/snd/pcmC2D1p
.
.
plugin-co 7237               user  mem       CHR             116,14                  557 /dev/snd/pcmC2D0c
plugin-co 7237               user   21u      CHR             116,14       0t0        557 /dev/snd/pcmC2D0c
.
.

La tâche est donc la suivante: Comment faire pour que pulseaudio sélectionne le périphérique n ° 1 de la carte de bouclage pour la lecture?

En supposant les valeurs ci-dessus, vous pouvez modifier /etc/Pulse/default.pa pour lire

.
.
### Load audio drivers statically
### (it's probably better to not load these drivers manually, but instead
### use module-udev-detect -- see below -- for doing this automatically)
#load-module module-alsa-sink
#load-module module-alsa-source device=hw:1,0
.
.
load-module module-alsa-sink device=hw:2,1
.
.

Assurez-vous de définir le ou les pilotes statiques avant les pilotes dynamiques. Maintenant, après le redémarrage de PA (pulseaudio -k), la sortie loopback de PA passe à card2, périphérique 1 (device=hw:2,1). Vérifier:

user@desk:~$ lsof | grep pcmC2
pulseaudi 8584               user  mem       CHR             116,15                  558 /dev/snd/pcmC2D1p
pulseaudi 8584               user   18u      CHR             116,15       0t0        558 /dev/snd/pcmC2D1p
alsa-sink 8584 8585          user  mem       CHR             116,15                  558 /dev/snd/pcmC2D1p
alsa-sink 8584 8585          user   18u      CHR             116,15       0t0        558 /dev/snd/pcmC2D1p
.
.

Ainsi, votre enregistreur flash peut enregistrer à partir de la sortie de pulseaudio.

Remarque: Si vous ne souhaitez pas éditer /etc/Pulse/default.pa, vous pouvez charger le module de manière interactive avec pacmd load-module module-alsa-sink device=hw:2,1. Cela vous donnera un second loopback dispositif dans pavucontrol. Et si vous ne voulez qu'un périphérique de bouclage, commencez par décharger le module correspondant:

user@desk:~$ pacmd list-modules
.
.
    index: 7
    name: <module-alsa-card>
    argument: <device_id="2" name="platform-snd_aloop.0" card_name="alsa_card.platform-snd_aloop.0" namereg_fail=false tsched=yes fixed_latency_range=no ignore_dB=no deferred_volume=yes use_ucm=yes card_properties="module-udev-detect.discovered=1">
    used: 0
    load once: no
    properties:
        module.author = "Lennart Poettering"
        module.description = "ALSA Card"
        module.version = "8.0"

Recherchez l'index où device-id=2 (ici: 7), puis déchargez le module (pacmd unload-module 7), puis chargez le récepteur pour le bouclage (pacmd load-module module-alsa-sink device=hw:2,1).

4
ridgy