Freigeben eines Mikrofon-Audiostreams unter Linux

Aug 23 2020

So wichtig es auch ist, mein Szenario ist die Entwicklung einer Barrierefreiheitsanwendung, nicht irgendeine Art von böswilligem Abhören, während es auch innerhalb dieses Szenarios verschiedene implizite Forschungs- und Entwicklungsszenarien gibt, die alle stark davon profitieren sollten, den Audiostream des Mikrofons mehrfach lesen zu können gleichzeitig ausgeführte nicht verwandte Prozesse wie Aufnahmewerkzeuge und/oder verschiedene Versionen meines eigenen Codes.

Problemstellung

Ich lese einen Mikrofoneingangsstrom mit einer Python-API auf hoher Ebene wie folgt:

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)

Ich würde gerne erfahren, ob es möglich ist (unter Linux), den Mikrofon-Audiostream gleichzeitig mit einem anderen Programm wie Google Meet / Zoom zu lesen. Dh den Audiostream effektiv teilen.

Wie bei dem erwähnten Python-Wrapper ist es keine große Überraschung, dass, wenn der obige Code gestartet wird, während ein Videoanruf läuft, der Stream einfach nicht geöffnet werden kann:

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

Zugegebenermaßen kenne ich mich mit der ALSA-Terminologie und generell dem Soundstack unter Linux noch nicht so gut aus.

Meine Frage ist, kann dies direkt mit der ALSA-Bibliotheks-API oder anderweitig über andere Sound-Stacks oder Soundsystemkonfigurationen erreicht werden? Oder wenn alles andere nicht funktionieren soll, über ein Proxy-Programm/einen Treiber, der in der Lage ist, einen Audiopuffer mehreren Verbrauchern zur Verfügung zu stellen, ohne dass es zu einer merklichen Verschlechterung der Audiostream-Latenz kommt?

Antworten

5 MatthewSalvatoreViglione Aug 26 2020 at 02:14

Sie können dies direkt mit ALSA tun. Dsnoop sollte den Trick machen. Es ist ein in ALSA enthaltenes Plugin, das die gemeinsame Nutzung von Eingabeströmen ermöglicht.

Von der Seite, die ich oben verlinkt habe:

dsnoopist das Äquivalent des dmixPlugins, aber zum Aufnehmen von Ton. Das dsnoopPlugin ermöglicht es mehreren Anwendungen, gleichzeitig vom selben Gerät aufzunehmen.

Aus den ALSA -Dokumenten :

Wenn Sie mehrere Input(Capture)-Clients verwenden möchten, müssen Sie das dsnoop-Plugin verwenden:

Sie können dort nach Details zur Verwendung suchen. Diese Ausgabe auf GitHub hilft Ihnen auch bei den ersten Schritten. Sie beschreibt, wie Sie die dsnoopSchnittstelle konfigurieren, damit Sie mit pyaudio.

Aktualisieren

Um ALSA zu konfigurieren, bearbeiten Sie /etc/asound.confFolgendes (ab ALSA-Dokumentationdsnoop ):

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
         }
 }

Sie können testen, ob Ihre Konfiguration mit etwas wie dem folgenden funktioniert:

arecord -d 30 -f cd -t wav -D pcm.mixin test.wav 
2 ArjaanAuinger Aug 23 2020 at 19:27

Das ist also eher eine Audio-Frage als eine Python-Frage, denke ich. :) Je nach API können Streams geräteexklusiv sein oder nicht. ASIO für professionelles Audio ist beispielsweise oft geräteexklusiv, sodass nur eine Anwendung (wie eine DAW) darauf zugreifen kann. Unter Windows können Sie dies beispielsweise wie hier gezeigt ein- und ausschalten:

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

Die meisten Python-Pakete wie pyaudio usw. stellen nur Bindungen für portaudio bereit, was die schwere Arbeit übernimmt, also werfen Sie auch einen Blick auf die portaudio-Dokumentation. Portaudio "kombiniert" all die verschiedenen APIs wie ASIO,ALSA,WASAPI,Core Audio und so weiter.

Damit ALSA mehr als einen Stream gleichzeitig erstellen kann, benötigen Sie möglicherweise dmix, werfen Sie einen Blick auf diese Stackoverflow-Frage:https://unix.stackexchange.com/questions/355662/alsa-doesnt-work-when-multiple-applications-are-opened