音频频谱分析仪(4410值为15条)

时间:2017-06-10 22:58:42

标签: python numpy audio pyaudio spectrum

我想用Python制作音频频谱分析仪。我使用了pyaudio库,我正在从麦克风中读取流。对于每次读取,我得到4410个值,我使用numpy转换为数字,然后将它们绘制到pygame屏幕上。看起来像这样:https://photos.google.com/share/AF1QipMCWVk1pR0dmrrsTlpE3gHQ9GTUV25MqwUxw4JuW8TrItkGkuU9X3ZpY2ZQ-RLHew?key=UE9Id19IU1dtSHZfUk43TjB3SWxFcVhRRTFYOWFB(图表颠倒了) 我的代码是:

import pyaudio, math, struct,pygame, numpy
pa = pyaudio.PyAudio()
#open audio stream
stream = pa.open(input_device_index=1,rate=44100,format=pyaudio.paInt16,channels=2,input=True)    

#read bytes from stream and convert to numbers
def get_data():
    data = stream.read(int(44100*0.05))
    s = numpy.fromstring(data, numpy.int16)
    return struct.unpack('h'*4410, data)



pygame.init()
screen = pygame.display.set_mode((4000,1000))

def redraw():
    data = get_data() 
    #draw every number as a bar onto pygame windows
    #last 4410 values are missin      
    for x in range(4000):            
        val = data[x]           
        pygame.draw.rect(screen,(0,0,0),(x,0,1,1000),0)                      
        pygame.draw.rect(screen,(255,255,255),(x,0,1,val),0)


    pygame.display.update()
    pygame.event.clear()

while 1:    
    redraw()

有没有任何奇特的方法将这些4410值合并到15,所以我可以拥有漂亮的&凉爽的绿色&合理大小的窗口中的红色条形图,而不是需要3个屏幕的丑陋的东西?

1 个答案:

答案 0 :(得分:2)

频率与时域

如上所述,您的代码会绘制样本的time-domain表示,而频谱分析器则是frequency domain表示。

时间< - >可以使用Discrete Fourier Transform实现频域转换。实际上,您需要在转换之前将Window function应用于数据。

DFT的输出是一系列大小相等的频率箱,每个频率箱包含实部和虚部。频谱分析仪通常具有相等感知宽度的频带 - 也就是说,相同数量的八度音程(或八度音程的分数)。因此,每个频带的频率区间将是之前的频率区间的两倍。 15个频段相当于每个频段2/3个八度音阶。

图形输出说明

您已经渲染了时域样本,每个样本水平使用一个像素,并且幅度直接映射到Y坐标。由于幅度范围为-32767 < x < 32768,因此绝大多数样本将小于或大于显示屏中提供的范围0 <= x < 4000 - 因此大多数样本将被裁剪为0或{ {1}}。

您可以通过缩放样本以使结果适合3999来对此结果进行更正,以便500的样本值呈现为0的Y坐标。