如何将脉冲音频设备路由到 alsa 环回(虚拟麦克风)?

Ada*_*ski 6 pulseaudio alsa loop-device

我想要一个想要录制我的麦克风的 Flash 应用程序(类似于https://online-voice-recorder.com/)来录制脉冲音频源。

我想,那个闪存使用了 ALSA。所以我安装了 Alsa loop device sudo modprobe snd-aloop,它整齐地出现pavucontrolalplay -l(在列表的末尾):

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

然后我确认,声音被路由到环回设备: pavucontrol 截图

不幸的是,Flash 插件根本看不到声音 - 就像我在录制零一样。

flash 插件可以看到所有面向 ALSA 的声源:

闪存配置

  1. 为什么 flash 插件没有声音?
  2. 如何将 Pulse Audio 的输出路由到 ALSA 输入?

rid*_*dgy 10

简单的答案在最后。但为了帮助理解解决方案,我会尽量做到易于理解。我的假设:“环回设备”是卡#2、设备#0 和#1,因此在所有示例中都是如此(例如,/dev/snd/pcmC2D0p表示“卡2、设备0、播放”)。您的安装可能会有所不同,因此请修改相应的值。

首先,我创建/修改/etc/modprobe.d/alsa-aloop.conf为只有一张卡片和一个子流(只是为了简单起见):

user@desk:~$ cat /etc/modprobe.d/alsa-aloop.conf 
options snd-aloop index=2 pcm_substreams=1 id=Loopback
Run Code Online (Sandbox Code Playgroud)

之后sudo modprobe snd_aloopaplay -larecord -l显示

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
Run Code Online (Sandbox Code Playgroud)

现在有一个问题:环回卡的两个设备都是播放设备和录音设备。但 的功能snd_aloop是将设备 0 的输入路由到设备 1 的输出,反之亦然(参见例如https://www.alsa-project.org/main/index.php/Matrix:Module-aloop)。您可以在/proc/asound目录中看到这些:

user@desk:~$ ls /proc/asound/card2
cable#0  cable#1  id  pcm0c  pcm0p  pcm1c  pcm1p
Run Code Online (Sandbox Code Playgroud)

其中“pcm0c”是捕获设备0,“pcm0p”是播放设备0等。

Sopavucontrol显示(并选择)两个循环设备,一个播放(hw:2,0)和一个记录(hw:2,1):

您不能在 中选择播放设备pavucontrol,因此它选择了设备 0:

查看播放设备文件时,您会看到:

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
.
.
Run Code Online (Sandbox Code Playgroud)

因此,这意味着必须通过以下方式捕获此音频流/dev/snd/pcmC2D1c;如果您选择loopback作为 flash 的输入设备,它将/dev/snd/pcmC2D0c改为使用(plugin-co意味着插件容器 flash 正在运行):

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
.
.
Run Code Online (Sandbox Code Playgroud)

您可以检查何时通过 明确播放声音/dev/snd/pcmC2D1p,例如

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

现在 flash 插件记录声音,你可以看到不同之处:

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
.
.
Run Code Online (Sandbox Code Playgroud)

所以,现在的任务是:如何让pulseaudio选择回送卡的#1设备进行播放?

假设上面的值,您可以修改/etc/pulse/default.pa为读取

.
.
### 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
.
.
Run Code Online (Sandbox Code Playgroud)

确保在动态驱动程序之前定义静态驱动程序。现在PA( pulseaudio -k)重启后,PA的loopback输出到card2,设备1( device=hw:2,1)。验证:

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
.
.
Run Code Online (Sandbox Code Playgroud)

因此,您的闪存录音机能够从pulseaudio 的输出中进行录音。

备注:如果您不想编辑/etc/pulse/default.pa,您可以使用 交互加载模块pacmd load-module module-alsa-sink device=hw:2,1。这将为您提供第二个loopback设备pavucontrol。如果您只需要一个环回设备,请先卸载相应的模块:

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"
Run Code Online (Sandbox Code Playgroud)

查找索引 where device-id=2(here:7),然后卸载模块 ( ),然后pacmd unload-module 7加载环回的接收器 ( pacmd load-module module-alsa-sink device=hw:2,1)。