Linux管道音频文件到麦克风输入

时间:2017-04-18 19:43:23

标签: linux audio microphone alsa voice-recording

我正在寻找一种将文件中的音频数据输入麦克风的方法,以便在第三方应用程序(例如 arecord 或Chromium' s"语音"功能)使用麦克风进行音频输入,而不是从文件接收音频数据。

这是我的方案:我编写的应用程序从麦克风录制音频数据(使用ALSA)并将其保存到文件(audioFile0.raw)。在未来某个未知的时间点,一些未知的第三方应用程序(例如,我没有开发的东西,所以我没有开发控制权,例如Chromium网络浏览器""语音搜索&# 34;功能)将使用麦克风获取音频数据。我希望第三方应用程序收集的音频数据来自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进行音频输入的应用程序将从我的文件而不是麦克风中获取音频数据? / p>

2 个答案:

答案 0 :(得分:13)

经过许多艰苦的工作,我终于得到了一些可以接受的工作。我解除了我用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文件变得非常大),但它现在会用。

如果有人找到更好的解决方案,请随时告诉我们!

答案 1 :(得分:0)

  1. 确保已安装PulseAudio音量控件(pavucontrol)。如果没有,则只需在终端机上输入sudo apt install pavucontrol即可安装它。

enter image description here

  1. 打开PulseAudio音量控制(pavucontrol)并转到“录音”选项卡。当没有任何设备录制麦克风时,该面板应为空。一旦任何应用程序开始记录或开始Skype通话,此面板上至少应有一个条目。

Recording Tab

  1. 选择“内置音频模拟立体声”是默认行为(将语音重定向到麦克风输出)。您还应该看到“内置音频模拟立体声显示器”。选择此选项时,输出音频的任何应用程序(例如VLC)的输出都应重定向到麦克风,而不是语音。

  2. 请确保在音频播放完毕后将其更改回“内置音频模拟立体声”,以使一切恢复正常。