用python生成一边录音一边显示MFCC画布PyQt5的多线程程序
时间: 2024-05-01 07:16:23 浏览: 9
以下是一个用Python生成一边录音一边显示MFCC画布的PyQt5多线程程序的示例:
```python
import sys
import numpy as np
import pyaudio
import wave
import librosa
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
class AudioRecorder(QObject):
finished = pyqtSignal()
update_mfcc = pyqtSignal(np.ndarray)
def __init__(self):
super().__init__()
self.chunk = 1024
self.format = pyaudio.paInt16
self.channels = 1
self.rate = 44100
self.frames = []
self.p = pyaudio.PyAudio()
self.stream = None
self.is_recording = False
def start_recording(self):
self.is_recording = True
self.stream = self.p.open(format=self.format, channels=self.channels,
rate=self.rate, input=True,
frames_per_buffer=self.chunk)
while self.is_recording:
data = self.stream.read(self.chunk)
self.frames.append(data)
samples = np.frombuffer(data, dtype=np.int16)
mfcc = librosa.feature.mfcc(y=samples, sr=self.rate)
self.update_mfcc.emit(mfcc)
self.stream.stop_stream()
self.stream.close()
self.p.terminate()
wf = wave.open("recording.wav", 'wb')
wf.setnchannels(self.channels)
wf.setsampwidth(self.p.get_sample_size(self.format))
wf.setframerate(self.rate)
wf.writeframes(b''.join(self.frames))
wf.close()
self.finished.emit()
def stop_recording(self):
self.is_recording = False
class MFCCCanvas(FigureCanvas):
def __init__(self, parent=None, width=5, height=4, dpi=100):
self.fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = self.fig.add_subplot(111)
self.axes.set_title("MFCC")
self.axes.set_xlabel("Time")
self.axes.set_ylabel("MFCC Coefficients")
super().__init__(self.fig)
def update_figure(self, mfcc):
self.axes.clear()
librosa.display.specshow(mfcc, x_axis='time', ax=self.axes)
self.draw()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Audio Recorder")
self.setFixedSize(500, 500)
self.record_button = QPushButton("Record", self)
self.record_button.setGeometry(QRect(200, 400, 100, 50))
self.record_button.clicked.connect(self.record_button_clicked)
self.mfcc_canvas = MFCCCanvas(self)
self.mfcc_canvas.setGeometry(QRect(50, 50, 400, 300))
self.audio_recorder = AudioRecorder()
self.audio_recorder.update_mfcc.connect(self.mfcc_canvas.update_figure)
self.audio_recorder.finished.connect(self.record_finished)
self.threadpool = QThreadPool()
def record_button_clicked(self):
if self.audio_recorder.is_recording:
self.audio_recorder.stop_recording()
self.record_button.setText("Record")
else:
self.record_button.setText("Stop")
self.threadpool.start(self.audio_recorder.start_recording)
def record_finished(self):
QMessageBox.information(self, "Finished", "Recording has finished.")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
```
这个程序使用PyAudio库来录制音频,每次录制一小段音频,然后计算其MFCC特征并将其显示在画布上。程序还包含一个按钮,用于开始和停止录音。当录音完成时,程序会将录制的音频保存到名为“recording.wav”的WAV文件中。程序还使用PyQt5的QThreadPool类来管理多个线程,以便在录制音频时不会阻塞用户界面。