Here is an audio signal which is a mix of (WAV file available here):
a 2000 Hz sinusoid, beginning at 1.00 sec, without fade-in/fade-out
a 2005 Hz sinusoid, beginning at 1.031 sec, with a slow fade-out at the end
background noise
(In reality it's even more complex: the sinusoids can also vary in amplitude...)
How to separate the signal into two signals (the two sinusoids), but also with a good temporal resolution?
Attempt 1
I zero-padded the signal to the next power of 2 (final length: 524288), did a real-FFT.
The size of the real-FFT vector h
is 262145 frequency bins to cover the frequency range [0, 22050hz], so each bin has a width 0.084 Hz. Pretty good news, we can distinguish the two sinusoids with this!
Now we can isolate the two sinusoids with:
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
It works, but the time-domain resolution is very bad (it's normal because the frequency resolution is very high!) : the sine is very poorly localized in time-domain. Instead of a fast attack in the separated sinusoid, we have a slow fade-in...
Of course, zeroing bins outside of the frequency range of interest (bins [23750:23800]) is not optimal, I should have used a (non-rectangular) window in the frequency domain instead:
h1[:23750] = 0
h1[:23800] = 0
h1[23750:23800] *= window
But even with such a windowing I doubt I can avoid a slow time-domain resolution after the separation.
Attempt 2
Use a STFT instead of a global FFT of the signal. This helps to localize, but ... in order to have a good frequency resolution to be able to separate the two sinusoids, we have to take a big FFTSIZE, such as 16384. Then each of the 8193 frequency bins (real-FFT) will have a 2.7 Hz width! Not enough to distinguish or separate the two sinusoids that have only 5 Hz of difference... So this approach will fail.
I know this is probably an example of the time-frequency trade off / uncertainty principle, but in this precise case, is there something else we can do to improve the separation?
Remark: I already read Separating waves of very close wavelengths but it did not help for this case.