更快地绘制实时音频信号 [英] Faster plotting of real time audio signal

查看:54
本文介绍了更快地绘制实时音频信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一段代码,它从我的笔记本电脑的音频插孔获取实时音频信号,并在一些基本过滤后绘制其图形.我面临的问题是,随着程序的运行,实时绘图变得越来越慢.

I have a piece of code that takes real time audio signal from audio jack of my laptop and plots its graph after some basic filtering. The problem I am facing is that the real time plotting is getting slower and slower as the program is running ahead.

有什么建议可以使绘图更快并以恒定速率进行?我认为动画功能会使其运行起来更快,但无法根据我的要求进行公式化

import pyaudio
import numpy as np
import time
import matplotlib.pyplot as plt
import scipy.io.wavfile
from scipy.signal import butter, lfilter
import wave

plt.rcParams["figure.figsize"] = 8,4

RATE = 44100
CHUNK = int(RATE/2) # RATE / number of updates per second
#Filter co-efficients 
nyq = 0.5 * RATE
low = 3000 / nyq
high = 6000 / nyq
b, a = butter(7, [low, high], btype='band')

#Figure structure
fig, (ax, ax2) =plt.subplots(nrows=2, sharex=True)
x = np.linspace(1, CHUNK, CHUNK)
extent = [x[0] - (x[1] - x[0]) / 2., x[-1] + (x[1] - x[0]) / 2., 0, 1]



def soundplot(stream):
    t1=time.time()
    data = np.array(np.fromstring(stream.read(CHUNK),dtype=np.int32))
    y1 = lfilter(b, a, data)
    ax.imshow(y1[np.newaxis, :], cmap="jet", aspect="auto")
    plt.xlim(extent[0], extent[1])
    plt.ylim(-50000000, 50000000)
    ax2.plot(x, y1)
    plt.pause(0.00001)
    plt.cla()  # which clears data but not axes
    y1 = []
    print(time.time()-t1)
if __name__=="__main__":
    p=pyaudio.PyAudio()
    stream=p.open(format=pyaudio.paInt32,channels=1,rate=RATE,input=True,
                  frames_per_buffer=CHUNK)
    for i in range(RATE):
        soundplot(stream)
    stream.stop_stream()
    stream.close()
    p.terminate()

推荐答案

这需要一段时间才能发表评论,由于您要提出建议,我认为这是一个半完整的答案.如果您需要的不是这里面的知识,则可以在线获取更多有关使用matplotlib进行实时绘图的信息和示例.该库不是为此目的而设计的,但是有可能.

This is a little long for a comment, and since you're asking for suggestions I think it's a semi-complete answer. There's more info and examples online about getting realtime plotting with matplotlib, if you need ideas beyond what's here. The library wasn't designed for this, but it's possible.

第一步,分析代码.您可以使用

First step, profile the code. You can do this with

import cProfile
cProfile.run('soundplot(stream)')

这将显示大部分时间都花在了哪里.如果不这样做,我将给出一些提示,但是请注意,分析可能会显示其他原因.

That will show where most of the time is being spent. Without doing that, I'll give a few tips, but be aware that profiling may show other causes.

首先,您要消除函数soundplot 中多余的函数调用.以下两项都是不必要的:

First, you want to eliminate redundant function calls in the function soundplot. Both of the following are unnecessary:

plt.xlim(extent[0], extent[1])
plt.ylim(-50000000, 50000000)

它们可以在初始化代码中被调用一次. imshow 会自动更新它们,但是为了提高速度,您不应该每次都调用它.相反,在某些初始化代码外部中,该函数使用 im = imshow(data,...),其中data与您要绘制的大小相同(尽管可能不需要).然后,在 soundplot 中使用 im.set_data(y1[np.newaxis, :]).不必每次迭代都重新创建图像对象将大大加快速度.

They can be called once in initialization code. imshow updates these automatically, but for speed you shouldn't call that every time. Instead, in some initialization code outside the function use im=imshow(data, ...), where data is the same size as what you'll be plotting (although it may not need to be). Then, in soundplot use im.set_data(y1[np.newaxis, :]). Not having to recreate the image object each iteration will speed things up immensely.

由于图像对象在每次迭代中都保留着,因此您还需要删除对 cla()的调用,并用 show() draw()以使图形绘制更新的图像.您可以使用 line.set_ydata(y) 对第二个轴上的线执行相同操作.

Since the image object remains through each iteration, you'll also need to remove the call to cla(), and replace it with either show() or draw() to have the figure draw the updated image. You can do the same with the line on the second axis, using line.set_ydata(y).

请发布之前和之后的汇率,并告诉我是否有帮助.

Please post the before and after rate it runs at, and let me know if that helps.

编辑:对相似代码的一些快速分析表明速度提高了100-500倍,主要是因为删除了 cla().

some quick profiling of similar code suggests a 100-500x speedup, mostly from removing cla().

还要查看您的代码,其速度变慢的原因是从未在第一轴上调用 cla .最终将在该轴上绘制数百张图像,从而使 matplotlib 变得缓慢.

Also looking at your code, the reason for it slowing down is that cla isn't ever called on the first axis. Eventually there will be hundreds of images drawn on that axis, slowing matplotlib to a crawl.

这篇关于更快地绘制实时音频信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆