快速傅里叶变换降噪频率移除

3

我使用Audacity生成了一个采样率为48KHz、持续时间为1秒的10Hz音调。然后,使用以下脚本加载它以绘制FFT图形:

from scipy.io import wavfile
from scipy.fftpack import fft, fftfreq
import matplotlib.pyplot as plt
from pydub import AudioSegment
import numpy as np

wav_filename = "\\test\\10Hz.wav"
samplerate, data = wavfile.read(wav_filename)
total_samples = len(data)
limit = int((total_samples /2)-1)
fft_abs = abs(fft(data))*2/total_samples
fft_db = 20*np.log10(fft_abs/32760)
freqs = fftfreq(total_samples,1/samplerate)
# plot the frequencies
plt.plot(freqs[:limit], fft_db[:limit])
plt.xscale('log',basex=10)
plt.title("Frequency spectrum")
plt.xlabel('Hz')
plt.ylabel('amplitude')
plt.show()

我得到了下面这张嘈杂的图表: enter image description here 但是如果我使用Audacity查看频谱图,它就很好。
我应该如何改进我的脚本以获得更好的FFT绘制?

@harold:这种模式是由Audacity的噪声形状抖动引起的,旨在减轻量化引起的失真。好吧,我承认我不熟悉这种模式,所以我不得不进行调查。 - francis
1个回答

4

这个WAV文件的频谱模式是由Audacity应用的噪声整形抖动生成的,以减轻量化产生的失真。

信号以有符号16位整数的形式存储在WAV文件中。这种量化使得信号相当不准确:2^15是32768:0.5/32768的相对误差非常可能,并且计算DFT可能会增加它。这大约是1e-5,或者-96dB。因此,如果信号值被粗心地转换为最近的整数,则可以舍弃任何低于96dB的频率作为量化噪音。

尽管如此,导出的WAV文件的频谱看起来非常好,因为所有频率的振幅都低于-100dB,唯一的例外是正弦波的频率,其振幅接近0dB。 问题需要重新表述:Audacity是如何实现WAV文件的如此精确频谱的?

导出的数值进行了优化,以提高光谱的准确性。实际上,单个导出数值的准确性不如将浮点值转换为整数。我在Audacity中生成了一个振幅为0.8的正弦波,并将其导出为WAV有符号16位PCM格式。量化误差可以计算为:
x=np.linspace(0,1,len(data),endpoint=False)
data2=np.sin(10*2*np.pi*x)

data=data.astype(np.double)
plt.plot(x, data-0.8*32768*data2, label="data-sin(x)")
#plt.xscale('log',basex=10)
plt.title("signal")
plt.xlabel('time, s')
plt.ylabel('amplitude')
plt.show()

量化误差的生成图:

enter image description here

如果信号值仅被转换为最近的整数并注入WAV文件中,则生成的误差将低于0.5。实际的逐点误差约为5。

Audacidy中考虑了噪声形状抖动,通过添加人类几乎听不到的高频噪声来提高量化信号的动态范围。这里有更多信息,这里, 这里这里也有相关内容。

你可以在Audacity中选择抖动,甚至可以禁用它。进入“首选项”=>“质量”!如果不考虑抖动,则实际空间中的点误差更小:

enter image description here

但是频谱上的量化误差更高:

enter image description here

一个矩形抖动可以用来获取类似于白噪声的东西:它可能是您使用的最佳选择,因为频谱上的误差约为-125dB,点误差为+-1。

enter image description here

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接