【发布时间】:2023-03-13 09:42:01
【问题描述】:
我正在寻找一种将文件中的音频数据输入麦克风的方法,以便当第 3 方应用程序(例如 arecord 或 Chromium 的“语音搜索”功能)使用麦克风获取音频时输入时,它们会从文件中接收音频数据。
这是我的场景:我编写的一个应用程序记录来自麦克风的音频数据(使用 ALSA)并将其保存到一个文件 (audioFile0.raw)。在未来某个未知的时间点,一些未知的 3rd 方应用程序(例如,我没有开发所以我没有开发控制权的东西,例如 Chromium 网络浏览器的“语音搜索”功能)将使用麦克风获取音频数据。我希望第 3 方应用程序收集的音频数据来自 audioFile.raw 而不是实际的麦克风本身。
我在想是否可以将默认音频输入设备更改为音频文件,或者命名管道并执行类似cat audioFile0.raw > mypipe 的操作(因为我不知道其他应用程序何时会尝试从麦克风)。也许有更简单的方法来做到这一点?
我希望我提供了足够的细节和清晰度。如果有不清楚的地方请告诉我。
编辑: 所以我想出了如何通过在我的主目录中创建以下 .asoundrc 文件来制作虚拟麦克风:
pcm.!virtmic {
type file
slave.pcm "hw:0,0"
file /dev/null
infile "/home/charles/audioFiles/audioFile0.raw"
}
pcm.!default {
type hw
card 0
}
ctl.!default {
type hw
card 0
}
然后我从命令行调用arecord test.raw -c 1 -f S16_LE -r 16000 -t raw -D virtmic,我就能够将audioFile0.raw 中的音频数据录制到test.raw。
我现在的目标是用我的虚拟麦克风替换默认设备,这样任何访问麦克风的应用程序都将读取audioFile0.raw 中的音频数据,而不是实际的麦克风本身。所以我编辑了我的 .asoundrc 文件,如下所示:
pcm.!virtmic {
type file
slave.pcm "hw:0,0"
file /dev/null
infile "/home/charles/audioFiles/audioFile0.raw"
}
pcm.!default {
type asym
playback.pcm {
type hw
card 0
}
capture.pcm {
type plug
slave.pcm "virtmic"
}
}
ctl.!default {
type hw
card 0
}
然后我从命令行调用arecord test.raw -c 1 -f S16_LE -r 16000 -t raw。然后我播放了test.raw,但它似乎是从麦克风本身录制的,而不是audioFile0.raw。
我究竟做错了什么?如何更改默认捕获设备,使其从audioFile0.raw 读取数据,而不是从麦克风输入?
编辑 2: 好的,所以我是在正确的轨道上。我在我之前展示的主目录中使用了相同的 .asoundrc 文件,在该文件中我将默认设备更改为 virtmic。我需要更改文件/usr/share/alsa/alsa.conf.d/pulse.conf,使其看起来像这样:
# PulseAudio alsa plugin configuration file to set the pulseaudio plugin as
# default output for applications using alsa when pulseaudio is running.
hook_func.pulse_load_if_running {
lib "libasound_module_conf_pulse.so"
func "conf_pulse_hook_load_if_running"
}
@hooks [
{
func pulse_load_if_running
files [
# "/usr/share/alsa/pulse-alsa.conf"
"/home/charles/.asoundrc"
]
errors false
}
]
我唯一做的就是将"/usr/share/alsa/pulse-alsa.conf" 行注释掉,并用"/home/charles/.asoundrc" 替换它,所以pulseaudio 插件不是使用ALSA 的应用程序的默认设置,而是使用我的虚拟麦克风作为默认设置。这可能不是最好的解决方案,但它确实有效。
这在我做arecord test.raw -t raw -c 1 -f S16_LE -r 16000 时有效。它从audiofile0.raw而不是麦克风获取数据!我使用命令lsof /dev/snd/* 来查看在arecord 命令运行时访问音频设备的具体内容。输出如下:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
pulseaudi 2044 charles 22u CHR 116,6 0t0 8977 /dev/snd/controlC0
pulseaudi 2044 charles 29u CHR 116,6 0t0 8977 /dev/snd/controlC0
arecord 4051 charles mem CHR 116,5 8976 /dev/snd/pcmC0D0c
arecord 4051 charles 4u CHR 116,5 0t0 8976 /dev/snd/pcmC0D0c
然后我尝试使用 Chromium 浏览器的“语音搜索”功能,发现无法从 audioFile0.raw 录制。然后我使用lsof /dev/snd/* 查看究竟是什么在访问音频设备。
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
pulseaudi 2044 charles mem CHR 116,5 8976 /dev/snd/pcmC0D0c
pulseaudi 2044 charles 22u CHR 116,6 0t0 8977 /dev/snd/controlC0
pulseaudi 2044 charles 29u CHR 116,6 0t0 8977 /dev/snd/controlC0
pulseaudi 2044 charles 30r CHR 116,33 0t0 7992 /dev/snd/timer
pulseaudi 2044 charles 31u CHR 116,5 0t0 8976 /dev/snd/pcmC0D0c
我看到它们都有相同的 PID,2044。它们都在使用 pulseaudio 守护进程,而不是通过 ALSA。
我的问题:我如何让 pulseaudio 默认使用我的虚拟麦克风,以便所有通过 pulseaudio 进行音频输入的应用程序将改为从我的文件而不是麦克风中获取音频数据?
【问题讨论】:
-
@CL。如果我错了,请纠正我,但在这种情况下,录音应用程序似乎是已知的(arecord test.raw -r 8000 -t raw)。就我而言,我无法控制哪个应用程序将访问麦克风。我希望任何将从麦克风读取的应用程序改为从我的文件中读取。
-
请注意,
arecord调用未指定设备名称并使用默认设备。 (而且程序总是可以显式使用不同的设备名称。) -
嗨@CL.,我澄清了我的问题。现在我需要更改默认设备本身。
标签: linux audio microphone alsa voice-recording