0
$\begingroup$

I am writing some code for audio analysis, and have currently got two signals with FFT performed on them.
I get the phase of my complex array by using:

ang = Math.atan(complex.im/complex.re)*180.0/Math.PI;

I then 'format' for wrapped phase:

if(complex.re < 0.0 && complex.im == 0.0){ang = 180.0;}
            else if(complex.re < 0.0 && complex.im == -0.0){
                ang = -180.0;}
            else if(complex.re < 0.0 && complex.im > 0.0){
                ang += 180.0;}
            else if(complex.re < 0.0 && complex.im < 0.0){
                ang += -180.0;}
            phase.add(ang);
        }

As I have converted this to degrees already, I then subtract channel 1 phase from channel 2 phase to give me the phase difference:

double phaseDiff = (((double)chan1phase.get(i)) - ((double)chan2phase.get(i)));

Finally, I add a method for keeping wrapped phase whilst subtracting the two phases:

if (phaseDiff < -180){
            phaseDiff += 360;
        }
        if (phaseDiff > 180){
            phaseDiff -= 360;
        }

This works really well currently, however there are too many data points for my application to respond quickly. I am working with 16k or 32k FFT size, and that's a lot of data to plot and redraw quickly when I manipulate my data. I also occasionally get one or two data points throughout the whole plot which are noisy or differ from the expected path of travel, which I would like to get rid off.

I have already used a smoothing function to display my magnitude vs frequency, and this responds really quickly. However I am not confused on how best to smooth phase. I need to reduce the data points to approximately 1000 points over the audible frequency range (20Hz - 20kHz).

However I cannot just use the same method as I used for magnitude because of the wrapped phase. Would I need to average the data points within an octave (or preset band) prior to wrapping the phase?

Or am I better disregarding some points and interpolating the data?

Any guidance would be appreciated. Apologies if there is too much actual code here, I realise this is a DSP site and not programming site, but thought it useful to see exactly what I am doing (or where I have gone wrong!).

$\endgroup$
2
  • 2
    $\begingroup$ You can save some computation time by using "Math.atan2" and also by sticking with radians and not converting to degrees. Good answers to the rest of your questions really requires knowing what your are trying to accomplish. $\endgroup$ Feb 25, 2018 at 15:33
  • $\begingroup$ I have trouble following you. What is your problem exactly? Is it the refresh rate or the the noisy data? Does smoothing your phase plot the only problem you are trying to solve? If you can't filter a phase/frequency plot because the phase wrap, why not unwrap it? You say that you cannot smooth like the magnitude, but you haven't told us how you do. If you are trying to remove few noisy points, maybe a median filter would be a good fit; that should behave good with wraping phase. $\endgroup$ Dec 17, 2018 at 4:35

2 Answers 2

1
$\begingroup$

To downsample an FFT result for both magnitude and phase, it may work best to do an FFTShift before the FFT, then downsample the real component vector and then the imaginary component vector separately, before taking the atan2() of them to estimate downsampled phase.

$\endgroup$
0
$\begingroup$

Let's say you have the signal in time series {t1,t2,t3,t4, ..., t10}, how about you shift {t2,t4,t6,t8,t10} to {t1,t3,t5,t7,t9}? So that you can just take average of t1 and t2 (t3 and t4, etc.) to reduce the fluctuation in the signal, meanwhile you get less sampling rate. This is kind of equivalent to interpolation.

In FFT, for any real number t0, if h(t) = f(t − t0), then in the frequency domain, h(w) = exp(−iwt0)f(w). See https://en.wikipedia.org/wiki/Fourier_transform.

Basically, one does FFT on f(t) first, shifts the f(w) a little bit with exp(−iwt0), do a backward FFT again to get f(t-t0).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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