2018年6月1日 星期五

多個process,共用麥克風Microphone 資源 - pulseaudio

環境: Ubuntu 14.04
Kernel: 3.10

查了谷歌後,其實有用pulseaudio的話,
就能簡單達到可以多個process,共用一個麥克風
用 arecord -L 查找,然後看"default"
default                                                                                                                                                                      
    Playback/recording through the PulseAudio sound server
不用pulseaudio的話,可以自行設定,如下的 .asoundrc
但只能用alsa相關的api,ex:sample code
用python的話,就有些問題@@, 因為它是呼叫pyaudio,
後來因整合因素,一邊用C,一邊用python來寫,
所以後來還是用了default比較快

keyword:
dsnoop: 能多個process來錄音
dmix   : 能多個process來放音

alsa-lib以/usr/share/alsa/alsa.conf的文件作為主要的入口點在裡面,
會看到兩個其它路徑:
/etc/asound.conf 和 /home/usrname/.asroundrc

.asroundrc內容是要自已加入: (模擬一個slave來使用,以達到可以多個process來呼叫)
pcm.dsnoop_test {
    type dsnoop
    ipc_key 4370927 # must be unique for all dsnoop plugins!!!!
    slave {
        pcm "hw:1,0"
 channels 1
 period_size 1024
 buffer_size 4096
 rate 16000
 periods 0 
 period_time 0
    }
}
Sample Code

用 arecord -L 可以得到device list,應該會顯示dsnoop_test,但沒任何的說明
或 下面這個程式 (ref: 树莓派Raspberry Pi中使用PyAudio实现语音捕获及回放)
#!/usr/bin/python3
# -*- coding:utf-8 -*-
import pyaudio
po = pyaudio.PyAudio()
for index in range(po.get_device_count()): 
    desc = po.get_device_info_by_index(index)
    #print desc
    print("index:%-5d  maxInputChannels: %-5d  device: %-40s  rate: %-10d" %  (index, desc["maxInputChannels"], desc["name"],  int(desc["defaultSampleRate"])))
啟動pyaudio時,會看到很多Unable to find definition訊息, 這些訊息可以透過/usr/share/alsa/alsa.conf把一些不會用到的interface關掉 ex:
ALSA lib confmisc.c:1286:(snd_func_refer) Unable to find definition 'cards.atm7059_link.pcm.surround40.0:CARD=0'                                                             
ALSA lib conf.c:4248:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory                                                                
ALSA lib conf.c:4727:(snd_config_expand) Evaluate error: No such file or directory

關掉不必要的
#
#  PCM interface
#
# redirect to load-on-demand extended pcm definitions
pcm.cards cards.pcm
pcm.default cards.pcm.default
#pcm.sysdefault cards.pcm.default
#pcm.front cards.pcm.front
#pcm.rear cards.pcm.rear
#pcm.center_lfe cards.pcm.center_lfe
#pcm.side cards.pcm.side
#pcm.surround40 cards.pcm.surround40
#pcm.surround41 cards.pcm.surround41
#pcm.surround50 cards.pcm.surround50
#pcm.surround51 cards.pcm.surround51
#pcm.surround71 cards.pcm.surround71
#pcm.iec958 cards.pcm.iec958
#pcm.spdif iec958
#pcm.hdmi cards.pcm.hdmi
#pcm.dmix cards.pcm.dmix
pcm.dsnoop cards.pcm.dsnoop
#pcm.modem cards.pcm.modem
#pcm.phoneline cards.pcm.phoneline
錄音 input_device_index就依上面的python code選擇,
開啟錄音程式的同時,再用上面的python code會發現,
所選用的index會暫時不見 這代表其它程式就不能用了,
目前知道defaultdsnoop可以讓多個程式使用
# -*- coding:utf-8 -*-
import os
import pyaudio
import wave
import sys

CHUNK = 512
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True, input_device_index=2,
                frames_per_buffer=CHUNK)

print("* recording")

frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)

print("* done recording")

stream.stop_stream()
stream.close()
p.terminate()

wf_path = os.path.join(sys.path[0], WAVE_OUTPUT_FILENAME)
wf = wave.open(wf_path, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
print(wf_path)

ref:
树莓派Raspberry Pi中使用PyAudio实现语音捕获及回放
Alsa Opensrc Org
Asoundrc

沒有留言:

張貼留言