Berbagi aliran audio mikrofon di Linux

Aug 23 2020

Sebanyak yang penting skenario saya mengembangkan aplikasi aksesibilitas bukan segala jenis penyadapan berbahaya, sedangkan dalam skenario ini ada berbagai skenario tersirat penelitian dan pengembangan, yang semuanya akan sangat diuntungkan dari kemampuan membaca aliran audio mikrofon oleh banyak orang. secara bersamaan menjalankan proses yang tidak terkait seperti alat perekam dan / atau versi berbeda dari kode saya sendiri.

Pernyataan masalah

Saya membaca aliran input mikrofon menggunakan API python tingkat tinggi seperti berikut:

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)

Saya ingin mempelajari apakah mungkin (di linux) membaca streaming audio mikrofon secara bersamaan ke program lain seperti Google Meet / Zoom membacanya. Yaitu berbagi aliran audio secara efektif.

Seperti halnya dengan pembungkus python yang disebutkan, tidak mengherankan bahwa ketika kode di atas dimulai saat panggilan video sedang berlangsung, itu hanya akan gagal untuk membuka aliran:

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

Memang, saya tidak terlalu fasih dengan terminologi ALSA dan secara umum tumpukan suara di linux.

Pertanyaan saya adalah, dapatkah ini dilakukan secara langsung menggunakan ALSA library API, atau melalui tumpukan suara atau konfigurasi sistem suara lainnya? Atau jika semuanya tidak dimaksudkan untuk berfungsi, melalui program / driver proxy yang mampu mengekspos buffer audio ke banyak konsumen tanpa menimbulkan penurunan yang nyata dalam latensi streaming audio?

Jawaban

5 MatthewSalvatoreViglione Aug 26 2020 at 02:14

Anda dapat melakukannya secara langsung dengan ALSA. Dsnoop harus melakukan triknya. Ini adalah plugin yang disertakan dengan ALSA yang memungkinkan berbagi aliran input.

Dari halaman yang saya tautkan di atas:

dsnoopsetara dengan dmixplugin, tetapi untuk merekam suara. The dsnoopPlugin memungkinkan beberapa aplikasi untuk merekam dari perangkat yang sama secara bersamaan.

Dari dokumen ALSA :

Jika Anda ingin menggunakan beberapa klien input (menangkap), Anda perlu menggunakan plugin dsnoop:

Anda dapat melihat-lihat di sana untuk mengetahui detail tentang cara menggunakannya. Ini masalah pada GitHub juga akan membantu Anda memulai, rincian bagaimana untuk mengkonfigurasi dsnoopantarmuka sehingga Anda dapat membaca dari itu dengan pyaudio.

Memperbarui

Untuk mengkonfigurasi ALSA, edit /etc/asound.confdengan sesuatu seperti ini (dari dokumen ALSA di 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
         }
 }

Anda dapat menguji untuk melihat apakah konfigurasi Anda berfungsi dengan sesuatu seperti ini:

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

Jadi, ini lebih merupakan pertanyaan audio daripada pertanyaan python. :) Bergantung pada API, Streams dapat berupa perangkat eksklusif atau tidak. ASIO untuk audio profesional misalnya sering kali eksklusif perangkat, jadi hanya satu aplikasi (seperti DAW) yang memiliki akses ke sana. Di Windows misalnya, Anda dapat mengaktifkan dan menonaktifkannya seperti yang terlihat di sini:

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

Kebanyakan paket Python seperti pyaudio dan seterusnya hanya menyediakan binding untuk portaudio, yang melakukan pekerjaan berat, jadi lihat juga dokumentasi portaudio. Portaudio "menggabungkan" semua API yang berbeda seperti ASIO, ALSA, WASAPI, Core Audio, dan sebagainya.

Agar ALSA dapat membuat lebih dari satu Aliran pada saat yang sama Anda mungkin memerlukan dmix, lihat pertanyaan Stackoverflow ini: https://unix.stackexchange.com/questions/355662/alsa-doesnt-work-when-multiple-applications-are-opened