在 44.1 Khz 音频信号中分离两个频率非常接近(5 Hz 差异)的正弦曲线,具有良好的时域分辨率

信息处理 fft 声音的 频谱 stft 时频
2022-02-25 03:38:13

这是一个混合的音频信号(此处提供 WAV 文件):

  • 2000 Hz 正弦曲线,从 1.00 秒开始,无淡入/淡出

  • 一个 2005 Hz 正弦曲线,从 1.031 秒开始,结束时缓慢淡出

  • 背景噪音

在此处输入图像描述

(实际上它更复杂:正弦曲线的幅度也可以变化......)

如何将信号分离成两个信号(两个正弦波),而且还具有良好的时间分辨率?

尝试 1

我将信号零填充到 2 的下一个幂(最终长度:524288),进行了实 FFT。

real-FFT 向量的大小h为 262145 个频率 bin,以覆盖频率范围 [0, 22050hz],因此每个 bin 的宽度为 0.084 Hz。好消息,我们可以用这个区分两个正弦曲线!

在此处输入图像描述

现在我们可以隔离两个正弦曲线:

h1 = h.copy()   # the real-FFT
h1[:23750] = 0  # zeroing bins outside [23750, 23800]
h1[23800:] = 0
x1 = irfft(h1)  # inverse real-FFT

h2 = h.copy() 
h2[:23810] = 0  # zeroing bins outside [23810, 23860]
h2[23860:] = 0
x2 = irfft(h1)  # inverse real-FFT

它可以工作,但时域分辨率非常差(这是正常的,因为频率分辨率非常高!):正弦在时域中的定位非常差。我们没有在分离的正弦曲线中快速攻击,而是缓慢淡入......

当然,在感兴趣的频率范围之外(bins [23750:23800])归零并不是最优的,我应该在频域中使用(非矩形)窗口:

h1[:23750] = 0 
h1[:23800] = 0
h1[23750:23800] *= window

但即使有这样的窗口,我怀疑我能否避免分离后的慢时域分辨率。

尝试 2

使用 STFT 而不是信号的全局 FFT。这有助于定位,但是......为了有一个好的频率分辨率能够分离两个正弦波,我们必须取一个很大的 FFTSIZE,比如 16384。然后每个 8193 个频率箱(real-FFT)将有 2.7 Hz 的宽度!不足以区分或分离只有 5 Hz 差异的两个正弦曲线......所以这种方法会失败。


我知道这可能是时频权衡/不确定性原理的一个例子,但在这种精确的情况下,我们还能做些什么来改善分离吗?

备注:我已经读过分离非常接近波长的波,但它对这种情况没有帮助。

1个回答

我相信您的回答没有按预期出现有几个原因。你的问题是三个信号之和的频谱

G(ω)=S1(ω)+S2(ω)+N(ω)

在哪里G(ω)是你展示的光谱,S1(ω), 和S2(ω)是感兴趣信号的频谱和N(ω)是噪声谱。您正在尝试恢复信号S1(ω), 和S2(ω)具有高保真度,在这种情况下这可能是不可能的。为简单起见,我不会担心这里的噪音。

您的解决方案假设了几件事。首先,它假设每个信号的带宽非常小。您提到恢复的信号淡入缓慢,这表明信号是带限的。例如,时域中的无限长正弦曲线将是频率中的增量函数。

此外,光谱S1(ω), 和S2(ω)重叠,这是有问题的。把它想象成一个线性方程组。在你的情况下,你有两个未知数,S1(ω), 和S2(ω),但只有一个方程。这会导致具有 0 或无限解的欠定系统。

为了克服这种情况,您可以尝试假设有关信号的其他信息S1(ω), 和S2(ω). 您先前对有限带宽和非重叠频谱的假设导致了您先前的答案。在寻找更好的解决方案时,我会提出新的假设。例如,您可以尝试对信号进行建模s1(n), 和s2(n)作为加窗正弦曲线,并尝试从数据中估计窗函数。此外,您可以尝试在时域信号上使用窗口函数来限制频谱的旁瓣,从而提高隔离度。