如何解决使用定义的 FFT 长度、块大小和波形文件的窗口计算 FFT
我有一个以 48KHz 采样率记录 5 秒的 32 位浮点 .wav 文件。我想在应用汉宁窗的情况下获得完整 5 秒的 FFT,没有重叠,并且 FFT 长度为 8192。在获得 FFT 时,我意识到我在 FFT 计算中犯了一个错误。
我使用以下代码来执行此操作:
# Imports
import matplotlib.pyplot as plt
import numpy as np
import math as math
import soundfile as sf
import scipy.fftpack as fftpack
import scipy.io.wavfile as wf
def dbfft(x,fs,win=None,ref=1):
"""
Calculate spectrum in dB scale
Args:
x: input signal
fs: sampling frequency
win: vector containing window samples (same length as x).
If not provided,then rectangular window is used by default.
ref: reference value used for dBFS . 32768 for int16 and 1 for float
Returns:
freq: frequency vector
s_db: spectrum in dB scale
"""
N = len(x) # Length of input sequence
if win is None:
win = np.ones(1,N)
if len(x) != len(win):
raise ValueError('Signal and window must be of the same length')
x = x * win
# Calculate real FFT and frequency vector
sp = np.fft.rfft(x)
freq = np.arange((N / 2) + 1) / (float(N) / fs)
# Scale the magnitude of FFT by window and factor of 2,because we are using half of FFT spectrum.
s_mag = np.abs(sp) * 2 / np.sum(win)
# Convert to dBFS using 20*log10(val/max)
s_dbfs = 20 * np.log10(s_mag/ref)
return freq,s_dbfs
def main():
# Read from wav file
data,samplerate = sf.read('Signal Analyzer_5s_55_1_L1F4_APxRecordedAudio.wav')
# Scaling factor
K = 120
# Calculation
N = 8192
win = np.hanning(N)
# Frequency domain
freq,s_dbfs = dbfft(data[0:N],samplerate,win)
# Scale from dbFS to dB
s_db = s_dbfs + K
# Time domain
Time = np.linspace(0,len(data) / samplerate,num=len(data))
# Amp_time = 20 * np.log10 (abs(data) / 0.00002) # ref = 1
Amp_time = (20*np.log10((data/50))) + K + 20*np.log10(math.sqrt(2)) # reference of sound i.e 20 log10(P rms_value/P ref)+120 dB Todo
# Plot
#fig,axes = plt.subplots(nrows=2,ncols=1)
plt.subplot(2,1,1)
plt.plot(Time,Amp_time)
plt.grid('on')
plt.minorticks_on
plt.xlabel('Time [s]')
plt.ylabel('Instantaneous Level [dBFS]')
plt.xlim([0,5])
plt.subplot(2,2)
plt.plot(freq,s_db)
plt.grid('on')
plt.minorticks_on
plt.xlabel('Frequency [Hz]')
plt.ylabel('Amplitude [dB]')
plt.xscale('log')
plt.xlim([10,10000])
plt.show()
if __name__ == "__main__":
main()
在代码中,我看到我只对前 8192 个样本进行 FFT,并对完整的 240000(5 秒)样本进行平均 FFT,块大小为 8192,带有汉宁窗口。对于 5 秒(88 次 FFT),我是否应该每 8192 秒进行多次 FFT 并平均幅度以获得结果 FFT?有没有一种有效的方法来执行此操作?
解决方法
也许您想了解 spectrogram 或 short-time Fourier transform。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。