2017-04-18 106 views
2

我正在寻找将文件中的音频数据馈送到麦克风的方式,因此当第三方应用程序(例如或Chromium的“按语音搜索”功能)使用麦克风对于音频输入,它们会从文件接收音频数据。Linux管道音频文件到麦克风输入

这是我的场景:我写的应用程序记录了麦克风(使用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/*来查看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通过对音频输入去的所有应用程序反而会从我的文件,而不是麦克风的音频数据?

+2

[管道输出从aplay到centos中的arecord]的可能重复(http://stackoverflow.com/questions/42843128/piping-output-from-aplay-to-arecord-in-centos) –

+0

@CL。纠正我,如果我错了,但在这种情况下,似乎记录应用程序已知(_arecord test.raw -r 8000 -t raw_)。就我而言,我无法控制哪个应用程序将访问麦克风。我希望任何将从麦克风读取的应用程序从我的文件中读取。 – cheerupcharlie

+1

请注意,'arecord'调用不指定设备名称并使用默认设备。 (程序总是可以明确使用不同的设备名称。) –

回答

5

经过许多艰苦的工作,我终于得到了可以接受的工作。我解开了我使用ALSA所做的所有事情(因为默认情况下ALSA使用PulseAudio,而我最初将其替换)。我创建了一个简单的bash脚本install_virtmic.sh,以创建一个“虚拟麦克风”的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文件变得非常大),但现在它会完成。

请随时让我知道如果有人在那里找到更好的解决方案!