0
$\begingroup$

I have an audio signal $g(t)$ composed by the sum of my original signal $f(t)$ and a delayed copy of itself:

$$g(t)=f(t)+f(t+\varepsilon)$$

My goal is to recover the original signal $f(t)$ knowing:

  • $g(t)$ from a .wav file
  • $\varepsilon$ from a spectral view in Audacity

spectral view

So now we know it is roughly equal to $55\ ms$.

I am using this method to get $f(t)$. Here is my implementation of that algoritgm with Octave:

[g_t, sample_rate] = audioread('raw_audio.wav'); epsilon = 55 / 1000; % Delay in seconds n = (0:length(g_t)-1); denominator = 1 + exp(-2*i*pi*n/length(g_t)*epsilon) G_fft = fft(g_t); % Perform element-wise division F_fft = G_fft ./ denominator.'; f_t = ifft(F_fft); audiowrite('fixed_audio.wav', real(f_t), sample_rate); 

But the resulting audio is very similar and keeps the same delay. What am I doing wrong?


Edit: fixed the code according to @Cris Luengo's suggestions in the comment section.

$\endgroup$
14
  • $\begingroup$ Is sample_rate equal to 1000??? And what is epsilon? Note also that ' is the complex conjugate transpose, you want to use .' instead. $\endgroup$ Commented Jul 23, 2023 at 14:05
  • 4
    $\begingroup$ Anyway, assuming you get those details right, consider a proper solution to the inverse problem rather than just division. Look up for example Wiener deconvolution. $\endgroup$ Commented Jul 23, 2023 at 14:08
  • $\begingroup$ @CrisLuengo epsilon is the time duration of the delay, as seen in $g(t)=f(t)+f(t+\varepsilon)$. I divide it by 1000 to transform the 55 milliseconds into 0.055 seconds. Thank you for suggesting the Wiener deconvolution, I will check it out. $\endgroup$ Commented Jul 23, 2023 at 14:10
  • $\begingroup$ I also assume that, the way your impulse response is defined, the computed delay must be really precise. You might need to include the delay as a parameter to estimate. $\endgroup$ Commented Jul 23, 2023 at 14:25
  • $\begingroup$ Ok, after this edit, I see you’re not using sample_rate at all. n is in units of samples, so epsilon must be in units of samples as well, not in seconds. The FFT has no motion of seconds. $\endgroup$ Commented Jul 23, 2023 at 14:28

1 Answer 1

2
$\begingroup$

denominator = 1 + exp(-2*pi*epsilon*n); Firstly you are missing the sample rate here since 'n' is in samples and not in time. Secondly, if the argument of the exp() becomes $\pi$, the whole expression becomes zero and you can't divide by it any more. Finally you are using an FFT which is an algorithm for the Discrete Fourier Transform (DFT), not the Continuous Fourier Transform.

The DFT is periodic in nature, i.e., you are implementing a circular delay and circular de-convolution, not linear ones.

Let's look at this analytically. Your discrete sequence can be written as

$$g[n] = f[n] + k\cdot f[n-M]$$

where $M$ is the delay in samples and $k$ the gain of the delayed copy. At this point we assume that the continuous delay can be rounded to the nearest sample without too much error. If that's not the case, things get a lot more complicated.

We can look at the transfer function and it's inverse

$$H[z] = 1 + k\cdot z^{-M} \\ H^{-1}[z] = \frac{1}{1 + k\cdot z^{-M} } $$

and can directly write the difference equation of the inverse operation as

$$ f[n] = g[n]-k \cdot f[n-M]$$

which is a recursive filter. As we can see from the transfer function, the filter is unstable for $k>=1$. You cannot completely remove an added copy if the gain of the copy is equal or larger than that of the original signal.

So your best shot is to do this directly in the time domain using the best possible estimates for $M$ and $k$ you can get. Eyeballing this in Audacity is not going to work you will need time accuracy down the sample. The exact gain can probably determine with a least square optimizer.

$\endgroup$
1
  • $\begingroup$ Thank you @Hilmar. I guess since I have a signal with $k=1$ I will generate several examples varying $M$ and choose the resulting signal with the least power. Also, I think you missed an $i$ inside exp, I committed the same mistake. $\endgroup$ Commented Jul 24, 2023 at 19:14

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.