3

最重要的是,我的场景是开发一个可访问性应用程序,而不是任何恶意窃听,而在这个场景中,还有各种研究和开发隐含的场景,所有这些都应该极大地受益于能够多次读取麦克风音频流同时运行不相关的进程,例如记录工具和/或我自己的代码的不同版本。

问题陈述

我正在使用高级 python API 读取麦克风输入流,如下所示:

import sounddevice

audio_stream = sounddevice.InputStream(
  device=self.microphone_device,
  channels=max(self.channels),
  samplerate=self.audio_props['sample_rate'],
  blocksize=int(self.audio_props['frame_elements_size']),
  callback=self.audio_callback)

我想了解是否可以(在 Linux 上)将麦克风音频流同时读取到另一个程序,例如 Google Meet / Zoom 读取它。即有效地共享音频流。

与上面提到的 python 包装器一样,当视频通话正在进行时启动上述代码时,它会简单地无法打开流,这并不奇怪:

Expression 'paInvalidSampleRate' failed in 
'src/hostapi/alsa/pa_linux_alsa.c', line: 2043 
Expression 'PaAlsaStreamComponent_InitialConfigure( &self->playback, outParams, self->primeBuffers, hwParamsPlayback, &realSr )' 
failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2716 
Expression 'PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer, &inputLatency, &outputLatency, &hostBufferSizeMode )' 
failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2837

诚然,我还不太熟悉 ALSA 术语以及一般的 linux 上的声音堆栈。

我的问题是,这可以直接使用 ALSA 库 API 来完成,还是通过其他声音堆栈或声音系统配置来完成?或者,如果所有其他方法都不起作用,通过代理程序/驱动程序能够将音频缓冲区暴露给多个消费者,而不会导致音频流延迟明显下降?

4

2 回答 2

5

您可以直接使用 ALSA 执行此操作。Dsnoop应该可以解决问题。它是 ALSA 附带的一个插件,允许共享输入流。

从我上面链接的页面:

dsnoop相当于dmix插件,但用于录制声音。该dsnoop插件允许多个应用程序同时从同一设备录制。

来自 ALSA文档

如果要使用多个输入(捕获)客户端,则需要使用 dsnoop 插件:

您可以在那里四处寻找有关如何使用它的详细信息。GitHub 上的这个问题也将帮助您入门,它详细说明了如何配置dsnoop界面,以便您可以使用pyaudio.

更新

要配置 ALSA,请使用以下内容进行编辑(/etc/asound.conf来自ALSA 文档dsnoop):

pcm.mixin {
         type dsnoop
         ipc_key 5978293 # must be unique for all dmix plugins!!!!
         ipc_key_add_uid yes
         slave {
                 pcm "hw:1,0"
                 channels 2
                 period_size 1024
                 buffer_size 4096
                 rate 44100
                 periods 0
                 period_time 0
         }
         bindings {
                 1 1
                 1 0
         }
 }

您可以测试以查看您的配置是否适用于以下内容:

arecord -d 30 -f cd -t wav -D pcm.mixin test.wav 
于 2020-08-25T19:14:07.783 回答
2

所以,这更像是一个音频问题,而不是我猜的 python 问题。:) 根据 API,Streams 可以是设备专有的,也可以不是设备专有的。例如,用于专业音频的 ASIO 通常是设备专有的,因此只有一个应用程序(如 DAW)可以访问它。例如,在 Windows 上,您可以打开和关闭它,如下所示:

https://help.ableton.com/hc/en-us/articles/209770485-Disabling-exclusive-mode-for-ASIO-interfaces

大多数 Python 包(如 pyaudio 等)只是为 portaudio 提供绑定,这很繁重,所以还请查看 portaudio 文档。Portaudio “组合”了所有不同的 API,如 ASIO、ALSA、WASAPI、Core Audio 等。

要让 ALSA 同时创建多个 Stream,您可能需要 dmix,请查看以下 Stackoverflow 问题: https ://unix.stackexchange.com/questions/355662/alsa-doesnt-work-when-multiple-applications -打开

于 2020-08-23T12:27:20.117 回答