用python生成一边录音一边播音一边显示FFT画布PyQt5的多线程程序
时间: 2023-09-04 19:16:05 浏览: 99
以下是一个使用Python和PyQt5生成一边录音一边播音一边显示FFT画布的多线程程序:
```python
import sys
import time
import numpy as np
import pyqtgraph as pg
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton
from PyQt5.QtCore import QThread, pyqtSignal
import sounddevice as sd
class AudioRecorder(QThread):
# 定义信号,传递录音数据
audio_data = pyqtSignal(np.ndarray)
def __init__(self, sample_rate=44100, channels=1):
super().__init__()
self.sample_rate = sample_rate
self.channels = channels
self.chunk_size = 1024
def run(self):
with sd.InputStream(samplerate=self.sample_rate, channels=self.channels, blocksize=self.chunk_size) as stream:
while True:
data, _ = stream.read(self.chunk_size)
self.audio_data.emit(data)
class AudioPlayer(QThread):
# 定义信号,传递播放数据
play_data = pyqtSignal(np.ndarray)
def __init__(self, sample_rate=44100, channels=1):
super().__init__()
self.sample_rate = sample_rate
self.channels = channels
def run(self):
while True:
data = np.zeros((1024, self.channels), dtype=np.float32)
self.play_data.emit(data)
time.sleep(0.01)
class AudioAnalyzer(QThread):
# 定义信号,传递FFT数据
fft_data = pyqtSignal(np.ndarray)
def __init__(self, sample_rate=44100, channels=1):
super().__init__()
self.sample_rate = sample_rate
self.channels = channels
self.chunk_size = 1024
def run(self):
while True:
data = np.zeros((self.chunk_size, self.channels), dtype=np.float32)
fft = np.fft.fft(data)
fft = np.abs(fft[:len(fft) // 2])
self.fft_data.emit(fft)
time.sleep(0.01)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# 创建GUI元素
self.audio_label = QLabel("Audio")
self.play_button = QPushButton("Play")
self.fft_plot = pg.PlotWidget()
# 创建线程
self.recorder = AudioRecorder()
self.player = AudioPlayer()
self.analyzer = AudioAnalyzer()
# 连接信号和槽函数
self.recorder.audio_data.connect(self.analyzer.data)
self.analyzer.fft_data.connect(self.fft_plot.plot)
self.player.play_data.connect(self.audio_label.setText)
# 启动线程
self.recorder.start()
self.player.start()
self.analyzer.start()
# 创建布局
audio_layout = QHBoxLayout()
audio_layout.addWidget(self.audio_label)
audio_layout.addWidget(self.play_button)
main_layout = QVBoxLayout()
main_layout.addLayout(audio_layout)
main_layout.addWidget(self.fft_plot)
self.setLayout(main_layout)
self.setWindowTitle("Audio Analyzer")
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
```
该程序中包含三个线程:`AudioRecorder`、`AudioPlayer`和`AudioAnalyzer`。`AudioRecorder`用于录制音频数据并将其传递给`AudioAnalyzer`进行FFT分析;`AudioPlayer`用于播放音频数据;`AudioAnalyzer`用于对录制的音频数据进行FFT分析,并将结果传递给GUI线程,以在`fft_plot`上显示FFT图像。
在`MainWindow`类的构造函数中,创建了GUI元素和线程,并将它们连接起来。最后,启动线程并显示GUI窗口。
阅读全文