Why are frequency values rounded in signal using FFT?

So, I am trying to figure out how to use DFT in practice to detect prevalent frequencies in a signal. I have been trying to wrap my head around what Fourier transforms are and how DFT algorithms work, but apparently I still have ways to go. I have written some code to generate a signal (since the intent is to work with music, I generated a major C chord, hence the weird frequency values) and then tried to work back to the frequency numbers. Here is the code I have

sr = 44100 # sample rate
x = np.linspace(0, 1, sr) # one second of signal
tpi = 2 * np.pi
data = np.sin(261.63 * tpi * x) + np.sin(329.63 * tpi * x) + np.sin(392.00 * tpi * x)
freqs = np.fft.fftfreq(sr)
fft = np.fft.fft(data)
idx = np.argsort(np.abs(fft))
fft = fft[idx]
freqs = freqs[idx]
print(freqs[-6:] * sr)

This gives me [-262. 262. -330. 330. -392. 392.] which is different from the frequencies I encoded (261.63, 329.63 and 392.0). What am I doing wrong and how do I fix it?

Indeed, if the frame lasts T seconds, the frequencies of the DFT are k/T Hz, where k is an integer. As a consequence, oversampling does not improve the accuracy of the estimated frequency, as long as these frequencies are identifed as maxima of the magnitude of the DFT. On the contrary, considering longer frames lasting 100s would induce a spacing between the DFT frequencies of 0.01Hz, which might be good enough to produce the expected frequency. It is possible to due much better, by estimating the frequency of a peak as its mean frequency wih respect to power density.

Figure 1: even after applying a Tuckey window, the DFT of the windowed signal is not a sum of Dirac: there is still some spectral leakage at the bottom of the peaks. This power must be accounted for as the frequencies are estimated.

Another issue is that the length of the frame is not a multiple of the period of the signal, which may not be periodic anyway. Nevertheless, the DFT is computed as if the signal were periodic but discontinuous at the edge of the frame. It induce spurous frequencies described as spectral leakage. Windowing is the reference method to deal with such problems and mitigate the problem related to the artificial discontinuity. Indeed, the value of a window continuously decrease to zero near the edges of the frame. There is a list of window functions and a lot of window functions are available in scipy.signal. A window is applied as:

tuckey_window=signal.tukey(len(data),0.5,True)
data=data*tuckey_window

At that point, the frequencies exibiting the largest magnitude still are 262, 330 and 392. Applying a window only makes the peaks more visible: the DFT of the windowed signal features three distinguished peaks, each featuring a central lobe and side lobes, depending on the DFT of the window. The lobes of these windows are symmetric: the central frequency can therefore be computed as the mean frequency of the peak, with respect to power density.

import numpy as np
from scipy import signal
import scipy

sr = 44100 # sample rate
x = np.linspace(0, 1, sr) # one second of signal
tpi = 2 * np.pi
data = np.sin(261.63 * tpi * x) + np.sin(329.63 * tpi * x) + np.sin(392.00 * tpi * x)

#a window...
tuckey_window=signal.tukey(len(data),0.5,True)
data=data*tuckey_window

data -= np.mean(data)
fft = np.fft.rfft(data, norm="ortho")

def abs2(x):
        return x.real**2 + x.imag**2

fftmag=abs2(fft)[:1000]
peaks, _= signal.find_peaks(fftmag, height=np.max(fftmag)*0.1)
print "potential frequencies ", peaks

#compute the mean frequency of the peak with respect to power density
powerpeak=np.zeros(len(peaks))
powerpeaktimefrequency=np.zeros(len(peaks))
for i in range(1000):
    dist=1000
    jnear=0
    for j in range(len(peaks)):
        if dist>np.abs(i-peaks[j]):
             dist=np.abs(i-peaks[j])
             jnear=j
    powerpeak[jnear]+=fftmag[i]
    powerpeaktimefrequency[jnear]+=fftmag[i]*i


powerpeaktimefrequency=np.divide(powerpeaktimefrequency,powerpeak)
print 'corrected frequencies', powerpeaktimefrequency

The resulting estimated frequencies are 261.6359 Hz, 329.637Hz and 392.0088 Hz: it much better than 262, 330 and 392Hz and it satisfies the required 0.01Hz accuracy for such a pure noiseless input signal.

Python - Fourier transform wrong frequency, Even if the signal is a sine wave, the peak of the discrete Fourier power density See Why are frequency values rounded in signal using FFT? Why are frequency values rounded in signal using FFT? Ask Question Asked 10 months ago. Active 10 months ago. Viewed 102 times 1. 0. So, I am trying to figure out how

DFT result bins are separated by Fs/N in frequency, where N is the length of the FFT. Thus, the duration of your DFT window limits the resolution in terms of DFT result bin frequency center spacings.

But, for well separated frequency peaks in low noise (high S/N), instead of increasing the duration of the data, you can instead estimate the frequency peak locations to a higher resolution by interpolating the DFT result between the DFT result bins. You can try parabolic interpolation for a coarse frequency peak location estimate, but windowed Sinc interpolation (essentially Shannon-Whittaker reconstruction) would provide far better frequency estimation accuracy and resolution (given a low enough noise floor around the frequency peak(s) of interest, e.g. no nearby sinusoids in your artificial waveform case).

How can I define the frequency resolution in FFT? And what is the , We value your privacy How to compute the frequency resolution based on the information from the FFT? it's quite the other way round: Your sampled signal defines the basic parameters for the FFT: the lowest frequency is the one defined � The second method of compressing the frequency domain is to discard some of the 64 spectral values. As shown by the spectra in Fig. 27-11, nearly all of the signal is contained in the low frequency components. This means the highest frequency components can be eliminated, while only degrading the signal a small amount.

Since you want to get a resolution of 0.01 Hz, you will need to sample at least 100 sec worth of data. You will be able to resolve frequencies up to about 22.05 kHz.

FFT, When all frequencies that are present in the underlying contain infinitely more information -- all the values between So you can think of the resulting spectrum as being a circular buffer, representing signal at each For a band-limited signal with all frequencies below� 1. You sample the signal with a certain sampling frequency over a window of a few cycles. Then apply the FFT on those samples. Then you calculate the RMS for that window with the square root of the sum of squares of the Fourier components. 2. Approximation: Consider the DC signal of your first function fixed over the first cycle.

Fast Fourier transform, A fast Fourier transform (FFT) is an algorithm that computes the discrete Fourier transform (DFT) of a sequence, or its inverse (IDFT). Fourier analysis converts a signal from its original domain (often time or space) to a representation in the frequency domain and vice versa. In the presence of round-off error, many FFT algorithms are much more� Let denote the difference-frequency period in samples, rounded up to the nearest integer. Then an ``-term'' Blackman-Harris window of length samples may be said to resolve the sinusoidal frequencies and . Using Table 5.2, the minimum resolving window length can be determined using the sharper bound as .

Scaling the FFT and the IFFT - MATLAB Answers, Learn more about fft, ifft, scaling, scale MATLAB. Flagging is used to mark a message because it conflicts with the terms of use, and the frequency increment as: of the computation, so that the overall round-trip scaling is 1/M ( as it should be). Can x assume any value to recover the signal for the mentioned cases? Why does the frequency spectra change when the sampling frequency is changed? matlab,signal-processing,fft,frequency,continuous-fourier. I can't get your pictures to load over my proxy, but the spectrum of a FFT will be have a bigger "gap" in the middle at a higher sampling rate.

Fourier Transforms - MATLAB & Simulink, Consider a sinusoidal signal x that is a function of time t with frequency you can use the fftshift function, which performs a zero-centered, circular shift on the� c++,matlab,fft,fftw,frequency-analysis I have some signals and I mix respectively add up to a larger signal, where each signal is located in different frequency regions. Now, I perform the FFT operation on the big signal with FFTW and cut the concrete FFT bins (where the signals are located) out. E.g.

Comments
  • Well, you haven't said what you expect to see so it's impossible to say.
  • I thought from my description it was reasonably clear. I expected to see the frequencies I put into the signal, 261.63, 329.63 and 392
  • @MadWombat because you have as many buckets (samples) as your sampling rate in Hz, the maximum theoretical resolution is 1Hz – so, not really possible without more samples.
  • @MadWombat, you updated your code, but not your stated output.
  • @MadWombat a higher sampling rate makes no difference if you don't have enough samples. The maximum number of frequency buckets available is number of samples / 2 (there are also negative components)
  • I wonder. Is it possible to modify the DFT algorithm to raise precision at the cost of limiting the frequency range?
  • You can reduce the range by reducing your sampling rate. As long as you sample 100 seconds you would still get a resolution of 0.01 Hz.
  • The length only needs to be increased if the S/N is low. Otherwise, one can interpolate to get higher resolution.