首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python示波器

Python示波器
EN

Stack Overflow用户
提问于 2019-03-07 18:57:34
回答 1查看 2.5K关注 0票数 0

我正在尝试用python创建一个程序,它可以通过现场音频(通过麦克风)创建示波器。

普通示波器的不同之处在于,它只显示一个波长,例如(期望的输出):

这显示了三个不同的波长,以及它们将如何在节目中显示。

我迄今取得的进展:

  1. 我已经创建了一个程序来显示一个图形,并清除和重新绘制它
  2. 然后,我创建了一个程序,它将显示声音实况(尽管它非常慢,如果可能的话,最好是修复)。

代码1:

代码语言:javascript
复制
import matplotlib.pyplot as plt
import time

plt.ion()

#y1 is the data
y1 = [0,0.309,0.587,0.809,0.951,1,0.951,0.809,0.587,0.309,0, -0.309, -0.587, -0.809, -0.951, -1, -0.951, -0.809, -0.587, -0.309, 0]

plt.plot(y1, 'r.-') #Graph with data
plt.plot([0 for _ in y1]) #Straight line at y=0

while True:
    #Update data to new data
    #y1 = new data
    plt.plot(y1, 'r.-') #Graph with data
    plt.plot([0 for _ in y1]) #Straight line at y=0
    plt.draw()
    plt.pause(0.5) #Time for one wave? Need some way to find this...
    plt.clf()

代码2:

代码语言:javascript
复制
import pyaudio
import numpy as np
import matplotlib.pyplot as plt
import time

RATE = 44100
CHUNK = int(RATE/20) # RATE / number of updates per second

def soundplot(stream):
    t1=time.time()
    data = np.fromstring(stream.read(CHUNK),dtype=np.int16)
    plt.pause(0.1) #To draw graph!
    plt.clf()
    plt.plot(data)
    plt.draw()
    plt.axis([0,len(data),-2**16/2,2**16/2])
    print("took %.02f ms"%((time.time()-t1)*1000))

if __name__=="__main__":
    p=pyaudio.PyAudio()
    stream=p.open(format=pyaudio.paInt16,channels=1,rate=RATE,input=True,
                  frames_per_buffer=CHUNK)
    for i in range(int(20*RATE/CHUNK)): #do this for 10 seconds
        soundplot(stream)
    stream.stop_stream()
    stream.close()
    p.terminate()

编辑:为了说明清楚,我想要的结果是显示图片中的一个单一波长,而不是第二个代码产生的多重波长。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-07 19:08:22

若要显示单个波长,请先向前扫描,直到找到非负数据点为止。(这将在第一个条目和代码#1中的数据中立即发生。)

然后继续向前扫描在时间,并保持一个三角洲之间的连续样品。最初,当曲线接近最大值时,δ(或离散导数)为正,然后变为负值,直到达到一分钟,然后再次变为正。

当遇到非负数据点且增量为正时,停止前向扫描。在这一点上,你有一个完整的波长。

编辑:

如果您有大量的数据,那么可以跳过一些前导数据示例。这里的关键是我们想要找到一个带正导数的过零点,然后继续,直到我们找到另一个带正导数的过零点。因此,第一项决定既要寻找一个非负数据点,又要坚持正数据点。

在存在噪声的情况下,我们可能会比波形的周期更多地看到δ上的符号变化。因此,第一步可能是找到一堆样本的最小值和最大值(这意味着一个范围),然后选择任意阈值,如min + .25 *范围和min + .75 *范围,记录第一个正零交叉,等待信号超过高阈值,等待它降到低阈值以下(在负过零之后),然后记录下一个正零交叉。这就给出了波长的估计。如果你觉得这样做有帮助的话,就重复估计,然后取一些方便的汇总,比如平均值或者(更好)中值。

使用波长估计,您可以更好地评估一对正零交叉是否“正确”,还是由于噪音。拒绝那些比你估计的要近得多的对。你可能还会发现计算光滑导数很方便,因此,你可以用最后两个点(K=2)的增量来平均计算最后的K点,也许是其中的6个点。平均函数是一个抗高频噪声的低通滤波器。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55050976

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档