我正在编写一个程序,该程序使用pyaudio连续从麦克风获取输入,并且每5秒进行一些计算,之后它会在tkinter小部件中更新一些matplotlib图。 我到目前为止:
import threading
from array import array
from Queue import Queue, Full
import pyaudio
from matplotlib import pyplot as plt
import numpy as np
CHUNK_SIZE = 1000
MIN_VOLUME = 500
PLOT_CHUNK_SIZE = CHUNK_SIZE * 5
BUF_MAX_SIZE = CHUNK_SIZE * 10
PLOT_MAX_SIZE = PLOT_CHUNK_SIZE * 10
big_chunk = np.array( [])
def main():
stopped = threading.Event()
q = Queue(maxsize=int(round(BUF_MAX_SIZE / CHUNK_SIZE)))
plot_queue = Queue(maxsize=int(round(PLOT_MAX_SIZE / PLOT_CHUNK_SIZE)))
listen_t = threading.Thread(target=listen, args=(stopped, q))
listen_t.start()
record_t = threading.Thread(target=record, args=(stopped, q, plot_queue))
record_t.start()
plot_t = threading.Thread(target=plot_chunk, args=(stopped, plot_queue))
plot_t.start()
try:
while True:
listen_t.join(0.1)
record_t.join(0.1)
plot_t.join(0.1)
except KeyboardInterrupt:
stopped.set()
listen_t.join()
record_t.join()
plot_t.join()
def record(stopped, q, plot_queue):
global big_chunk, p, ready
while True:
if stopped.wait(timeout=0):
break
vol = max(q.get())
if vol >= MIN_VOLUME:
big_chunk = np.append(big_chunk, q.get())
print 'new chunk'
if len(big_chunk) > PLOT_CHUNK_SIZE-1:
plot_queue.put(big_chunk)
big_chunk = np.array( [])
else:
print "-",
def plot_chunk(stopped, plot_queue):
while True:
if stopped.wait(timeout=0):
break
features = plot_queue.get()
my_features = do_calculations(features)
plt.imshow(my_features)
def listen(stopped, q):
stream = pyaudio.PyAudio().open(
format=pyaudio.paInt16,
channels=1,
rate=44100,
input=True,
frames_per_buffer=1024,
)
while True:
if stopped.wait(timeout=0):
break
try:
q.put(array('h', stream.read(CHUNK_SIZE)))
except Full:
pass # discard
if __name__ == '__main__':
main()
我尝试用线程做它,除了绘图之外它工作正常。似乎matplotlib和tkinter不能使用线程和多处理将是最佳选择。所以我尝试了这个:
import Tkinter as Tk
import multiprocessing
from Queue import Empty, Full
import time
import pyaudio
import array
class GuiApp(object):
def __init__(self,q):
self.root = Tk.Tk()
self.root.geometry('300x100')
self.text_wid = Tk.Text(self.root,height=100,width=100)
self.text_wid.pack(expand=1,fill=Tk.BOTH)
self.root.after(100,self.CheckQueuePoll,q)
def CheckQueuePoll(self,c_queue):
try:
str = c_queue.get(0)
self.text_wid.insert('end',str)
except Empty:
pass
finally:
self.root.after(100, self.CheckQueuePoll, c_queue)
# Data Generator which will generate Data
def GenerateData(q):
for i in range(10):
print "Generating Some Data, Iteration %s" %(i)
time.sleep(0.1)
q.put("Some Data from iteration %s \n" %(i))
def listen( q):
CHUNK_SIZE = 100
stream = pyaudio.PyAudio().open(
format=pyaudio.paInt16,
channels=1,
rate=44100,
input=True,
frames_per_buffer=1024,
)
while True:
try:
q.put(array('h', stream.read(CHUNK_SIZE)))
except Full:
pass # discard
if __name__ == '__main__':
# Queue which will be used for storing Data
q = multiprocessing.Queue()
q2 = multiprocessing.Queue()
q.cancel_join_thread() # or else thread that puts data will not term
q2.cancel_join_thread() # or else thread that puts data will not term
gui = GuiApp(q)
t1 = multiprocessing.Process(target=GenerateData,args=(q,))
t2 = multiprocessing.Process(target=listen,args=(q2,))
t1.start()
t2.start()
gui.root.mainloop()
t1.join()
t2.join()
我收到以下错误:
q.put(array('h', stream.read(CHUNK_SIZE)))
TypeError: 'module' object is not callable
任何想法?
答案 0 :(得分:1)
问题是代码中的array
是一个模块,不可调用(如错误信息所示)。
将导入更改为
from array import array
或将您的代码更改为
array.array(...)