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

enter image description here

(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!

enter image description here

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.

  • $\begingroup$ Your file is gone and there is no code to generate the test signal. Additionally, what do you consider a good time resolution? $\endgroup$
    – jojek
    Oct 18 '18 at 15:19

I believe there are a couple of reasons why your answere is not coming out as expected. What you have in your problem is the spectrum of the sum of three signals

$G(\omega) = S_1(\omega) + S_2(\omega) + N(\omega)$

where $G(\omega)$ is the spectrum you showed, $S_1(\omega)$, and $S_2(\omega)$ are the spectrum of the signals of interest and $N(\omega)$ is the noise spectrum. You are attempting to recover signals $S_1(\omega)$, and $S_2(\omega)$ with high fidelity, which may not be possible in this case. For simplicity, I won't worry about noise here.

Your solution assumes a couple of things. First it assumes a very small bandwidth for each signal. You mention that the recovered signals have a slow fade in, which would indicate a band-limited signal. As an example, a infinite length sinusoid in the time domain would be delta function in frequency.

Also, the spectrums $S_1(\omega)$, and $S_2(\omega)$ overlap, which is problematic. Think of it as a system of linear equation. In your case, you have two unknowns, $S_1(\omega)$, and $S_2(\omega)$, but only one equation. This leads to an underdetermined system that has 0 or infinite solutions.

To overcome this situation you may attempt to assume additional information about the signals $S_1(\omega)$, and $S_2(\omega)$. Your previous assumptions of limited bandwidth and non overlapping spectrums lead to your previous answer. In looking toward a better solution, I would suggest new assumptions. For example, you could attempt to model your signals $s_1(n)$, and $s_2(n)$ as windowed sinusoids and attempt to estimate window function from the data. Additionally, you may attempt to use a windowing function on the time domain signal to limit the side lobes of the frequency spectrum to improve isolation as well.

  • $\begingroup$ you could attempt to model your signals s1(n), and s2(n) as windowed sinusoids: in fact s1(n) and s2(n) are harmonics of two different sounds, and they vary in amplitude during the whole sound. So I can't model it very simply... $\endgroup$
    – g6kxjv1ozn
    Sep 18 '18 at 16:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.