这是我的场景:我编写的应用程序从麦克风录制音频数据(使用ALSA)并将其保存到文件(audioFile0.raw).在未来的某个未知时间点,一些未知的第三方应用程序(例如,我没有开发的东西,所以我没有开发控制权,例如Chromium网络浏览器的“语音搜索”功能)将使用麦克风来获取音频数据.我希望第三方应用程序收集的音频数据来自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 / *来查看iscord命令运行时访问音频设备的确切内容.输出如下:
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 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进行音频输入的应用程序将从我的文件而不是麦克风中获取音频数据?
解决方法
#!/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文件变得非常大),但它现在会做.
如果有人找到更好的解决方案,请随时告诉我们!