4

我正在尝试从音频流中获取样本并将它们放入共享队列中。我有另一个从这个队列中提取的进程。

当我运行时,我收到此错误:

* 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 上,我安装portaudiohomebrew尝试了pip`pyaudio 和 dmg 安装,但都没有运气。

4

1 回答 1

5

缓冲区溢出错误是因为您的 frames_per_buffer 和 read 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循环对延迟做了什么,但即使是使用和之间相对较小的性能改进也值得注意:arraynp.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
于 2013-11-13T06:43:39.697 回答