Sharing a microphone audio stream on Linux
Asked Answered
S

2

5

As much as it matters my scenario is developing an accessibility application not any kind of malicious eavesdropping, whereas also within this scenario there are various research and development implied scenarios, all of which should greatly benefit from being able to read the microphone audio stream by multiple simultaneously running unrelated processes such as recording tools and/or different versions of my own code.

Problem Statement

I am reading a microphone input stream using a high level python API like follows:

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)

I would like to learn whether it is possible (on linux) to read the microphone audio stream simultaneously to another program such as Google Meet / Zoom reading it. I.e. effectively share the audio stream.

As is with the mentioned python wrapper, it is no big surprise that when the above code is started while a video call is in progress, it will simply fail to open the stream:

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

Admittedly, I am not very well versed with ALSA terminology and in general the sound stack on linux yet.

My question is, can this be accomplished directly using ALSA library API, or otherwise via other sound stacks or sound system configuration? Or if all else is not meant to work, via a proxy program/driver that is able to expose an audio buffer to multiple consumers without incurring noticeable degradation in audio stream latency?

Sphingosine answered 22/8, 2020 at 22:53 Comment(3)
FYI, Dante Via is a product that does exactly this. Unfortunately it is only available for Windows and MacOS.Moresque
:-( Thanks :-) I wonder though what directions would come up as it may not seem to be impossible a-priori to me, I just need some help pointing me in the right direction with the right concepts and terminology.Sphingosine
Does this point you in the right direction re: an Alsa loopback device askubuntu.com/questions/895216/…Ottavia
K
6

You can do this directly with ALSA. Dsnoop should do the trick. It is a plugin included with ALSA that allows sharing input streams.

From the page I linked above:

dsnoop is the equivalent of the dmix plugin, but for recording sound. The dsnoop plugin allows several applications to record from the same device simultaneously.

From the ALSA docs:

If you want to use multiple input(capture) clients you need to use the dsnoop plugin:

You can poke around there for details on how to use it. This issue on GitHub will also help you get started, it details how to configure the dsnoop interface so you can read from it with pyaudio.

Update

To configure ALSA, edit /etc/asound.conf with something like this (from the ALSA docs on 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
         }
 }

You can test to see if your configuration works with something like this:

arecord -d 30 -f cd -t wav -D pcm.mixin test.wav 
Katharynkathe answered 25/8, 2020 at 19:14 Comment(7)
Thank you very much. Although I can't try this in the next few days, it looks like the best path to get dsnoop to work, even if my system does not show cards.pcm.dsnoop on the output of arecord -L as outlined in its main (?) docs.Sphingosine
I wonder if setting up a device can only be done via the command-line as per the specific config file locations on your linux flavor, since it is kind of a hardware configuration, v.s. something you can accomplish from code via some programming API related to dsnoop.Sphingosine
I could get from it the initial impression that this ALSA extension is not maintained very high velocity and some further augmentation to the bounty answer might potentially help offset in light of my reservations above.Sphingosine
You will have to apply this configuration before the sound card will show up.Katharynkathe
I'm not sure what you mean by "this ALSA extension is not maintained very high velocity". As far as I know, this is the proper way to do this.Katharynkathe
What is an actual command to share microphone stream?Latimore
Apparently setting the ipc_perm subkey to 0666 in /etc/asound.conf solved the issue I was having. Thanks to bugzilla.redhat.com/show_bug.cgi?id=174848#c6, pointed to by the Github link above.Steffi
P
2

So, this is more an audio question than a python question I guess. :) Depending on the API, Streams can be device exclusive or not. ASIO for professional audio for example is often device exclusive, so just one application(like a DAW) has access to it. On Windows for example you can turn this on and off as seen here:

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

Most Python packages like pyaudio and so on are just providing bindings for portaudio, which does the heavy lifting, so also have a look at the portaudio documentation. Portaudio "combines" all the different APIs like ASIO,ALSA,WASAPI,Core Audio, and so on.

For ALSA to create more than one Stream at the same time you might need dmix, have a look at this Stackoverflow question: https://unix.stackexchange.com/questions/355662/alsa-doesnt-work-when-multiple-applications-are-opened

Postulant answered 23/8, 2020 at 12:27 Comment(1)
Thanks. This relates to my question but doesn't point at any solution. I have already looked at PulseAudio quite a bit but nothing here relates to multiplexing input audio from a microphone.Sphingosine

© 2022 - 2024 — McMap. All rights reserved.