Linux 将音频文件通过管道传输到麦克风输入
Linux pipe audio file to microphone input
我正在寻找一种将文件中的音频数据馈送到麦克风的方法,这样当第 3 方应用程序(例如 arecord 或 Chromium 的 "search by voice" 功能)使用麦克风进行音频输入,他们从文件中接收音频数据。
这是我的场景:我编写的一个应用程序记录来自麦克风的音频数据(使用 ALSA)并将其保存到文件中(audioFile0.raw)。在未来某个未知的时间点,一些未知的第 3 方应用程序(例如,我没有开发的东西,所以我无法控制,例如 Chromium 网络浏览器的 "search by voice" 功能)将使用麦克风来获取音频数据。我希望第 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 浏览器的 "search by voice" 功能,发现无法从 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 进行音频输入的应用程序都将从我的文件中获取音频数据,而不是比麦克风?
经过许多艰苦的努力,我终于得到了可以接受的工作。我撤消了我对 ALSA 所做的一切(因为 ALSA 的默认设置是使用 PulseAudio,我最初忽略了它)。我创建了一个简单的 bash 脚本 install_virtmic.sh
来创建一个 "virtual microphone" 供 PulseAudio 以及 PulseAudio 客户端使用:
#!/bin/bash
# This script will create a virtual microphone for PulseAudio to use and set it as the default device.
# Load the "module-pipe-source" module to read audio data from a FIFO special file.
echo "Creating virtual microphone."
pactl load-module module-pipe-source source_name=virtmic file=/home/charles/audioFiles/virtmic format=s16le rate=16000 channels=1
# Set the virtmic as the default source device.
echo "Set the virtual microphone as the default device."
pactl set-default-source virtmic
# Create a file that will set the default source device to virtmic for all
PulseAudio client applications.
echo "default-source = virtmic" > /home/charles/.config/pulse/client.conf
# Write the audio file to the named pipe virtmic. This will block until the named pipe is read.
echo "Writing audio file to virtual microphone."
while true; do
cat audioFile0.raw > /home/charles/audioFiles/virtmic
done
一个快速脚本 uninstall_virtmic.sh
用于撤消安装脚本所做的一切:
#!/bin/bash
# Uninstall the virtual microphone.
pactl unload-module module-pipe-source
rm /home/charles/.config/pulse/client.conf
然后我启动了 Chromium 并点击了麦克风以使用其语音搜索功能,结果成功了!我也尝试过 arecord test.raw -t raw -f S16_LE -c 1 -r 16000
并且它也有效!它并不完美,因为我一直在脚本的无限循环中写入命名管道 virtmic
(这很快使我的 test.raw
文件变得异常大),但它现在就可以了。
如果有人找到更好的解决方案,请随时告诉我!
- 确保安装了 PulseAudio 音量控制 (pavucontrol)。如果没有,您只需在终端中输入即可安装它:
sudo apt install pavucontrol
.
- 打开 PulseAudio 音量控制 (pavucontrol) 并转到“录音”选项卡。当您没有任何设备录制您的麦克风时,此面板应该看起来是空的。一旦任何应用程序开始录音或开始 Skype 通话,此面板应至少有一个条目。
选择“内置音频模拟立体声”是默认行为(将您的声音重定向到麦克风输出)。您还应该看到“内置音频模拟立体声的监视器”。当你 select 这个选项时,输出任何播放音频的应用程序(例如 VLC)应该被重定向到麦克风而不是你的声音。
确保在音频播放完毕后将其改回“内置音频模拟立体声”,以便一切恢复正常。
我正在寻找一种将文件中的音频数据馈送到麦克风的方法,这样当第 3 方应用程序(例如 arecord 或 Chromium 的 "search by voice" 功能)使用麦克风进行音频输入,他们从文件中接收音频数据。
这是我的场景:我编写的一个应用程序记录来自麦克风的音频数据(使用 ALSA)并将其保存到文件中(audioFile0.raw)。在未来某个未知的时间点,一些未知的第 3 方应用程序(例如,我没有开发的东西,所以我无法控制,例如 Chromium 网络浏览器的 "search by voice" 功能)将使用麦克风来获取音频数据。我希望第 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 浏览器的 "search by voice" 功能,发现无法从 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 进行音频输入的应用程序都将从我的文件中获取音频数据,而不是比麦克风?
经过许多艰苦的努力,我终于得到了可以接受的工作。我撤消了我对 ALSA 所做的一切(因为 ALSA 的默认设置是使用 PulseAudio,我最初忽略了它)。我创建了一个简单的 bash 脚本 install_virtmic.sh
来创建一个 "virtual microphone" 供 PulseAudio 以及 PulseAudio 客户端使用:
#!/bin/bash
# This script will create a virtual microphone for PulseAudio to use and set it as the default device.
# Load the "module-pipe-source" module to read audio data from a FIFO special file.
echo "Creating virtual microphone."
pactl load-module module-pipe-source source_name=virtmic file=/home/charles/audioFiles/virtmic format=s16le rate=16000 channels=1
# Set the virtmic as the default source device.
echo "Set the virtual microphone as the default device."
pactl set-default-source virtmic
# Create a file that will set the default source device to virtmic for all
PulseAudio client applications.
echo "default-source = virtmic" > /home/charles/.config/pulse/client.conf
# Write the audio file to the named pipe virtmic. This will block until the named pipe is read.
echo "Writing audio file to virtual microphone."
while true; do
cat audioFile0.raw > /home/charles/audioFiles/virtmic
done
一个快速脚本 uninstall_virtmic.sh
用于撤消安装脚本所做的一切:
#!/bin/bash
# Uninstall the virtual microphone.
pactl unload-module module-pipe-source
rm /home/charles/.config/pulse/client.conf
然后我启动了 Chromium 并点击了麦克风以使用其语音搜索功能,结果成功了!我也尝试过 arecord test.raw -t raw -f S16_LE -c 1 -r 16000
并且它也有效!它并不完美,因为我一直在脚本的无限循环中写入命名管道 virtmic
(这很快使我的 test.raw
文件变得异常大),但它现在就可以了。
如果有人找到更好的解决方案,请随时告诉我!
- 确保安装了 PulseAudio 音量控制 (pavucontrol)。如果没有,您只需在终端中输入即可安装它:
sudo apt install pavucontrol
.
- 打开 PulseAudio 音量控制 (pavucontrol) 并转到“录音”选项卡。当您没有任何设备录制您的麦克风时,此面板应该看起来是空的。一旦任何应用程序开始录音或开始 Skype 通话,此面板应至少有一个条目。
选择“内置音频模拟立体声”是默认行为(将您的声音重定向到麦克风输出)。您还应该看到“内置音频模拟立体声的监视器”。当你 select 这个选项时,输出任何播放音频的应用程序(例如 VLC)应该被重定向到麦克风而不是你的声音。
确保在音频播放完毕后将其改回“内置音频模拟立体声”,以便一切恢复正常。