用Python制作一边播放音频文件一边分段显示FFT波形pyqt5带按键的多线程程序
时间: 2024-05-14 19:11:52 浏览: 217
FFT.zip_fft_fft python_python FFT程序_python fft
以下是一个用Python制作一边播放音频文件一边分段显示FFT波形pyqt5带按键的多线程程序的示例代码:
```python
import sys
import os
import wave
import numpy as np
import pyaudio
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.uic import loadUi
class AudioPlayer(QThread):
signalFFT = pyqtSignal(np.ndarray)
def __init__(self, file_path):
super().__init__()
self.file_path = file_path
self.chunk_size = 1024
self.p = pyaudio.PyAudio()
self.stream = None
self.wf = None
def run(self):
self.wf = wave.open(self.file_path, 'rb')
self.stream = self.p.open(format=self.p.get_format_from_width(self.wf.getsampwidth()),
channels=self.wf.getnchannels(),
rate=self.wf.getframerate(),
output=True)
while True:
data = self.wf.readframes(self.chunk_size)
if not data:
break
self.stream.write(data)
data = np.frombuffer(data, dtype=np.int16)
fft_data = np.abs(np.fft.fft(data))[:self.chunk_size // 2]
self.signalFFT.emit(fft_data)
self.stream.close()
self.p.terminate()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
loadUi('mainwindow.ui', self)
self.audio_thread = None
self.play_button.clicked.connect(self.play_audio)
self.stop_button.clicked.connect(self.stop_audio)
self.file_button.clicked.connect(self.open_file)
def open_file(self):
file_path, _ = QFileDialog.getOpenFileName(self, 'Open file', os.path.expanduser('~'))
if file_path:
self.file_path_label.setText(file_path)
def play_audio(self):
if not self.audio_thread:
file_path = self.file_path_label.text()
if file_path:
self.audio_thread = AudioPlayer(file_path)
self.audio_thread.signalFFT.connect(self.update_fft)
self.audio_thread.start()
def stop_audio(self):
if self.audio_thread:
self.audio_thread.terminate()
self.audio_thread = None
def update_fft(self, fft_data):
fft_data = fft_data / np.max(fft_data)
fft_data *= 255
fft_data = fft_data.astype(np.uint8)
image = QImage(fft_data, self.audio_plot.width(), self.audio_plot.height(), QImage.Format_Grayscale8)
pixmap = QPixmap.fromImage(image)
self.audio_plot.setPixmap(pixmap)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
```
这个程序使用了PyQt5来创建GUI界面,使用了PyAudio来播放音频文件和处理FFT。程序中有一个AudioPlayer类,继承自QThread,用来在一个单独的线程中播放音频文件,并实时计算FFT数据。AudioPlayer类中定义了一个signalFFT信号,用来在主线程中更新FFT图形。MainWindow类是程序的主窗口,其中包含了一个按键来选择音频文件,一个按键来开始播放音频文件,一个按键来停止播放音频文件,以及一个用来显示FFT图形的标签。当用户点击“播放”按钮时,程序会创建一个AudioPlayer实例并启动它的线程,在主线程中等待signalFFT信号,当这个信号被发射时,程序会将FFT数据转换为图像,并更新标签上的图像。当用户点击“停止”按钮时,程序会终止AudioPlayer线程。
阅读全文