我有一个带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幅度的最大值与之接近。这怎么可能?
谢谢