0
$\begingroup$

I am kind of new to the DSP domain. I was trying to get the frequencies associated with a signal by performing FFT over it. I used numpy.fft.fft for this.

Input signal frequency = 1000 Hz

Noise signal frequency = 200 Hz

The input signal, noise signal and combined_signal all have 2400 samples. When I apply FFT on the combined_signal, i get 2400 size array as output. According to my understanding the FFT operation returns the frequencies present in the signal (in this case, 1000 Hz and 200 Hz). Also, when I plot the output of the FFT, I get some weird plot. Instead of giving two peaks at 1000 Hz and 200 Hz it is giving some random frequencies. Also, why is it giving are two peeks at the beginning and 2 at the end ?

I have used the following jupyter notebook code.

import numpy as np
from matplotlib import pyplot as plt
import matplotlib
%matplotlib inline
matplotlib.rcParams['figure.figsize'] = (16, 9)

freq_noise = 200
freq_signal = 1000

sampling_rate = 48000.0
seconds = 0.05
num_samples = int(sampling_rate * seconds)

signal = [np.sin(2 * np.pi * freq_signal * x1/sampling_rate) for x1 in range(num_samples)]
noise = [np.sin(2 * np.pi * freq_noise * x1/sampling_rate) for x1 in range(num_samples)]

# convert to numpy array
signal = np.array(signal) * 1000      # Increase the amplitude of the signal
noise = np.array(noise) * 500         # Lower amplitude for the noise

combined_signal = signal + noise

print "The length of the signal is : ", len(signal)
print "The length of the noise is : ", len(noise)
print "The length of the combined signal  is : ", len(combined_signal)

plt.subplot(4, 1, 1)
plt.plot(signal)
plt.xlabel('Sample number')
plt.ylabel('Amplitude')
plt.title('Original Signal')

plt.subplot(4, 1, 2)
plt.plot(noise)
plt.xlabel('Sample number')
plt.ylabel('Amplitude')
plt.title('Noise Signal')

plt.subplot(4, 1, 3)
plt.plot(combined_signal)
plt.xlabel('Sample number')
plt.ylabel('Amplitude')
plt.title('Combined Signal')

combined_fft = np.fft.fft(combined_signal)
combined_freq = np.abs(combined_fft)

plt.subplot(4, 1, 4)
plt.plot(combined_freq)
plt.xlabel('Frequency')
plt.ylabel('Amplitude')
plt.title('FFT of Combined signal')

plt.tight_layout()
plt.show()

The output of the above code is:

The length of the signal is :  2400
The length of the noise is :  2400
The length of the combined signal  is :  2400

enter image description here

$\endgroup$
1
$\begingroup$

First off, you have a "bug" in your code. Look at line 45:

combined_fft = np.fft.fft(signal)

You are taking the FFT of your signal and calling it, and labeling it, the combined signal. Fix this, and you will see two peaks on each end.

If you use the "rfft" (real FFT) call instead, you will get back the first half and the Nyquist bin for even N.

combined_fft = np.fft.rfft(combined_signal)

For real valued signals, that is all you need. The top half is redundant.

Why there are two ends really boils down to this equation:

$$ \cos( \theta ) = \frac{ e^{i \theta} + e^{-i \theta} }{2} $$

See my answer on a similar question for further explanation.

Ced

$\endgroup$
  • $\begingroup$ Thank you for pointing out the mistake. I have made the correction. Still I don't understand why I am getting the the frequency peeks at the wrong place. According to my understanding they should be close to 200 and 1000. $\endgroup$ – amitasviper Mar 25 '18 at 17:02
  • 1
    $\begingroup$ @amitasviper, The bin number is the number of cycles per frame. Your 1000 Hz signal is 1000 cycles per second. Your interval is .05 seconds per frame. So there are 50 cycles in the frame. Therefore, it shows up in bin 50. Likewise your "noise" is in bin 20. $\endgroup$ – Cedron Dawg Mar 25 '18 at 17:15
  • $\begingroup$ @amitasviper, Set your seconds to 1 and your sampling_rate to 2400 and you will get the same number of samples with the bin numbers corresponding to Hz. $\endgroup$ – Cedron Dawg Mar 25 '18 at 17:27
1
$\begingroup$

To answer the question in your title:

Because it is defined to do exactly that.

Think about it: the DFT is a revertible linear operation on all vectors of the $\mathbb C^N$. In other words, for every vector that you apply the DFT to, there is exactly one vector that is the result, and for every result vector, there is exactly one vector that maps to it.

The operation can only exist on sets of the same dimensionality. And thus, the input and output vectors need to be of the same size.

The fact that you can interpret the DFT of a time sample vector as a frequency sample vector doesn't change that.

Your "why are there two peaks" question can be answered by: because your signal is real valued; real-valued signals always have symmetry in Fourier domain.

The "odd" shape is probably Gibb's/leakage phenomena. That always happens when your signal is not perfectly periodic within a circular repetition of your vector.

$\endgroup$

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.