[英]python pyaudio using multiprocessing
我正在嘗試從音頻流中獲取樣本並將它們放入共享隊列中。 我有另一個從這個隊列中拉出來的進程。
當我跑,我得到這個錯誤:
* recording
Traceback (most recent call last):
File "record.py", line 43, in <module>
data = stream.read(CHUNK)
File "/Library/Python/2.7/site-packages/pyaudio.py", line 605, in read
return pa.read_stream(self._stream, num_frames)
IOError: [Errno Input overflowed] -9981
編輯:顯然問題已經存在一段時間沒有發布解決方案(我嘗試了他們的建議):
這是(簡化)代碼:
import pyaudio
import wave
import array
import time
from multiprocessing import Queue, Process
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 2
p = pyaudio.PyAudio()
left = Queue()
right = Queue()
def other(q1, q2):
while True:
try:
a = q1.get(False)
except Exception:
pass
try:
b = q2.get(False)
except Exception:
pass
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* recording")
Process(target=other, args=(left, right)).start()
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
byte_string = ''.join(data)
nums = array.array('h', byte_string)
for elt in nums[1::2]:
left.put(elt)
for elt in nums[0::2]:
right.put(elt)
print("* done recording")
stream.stop_stream()
stream.close()
print "terminated"
我究竟做錯了什么? 我在Mac OSX和Python 2.7上,我通過homebrew
安裝了portaudio
並嘗試了`pyaudio的pip
和dmg安裝,但沒有運氣。
緩沖區溢出錯誤是因為您的frames_per_buffer和讀取chunksize可能太小。 嘗試更大的值,即512,2048,4096,8192等
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 2
for CHUNK1 in [512,2048,4096,8192,16384]:
for CHUNK2 in [512,2048,4096,8192,16384]:
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK1)
try:
print CHUNK1,CHUNK2
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK2)
except:
print "Boohoo"
stream.stop_stream()
stream.close()
更新
好吧,我想我明白了。 如果你在下一次讀取之前等待太久,pyaudio庫將引發溢出錯誤。
byte_string = ''.join(data)
nums = array.array('h', byte_string)
for elt in nums[1::2]:
left.put(elt)
for elt in nums[0::2]:
right.put(elt)
這在這里做了很多很慢的處理。 特別是在python中的兩個for
循環。 讓處理過程得到一大塊單流數據,它可以處理,而不是一次一個int。
import numpy as np
...
n=np.fromstring(data,np.uint16)
left.put(n[1::2])
right.put(n[0::2])
我甚至不想想for
循環對延遲的影響,但即使使用array
和np.array
之間相對較小的性能提升值得注意:
a=array.array('h',s)
n=np.array(a)
In [26]: %timeit n[1::2]
1000000 loops, best of 3: 669 ns per loop
In [27]: %timeit n[1::2].copy()
1000 loops, best of 3: 725 us per loop
In [28]: %timeit a[1::2]
1000 loops, best of 3: 1.91 ms per loop
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.