在对Audacity做了一些逆向工程后,这里给出了一些答案。首先,他们使用Welch algorithm来估计PSD。简而言之,它将信号分割成重叠段,应用一些窗口函数,应用FFT并对结果进行平均。主要是因为这有助于在存在噪声时获得更好的结果。总之,在提取了必要的参数后,这里的解决方案近似于Audacity的光谱图:import numpy as np
from scipy.io import wavfile
from scipy import signal
from matplotlib import pyplot as plt
segment_size = 512
fs, x = wavfile.read('sine3k6k.wav')
x = x / 32768.0 # scale signal to [-1.0 .. 1.0]
noverlap = segment_size / 2
f, Pxx = signal.welch(x, # signal
fs=fs, # sample rate
nperseg=segment_size, # segment size
window='hanning', # window type to use
nfft=segment_size, # num. of samples in FFT
detrend=False, # remove DC part
scaling='spectrum', # return power spectrum [V^2]
noverlap=noverlap) # overlap between segments
# set 0 dB to energy of sine wave with maximum amplitude
ref = (1/np.sqrt(2)**2) # simply 0.5 ;)
p = 10 * np.log10(Pxx/ref)
fill_to = -150 * (np.ones_like(p)) # anything below -150dB is irrelevant
plt.fill_between(f, p, fill_to )
plt.xlim([f[2], f[-1]])
plt.ylim([-90, 6])
# plt.xscale('log') # uncomment if you want log scale on x-axis
plt.xlabel('f, Hz')
plt.ylabel('Power spectrum, dB')
plt.grid(True)
plt.show()
有关参数的一些必要说明:波形文件读取为16位PCM,为了与Audacity兼容,应将其缩放为| A |<;1.0
segment_size对应于Audacity的GUI中的Size。在
默认窗口类型为“Hanning”,如果需要,可以更改它。在
重叠是segment_size/2,就像在Audacity代码中一样。在
输出窗口被框住以遵循Audacity样式。他们扔掉第一个低频仓,把所有的东西都降低到-90分贝以下
What's physical meaning of the amplitude in the second picture?
它基本上是频率仓中的能量量。在How to normalize the amplitude to 0dB like the one in Audacity?
你需要选择一些参考点。以分贝为单位的图表总是与某些事物相关。当你选择最大能量箱作为参考,你的0db点就是最大能量(显然)。可以将最大振幅的正弦波设定为参考能量。请参见ref变量。正弦信号中的功率是RMS的平方,要得到RMS,只需将振幅除以sqrt(2)。所以比例因子是0.5。请注意,log10之前的系数是10而不是20,这是因为我们处理的是信号的功率而不是振幅。在Can I treat the amplitude below -90dB so low that it can be ignored?
是的,低于-40dB的东西通常被认为是可以忽略的
本文介绍了如何使用Python的scipy库来实现RMS归一化的FFT频谱分析,参照Audacity的Welch算法进行信号处理。通过设置合适的参数,如窗口大小、重叠和窗函数类型,计算并显示功率谱密度。归一化过程包括将最大振幅的正弦波作为参考,设置0dB,并将低于-90dB的频谱忽略不计。
833

被折叠的 条评论
为什么被折叠?



