用Pyaudio录制后标准化FFT

时间:2019-08-09 18:27:17

标签: python fft pyaudio

我有一个带24位ADC的USB麦克风,但是Pyaudio不允许24位编码,因此我使用了16位。我希望这不是问题。话虽如此,我希望确保我正确地应用了Hanning窗口并正确地标准化了FFT幅度。

import numpy as np
import pyaudio
import matplotlib.pyplot as plt
from scipy.fftpack import fft
from scipy.io import wavfile # get the api
import wave

CHUNK = 2048
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 20480
RECORD_SECONDS = 34

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

n = CHUNK
k=np.arange(n)
T = n/RATE     #reciprocal of freq resolution
frq = k/T      #k* freq resolution
frq = frq[range(int(n/2))]    # one side frequency range, for plotting
freq_resolution=RATE/n        #frequency resolution 
window=np.hanning(n)          #Hanning window 
num_frames=int(RATE*RECORD_SECONDS/CHUNK)

for i in range(0, num_frames):
    data = stream.read(CHUNK)
    decoded = np.frombuffer(data, dtype=np.int16)
    windowed=window*decoded      #apply Hanning window
    fft_decode=fft(windowed)/(len(decoded)/2)
    mags=np.absolute(fft_decode) 

    plt.ylim(top=2)
    plt.xlabel('Freq (Hz)')
    plt.ylabel('|Y(freq)|')
    plt.plot(frq), mags[range(int(n/2))],'b') 
    plt.pause(.001)
    plt.gcf().clear()
plt.close()

我通过(样本数/ 2)对幅度进行归一化,因为我只对单侧图感兴趣,并且我希望幅度与真实信号相对应。这意味着真实信号为5 sin(2pi * 3000 * t),我要在3000hz一侧幅值图上将幅值设为5。如果我仅将样本数除以,那将是该值的一半。这是正确的吗?

但是,我还打印出循环中每次迭代的最大数据(已解码)和fft大小的最大值,尽管它们大多是相关的,但有时却不相关。我可能会获得较高的“已解码”最大值(例如32000),但fft幅度的最大值与之接近。这怎么可能?

谢谢

0 个答案:

没有答案