I would like to find the phase shift between two non-periodic signals read from an electret microphone. So what I did so far is the following:

  1. read the signals from the mics using an arduino uno micro controller.
  2. finished writing an fft code based on cooley_tukey algorithm.
  3. tested the fft with the help of matlab.

My plan is:

  1. search for the maximum value in each signal and store its index
  2. find the phase corresponding to the index found in the previous step from fft using: phase = atan(imaginary/real)
  3. assume phase1 and phase2 corresponding to phases calculated in step(2) for signals 1 and 2 respectively.
  4. difference = phase1 - phase2 if (difference < 0) → phase1 < phase2 → signal 1 came first and vice versa.

So, is this procedure correct? Am I going to get the phase shift using this technique? I would to do a sound localization using 4 microphones. Thanks in advance. Your help is appreciated.


You have two functions. One is \$f(t)\$ and the other is the time shift of \$f\$, \$g(t) = f(t+\Delta)\$. You would like to find \$\Delta\$.

We can take the Laplace/Fourier transform (say via Cooley-Tukey FFT algorithm) and denote the transformed signals by \$\hat{f}(s)\$ and \$\hat{g}(s)\$.

Now \$\hat{g}(s) = e^{\Delta s} \hat{f}(s)\$ so the quantity you seek is $$\Delta = \frac{ln(\hat{g}(s))-ln(\hat{f}(s))}{s}.$$

In other words, the natural log of the quotient \$\frac{\hat{g}}{\hat{f}}\$ will be linear in \$s\$ and the slope of this line will be \$\Delta\$.

  • \$\begingroup\$ Excellent explanation thanks. But I have a small question, should I do this for every single point in the fft results? or only to the index where I got the maximum value in the original signal? and in either case, what is the value of "s" then? I think its the index, right? \$\endgroup\$ Apr 5 '14 at 18:23
  • \$\begingroup\$ Purely theoretically, you can do it for just one value of \$s\$ because \$\Delta\$ doesn't depend on \$s\$. In reality, you'll have noise and other factors so you should in some way "average" \$\Delta\$ over several values of \$s\$. \$\endgroup\$
    – SomeEE
    Apr 5 '14 at 18:38
  • \$\begingroup\$ Thanks again, but as I said, i will be using an arduino uno micro controller which has low processing capabilities. So, I need to do the process in a fast way and get an approximate location of the sound source (not necessarily the exact location). And again please, "s" is the index or what exactly? \$\endgroup\$ Apr 5 '14 at 21:12
  • \$\begingroup\$ You don't need to average them all just some. Even averaging all of them is still computationally less complex than FFT. When you execute the Cooley-Tukey algorithm it returns list of numbers with some indexes corresponding to frequencies. These frequencies are the $s$. \$\endgroup\$
    – SomeEE
    Apr 5 '14 at 21:26

You're thinking "phase shift" when what you really want is the time delay. They're not the same thing.

The FFT will give you the phase angles of the various sinusoidal components that make up your signal, but these don't easily translate into a time delay value.

What you really want is to cross-correlate the signals in the time domain. The location of the peak in the result is the time delay. There is a way to implement cross-correlation using FFT, but I'm not familiar with the details. (See MathEE's answer.)

In any case, if you want to do this in real time, this is a serious amount of DSP, and your Arduino might not be up to the task. Or are you using it only to collect the raw data?

  • \$\begingroup\$ no actually i want to use it in real time. a short delay won't affect the process i guess as long as it is not a long one. \$\endgroup\$ Apr 5 '14 at 15:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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