Python - 示波器

问题描述 投票:0回答:1

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

与普通示波器的不同之处在于,它仅显示一个波长,例如(所需输出):

Output Example

这显示了三种不同的波长,以及它们如何在程序中显示。

我到目前为止的进展:

  1. 我已经创建了一个程序来显示图形并清除和重绘它
  2. 然后我创建了一个程序,它将显示现场的声音(虽然它很慢,如果可能的话理想情况下会被修复)

代码#1:

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:

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()

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

python python-3.x audio microphone oscilloscope
1个回答
1
投票

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

然后继续向前扫描,并在连续样本之间保持增量。最初,当曲线接近其最大值时,delta(或离散导数)将为正,然后将变为负值直到达到最小值,然后将再次变为正值。

遇到非负数据点并且增量为正数时,请及时停止扫描。那时你有一个完整的波长。

编辑:

如果您有大量数据,则可以跳过一些前导数据样本。这里的关键是我们想找到一个带正导数的零交叉,然后继续前进,直到找到另一个带正导数的零交叉。因此,第一个决策应该同时寻找非负数据点并坚持正delta。

在存在噪声的情况下,我们可能会看到delta上的符号变化比波形周期更频繁。因此,最初的步骤可能是找到一堆样本的最小值和最大值(意味着一个范围),然后选择任意阈值,如min + .25 * range和min + .75 * range,记录第一个正零过,等待如果信号超过高阈值,等待它低于低阈值(在负过零点之后),然后记录下一个正零过零点。这可以估算出波长。如果您发现有用,请重复估算,并采取一些方便的汇总,如均值或(更好)中位数。

通过波长估计,您可以更好地评估一对正过零点是否“正确”或由于噪声。拒绝与您的估计建议的距离更近的对。您可能还会发现计算平滑导数很方便,因此,不是看到最后两个点的差值(K = 2),而是对最后K个点进行平均,可能是其中的六个点。平均功能是低通滤波器,可抑制高频噪声。

© www.soinside.com 2019 - 2024. All rights reserved.