Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

To resolve issues starting MATLAB on Mac OS X 10.10 (Yosemite) visit: http://www.mathworks.com/matlabcentral/answers/159016

ifft returns a complex signal from a real fft spectrum; i desire a real signal

Asked by Jeff on 11 Aug 2011

Hi all,

I've been trying to synthesize a 1 second long complex tone with 10 harmonics (at 200Hz, 400Hz, ... 2000Hz) of equal power using Matlab. My code below assigns real fft values (nothing in the imaginary domain), then performs an ifft. However, the ifft produces real + imag values, and I want a real signal.

sigfft = zeros(44100,1);

    for i=1:10
        sigfft(i*200) = 1000;
        sigfft(44100-i*200) = 1000;
    end

sig = ifft(sigfft);

Questions: First, why am I getting these imag values?

Second, how do I force ifft to give me real values instead of real + imag values?

Cheers

0 Comments

Jeff

Products

No products are associated with this question.

4 Answers

Answer by Walter Roberson on 11 Aug 2011
Accepted answer

The first non-zero frequency is at sigfft(2) not sigfft(1) -- you have to shift the left-hand side frequencies by one bin to the right, sigfft(1+i*200)

Likewise, suppose for a moment that the harmonics were 1 Hz apart starting from 1 Hz. Your code would use sigfft(44100-i*1) which would be sigfft(44099). The last bin though, corresponds to the first non-zero point, so you should be using sigfft(44100+1-i*200)

You now need to take in to account that because the first bin is occupied by the constant power (like the DC frequency 0 Hz) but the last bin does not include that, then if you have an even number of bins to start, and you proceed far enough with the harmonics, you may find that bin 22051 corresponds to both an harmonic "starting from the front" and a harmonic "starting from the back". You need to work out whether that means that a special value should be put in to that location.

0 Comments

Walter Roberson
Answer by Honglei Chen on 11 Aug 2011

Hi Jeff,

There is no guarantee that the real spectrum will generate a real signal. Between time domain and frequency domain, if the signal in one domain is real, then the signal in the other domain has to be symmetric. You can find details in any DSP book such as Oppenheim's. A subtle point in programming this is that in MATLAB, the frequency domain is often represented from 0 to 2*pi so if you want to start with a symmetric sequence, you may want to use iffshift first to make it correctly mapped from 0 to 2*pi. Here is a quick example:

>> ifft(ifftshift([1 0 0 0 1 0 0 0 1]))

HTH

0 Comments

Honglei Chen
Answer by Daniel on 11 Aug 2011

try

sigfft(44100+2-i*200) = 1000;

notice the +2.

2 Comments

Walter Roberson on 11 Aug 2011

I'm not convinced, Daniel. If the increment were 1 instead of 200, then for i=1, you would have sigfft(44100+2-1) which would be outside of the defined sigfft vector.

Daniel on 12 Aug 2011

Walter you are correct. I was only focusing on making sigfft symmetric to get a real signal, and not on the frequency components. My answer will produce a real signal with frequencies that are off by one frequency bin (i.e., 1+i*200 instead of i*200).

Daniel
Answer by Nike on 25 Mar 2013

Hi , why havent you tried adding multiple sine waves as below.

fs = 44100; %sampling frequency
dur = 1; %duration in seconds
n = fs*dur; % number off samples
t = 1/fs:1/fs:dur; %time array
freq = [200:200:10*200];%frequency components
db = 80; % intensity
amp = 10^((db-100)/20);
for i = 1:length(freq)
tone = amp*sin(2*pi*freq(i)*t);
tones(:,i) = tone;
end
complex = sum(tones,2);
plot(t,complex)
sound(complex,fs)

0 Comments

Nike

Contact us