python - FFT噪声频率去除

标签 python fft

我使用 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 绘图?

最佳答案

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

信号以带符号的 16 位整数形式存储在 WAV 文件中。这quantization使信号非常不准确:2^15 是 32768:0.5/32768 的相对误差很可能并且计算 DFT 可能会增加它。那大约是 1e-5,或 -96dB。因此,如果不小心将信号值强制转换为最接近的整数,则任何低于 96dB 的频率都可以作为量化噪声丢弃。

然而,导出的 WAV 文件的频谱看起来非常好,因为所有频率的幅度都低于 -100dB,唯一的异常(exception)是正弦波的频率,其幅度接近 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。

A noise-shaped dither Audacidy 中考虑通过添加人类几乎听不到的高频噪声来改善量化信号的动态范围。 there , therethere .

您可以 choose the dither in Audacity 甚至禁用它。进入首选项=>质量!如果不考虑dither,真实空间中的pointwise error更小:

enter image description here

但频谱上的量化误差较高:

enter image description here

矩形抖动可用于恢复看起来像白噪声的东西: 它可能是您使用的最佳选择,因为频谱上的误差约为 -125dB,逐点误差为 +-1。

enter image description here

enter image description here

关于python - FFT噪声频率去除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57892632/

相关文章:

c++ - OpenCV/C++ - 将图像转换为 double vector 以进行 FFT(快速傅里叶变换)

matlab - Matlab中的FFT,出乎意料的结果

python - pandas Mean() 值给出空白

python - 如何在 Spark Dataframe 中按组/分区重命名列?

python - 正则表达式捕获任何http地址

python - 两个fft函数的卷积

python - 奇怪的 numpy fft 性能

python - 在 Jupyter Notebook 中的任何地方重命名变量

python - 如何使用 Python 子进程在 Windows 中进行搜索

c - 这个FFT函数的输出有什么意义呢?