用python生成一边录音一边显示FFT画布canvas的多线程程序
时间: 2024-05-02 11:21:37 浏览: 197
以下是一个使用Python实现一边录音一边显示FFT画布的多线程程序的示例。该程序使用PyAudio库进行音频录制和FFT计算,使用matplotlib库进行画布绘制。
```python
import pyaudio
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import threading
# 录音参数
CHUNK = 1024 # 每个缓冲区的大小
FORMAT = pyaudio.paInt16 # 录音格式
CHANNELS = 1 # 声道数
RATE = 44100 # 采样率
RECORD_SECONDS = 10 # 录音时长
# 创建PyAudio对象
p = pyaudio.PyAudio()
# 创建一个用于存储录音数据的队列
audio_queue = []
# 创建一个用于存储FFT数据的队列
fft_queue = []
# 创建一个用于控制线程运行的事件
stop_event = threading.Event()
# 录音线程函数
def record_thread():
stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK)
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
# 从音频流中读取数据
data = stream.read(CHUNK)
# 将数据存入队列
audio_queue.append(data)
# 如果队列中的数据过多,则清空队列
if len(audio_queue) > 10:
audio_queue.clear()
# 如果线程被要求停止,则跳出循环
if stop_event.is_set():
break
# 关闭音频流
stream.stop_stream()
stream.close()
# FFT线程函数
def fft_thread():
while not stop_event.is_set():
# 如果队列中有录音数据,则进行FFT计算
if len(audio_queue) > 0:
# 从队列中取出录音数据
data = audio_queue.pop(0)
# 将数据转换为numpy数组
np_data = np.frombuffer(data, dtype=np.int16)
# 进行FFT计算
fft_data = np.abs(np.fft.fft(np_data))[:int(CHUNK / 2)]
# 将FFT数据存入队列
fft_queue.append(fft_data)
# 如果队列中的数据过多,则清空队列
if len(fft_queue) > 10:
fft_queue.clear()
# 绘图线程函数
def plot_thread():
# 创建一个Figure对象和一个Axes对象
fig, ax = plt.subplots()
# 创建一个空的线条对象用于实时绘制FFT数据
line, = ax.plot([], [])
# 设置Axes对象的坐标轴范围和标签
ax.set_xlim(0, CHUNK / 2)
ax.set_ylim(0, 20000)
ax.set_xlabel('Frequency (Hz)')
ax.set_ylabel('Amplitude')
# 动画更新函数
def update(frame):
# 如果队列中有FFT数据,则绘制最新的FFT数据
if len(fft_queue) > 0:
# 从队列中取出最新的FFT数据
fft_data = fft_queue.pop(-1)
# 更新线条数据
line.set_data(np.arange(len(fft_data)) * (RATE / CHUNK), fft_data)
return line,
# 创建一个动画对象
anim = FuncAnimation(fig, update, blit=True)
# 显示画布
plt.show()
# 创建录音线程、FFT线程和绘图线程
record_thread = threading.Thread(target=record_thread)
fft_thread = threading.Thread(target=fft_thread)
plot_thread = threading.Thread(target=plot_thread)
# 启动录音线程、FFT线程和绘图线程
record_thread.start()
fft_thread.start()
plot_thread.start()
# 等待录音线程、FFT线程和绘图线程完成
record_thread.join()
fft_thread.join()
plot_thread.join()
# 关闭PyAudio对象
p.terminate()
```
该程序使用三个线程分别进行录音、FFT计算和画布绘制。录音线程通过PyAudio库从麦克风中读取音频数据,并将数据存入一个队列中。FFT线程从音频数据队列中取出数据,进行FFT计算,并将结果存入另一个队列中。画布绘制线程从FFT数据队列中取出最新的FFT数据,实时更新画布。程序使用了Python内置的threading模块进行多线程编程,并使用了matplotlib库进行画布绘制。
阅读全文