用python生成一边录音一边显示FFT画布canvas.draw()的多线程程序
时间: 2024-05-06 20:22:12 浏览: 100
FFT.zip_fft_fft python_python FFT程序_python fft
以下是一个使用PyAudio和matplotlib库实现一边录音一边显示FFT画布的多线程程序:
```python
import pyaudio
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import QThread, pyqtSignal
CHUNK_SIZE = 1024
FORMAT = pyaudio.paFloat32
CHANNELS = 1
RATE = 44100
FFT_SIZE = 2048
class AudioThread(QThread):
signal = pyqtSignal(np.ndarray)
def __init__(self):
super().__init__()
self.p = pyaudio.PyAudio()
self.stream = self.p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK_SIZE)
def run(self):
while True:
data = np.frombuffer(self.stream.read(CHUNK_SIZE), dtype=np.float32)
self.signal.emit(data)
def close(self):
self.stream.stop_stream()
self.stream.close()
self.p.terminate()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Real-time FFT")
self.setGeometry(100, 100, 800, 600)
self.fig, self.ax = plt.subplots()
self.canvas = FigureCanvas(self.fig)
self.setCentralWidget(self.canvas)
self.audio_thread = AudioThread()
self.audio_thread.signal.connect(self.update_canvas)
self.audio_thread.start()
def update_canvas(self, data):
fft = np.abs(np.fft.fft(data, n=FFT_SIZE))
freqs = np.fft.fftfreq(FFT_SIZE, 1/RATE)[:FFT_SIZE//2]
self.ax.clear()
self.ax.plot(freqs, fft[:FFT_SIZE//2])
self.ax.set_xlim(0, 5000)
self.ax.set_ylim(0, 100)
self.canvas.draw()
def closeEvent(self, event):
self.audio_thread.close()
self.audio_thread.wait()
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
```
程序首先定义了一些常量,如音频数据的块大小、格式、通道数、采样率和FFT大小。它创建了一个名为AudioThread的QThread子类,该子类负责从音频流中读取数据并发出信号以更新绘图画布。MainWindow类是一个简单的窗口应用程序,它使用matplotlib创建一个绘图画布,并在启动时启动AudioThread线程。update_canvas方法是用于更新绘图画布的槽函数,它将输入数据的FFT计算和绘图操作放入matplotlib的绘图区域中,并调用canvas.draw()方法以更新画布。
注意,在关闭主窗口时,必须注意正确关闭音频线程以避免资源泄漏。closeEvent方法是在主窗口关闭时调用的,它调用AudioThread的close方法以停止音频流并等待线程结束。
阅读全文