【问题标题】:Linux pipe audio file to microphone inputLinux管道音频文件到麦克风输入
【发布时间】: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


【解决方案1】:
  1. 确保您已安装 PulseAudio 音量控制 (pavucontrol)。如果没有,您只需在终端中输入即可安装它:sudo apt install pavucontrol

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

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

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

【讨论】:

    【解决方案2】:

    经过许多艰苦的工作,我终于得到了可以接受的工作。我取消了我对 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 文件变得异常大),但现在可以了。

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

    【讨论】:

    • 在我的情况下,流式输出被扭曲了,我似乎数据速度非常快,任何帮助???
    • 摆弄 Alexa - 我刚刚添加了 sleep 1;在猫之后,因为它无法跟上所有数据。有了它,它工作得很好,谢谢。
    • 你是老板!!!节省了我用 alsa/pulseaudio 闲逛的时间。只是一个小提示,而不是cat 我使用ffmpeg 就像这样:ffmpeg -re -i input.mp3 -f s16le -ar 16000 -ac 1 - > /home/spiq/virtmic
    • 感谢@sebpiq,这是一个非常关键的细节,可以让一切顺利进行!
    • 当涉及到从管道读取数据的速度并且尽可能快地读取时,pulseaudio module-pipe-source 似乎忽略了rate 参数。 cat 将尽可能快地写入,因此您最终得到的是一个 16 kHz 源,其运行速度比应有的速度快约 1000 倍。有必要使用 ffmpeg 之类的东西来调整写入的速度。
    猜你喜欢
    • 2018-12-10
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 2014-01-01
    • 2011-04-29
    • 2023-01-10
    相关资源
    最近更新 更多