0
votes

I'm trying to recover the phase of a simple (audio) signal in matlab: In matlab I do the following:

% This wave is perfectly periodic in the sample.  That is, 
% there are exactly 1000 periods.
swave = sin( 2 * pi * (0:10000) * 441/44100);

% Find the fft
sFFT = fft(swave);
% Remove the duplicate data in the FFT
sFFT = sFFT(1:length(sFFT)/2);

% Take a look a the amplitudes from the FFT and it checks out
freqs = 44100/ 2*linspace(0,1,length(sFFT);
plot(freqs, abs(sFFT));

% Now to get the phase
plot(freqs, angle(sFFT));

This result makes almost no sense to me. Because this is a sin wave (not a cos wave). I expect to see 1/2*pi = 1.57079 for the value of the 441hz bin. Instead I see a nearly discontinuous jump from (441, -1.539) to (445, 1.603). Why is 441 so far from the correct value? Why is 445 so close?

The value for all of the bins besides 441 hz are a mystery to me. I've also tried several other methods of recovering the phase including unwrap(angle(sFFT)) and atan2(imag(sFFT), real(sFFT)); These change the output but also do not make any sense to me. Why are bins besides 441 any value but 0 (like the abs(FFT) shows?). Why is the 441 bin close but not the correct value?

Thanks for the help!

1
did you try unwrap ? it corrects phase angles to produce smoother phase plots, see mathworks.com/help/matlab/ref/unwrap.htmlbla

1 Answers

0
votes

To better estimate the phase, change the 0 phase reference to the center of the window by doing an fftshift, which should eliminate most of the alternating phase discontinuities, and then interpolate, but noting that you have changed your 0 point.

Note the the phase of a vector of length zero is meaningless in most cases, and thus anything close is likely just numerical noise (near zero vectors in various random directions) due to finite precision math.

Thus some people just clamp the plotted phase to zero for any magnitude below some noise floor.