How to get frequency from fft result?
The complex data is interleaved, with real components at even indices and imaginary components at odd indices, i.e. the real components are at index 2*i
, the imaginary components are at index 2*i+1
.
To get the magnitude of the spectrum at index i, you want:
re = fft[2*i];
im = fft[2*i+1];
magnitude[i] = sqrt(re*re+im*im);
Then you can plot magnitude[i] for i = 0 to N / 2 to get the power spectrum. Depending on the nature of your audio input you should see one or more peaks in the spectrum.
To get the approximate frequency of any given peak you can convert the index of the peak as follows:
freq = i * Fs / N;
where:
freq = frequency in Hz
i = index of peak
Fs = sample rate in Hz (e.g. 44100 Hz, or whatever you are using)
N = size of FFT (e.g. 1024 in your case)
Note: if you have not previously applied a suitable window function to the time-domain input data then you will get a certain amount of spectral leakage and the power spectrum will look rather "smeared".
To expand on this further, here is pseudo-code for a complete example where we take audio data and identify the frequency of the largest peak:
N = 1024 // size of FFT and sample window
Fs = 44100 // sample rate = 44.1 kHz
data[N] // input PCM data buffer
fft[N * 2] // FFT complex buffer (interleaved real/imag)
magnitude[N / 2] // power spectrum
// capture audio in data[] buffer
// ...
// apply window function to data[]
// ...
// copy real input data to complex FFT buffer
for i = 0 to N - 1
fft[2*i] = data[i]
fft[2*i+1] = 0
// perform in-place complex-to-complex FFT on fft[] buffer
// ...
// calculate power spectrum (magnitude) values from fft[]
for i = 0 to N / 2 - 1
re = fft[2*i]
im = fft[2*i+1]
magnitude[i] = sqrt(re*re+im*im)
// find largest peak in power spectrum
max_magnitude = -INF
max_index = -1
for i = 0 to N / 2 - 1
if magnitude[i] > max_magnitude
max_magnitude = magnitude[i]
max_index = i
// convert index of largest peak to frequency
freq = max_index * Fs / N
How can I get DFT/FFT output frequencies in Hertz?
You need to find the peak magnitude then work out the corresponding frequency:
- calculate the magnitude of each DFT output bin:
magnitude = sqrt(re*re+im*im)
- find the bin with the largest magnitude, call its index
i_max
. - calculate the equivalent frequency of this bin:
freq = i_max * Fs / N
, hereFs
= sample rate (Hz) andN
= no of points in FFT.
See this answer for a more detailed explanation of how bin indices and frequency are related.
How to determine frequencies values from an FFT
Generally for an FFT result, the array index corresponds to the discretised frequency "block" and the value is just the magnitude. Since you probably want to know the peak frequency and not the amplitude, the exact value of the latter is not that important.
The general steps are:
- get the array
- get the size of the array [1]
- find the max value in array [1]
- get the index of the max value [3]
- calculate frequency interval = sampleRate / size [2] / 2
- calculate the max frequency = index [4] * frequency interval
- return the frequency [6]
Calculate Frequency from sound input using FFT
The frequency corresponding to a given FFT bin index is given by:
f = i * Fs / N;
where:
Fs = sample rate (Hz)
N = FFT size
i = bin index
So for your peak index maxIndex
and FFT size blockSize
the frequency of the peak will be:
f = maxIndex * Fs / blockSize;
See this answer for more details.
how to extract frequency associated with fft values in python
np.fft.fftfreq
tells you the frequencies associated with the coefficients:
import numpy as np
x = np.array([1,2,1,0,1,2,1,0])
w = np.fft.fft(x)
freqs = np.fft.fftfreq(len(x))
for coef,freq in zip(w,freqs):
if coef:
print('{c:>6} * exp(2 pi i t * {f})'.format(c=coef,f=freq))
# (8+0j) * exp(2 pi i t * 0.0)
# -4j * exp(2 pi i t * 0.25)
# 4j * exp(2 pi i t * -0.25)
The OP asks how to find the frequency in Hertz.
I believe the formula is frequency (Hz) = abs(fft_freq * frame_rate)
.
Here is some code that demonstrates that.
First, we make a wave file at 440 Hz:
import math
import wave
import struct
if __name__ == '__main__':
# http://stackoverflow.com/questions/3637350/how-to-write-stereo-wav-files-in-python
# http://www.sonicspot.com/guide/wavefiles.html
freq = 440.0
data_size = 40000
fname = "test.wav"
frate = 11025.0
amp = 64000.0
nchannels = 1
sampwidth = 2
framerate = int(frate)
nframes = data_size
comptype = "NONE"
compname = "not compressed"
data = [math.sin(2 * math.pi * freq * (x / frate))
for x in range(data_size)]
wav_file = wave.open(fname, 'w')
wav_file.setparams(
(nchannels, sampwidth, framerate, nframes, comptype, compname))
for v in data:
wav_file.writeframes(struct.pack('h', int(v * amp / 2)))
wav_file.close()
This creates the file test.wav
.
Now we read in the data, FFT it, find the coefficient with maximum power,
and find the corresponding fft frequency, and then convert to Hertz:
import wave
import struct
import numpy as np
if __name__ == '__main__':
data_size = 40000
fname = "test.wav"
frate = 11025.0
wav_file = wave.open(fname, 'r')
data = wav_file.readframes(data_size)
wav_file.close()
data = struct.unpack('{n}h'.format(n=data_size), data)
data = np.array(data)
w = np.fft.fft(data)
freqs = np.fft.fftfreq(len(w))
print(freqs.min(), freqs.max())
# (-0.5, 0.499975)
# Find the peak in the coefficients
idx = np.argmax(np.abs(w))
freq = freqs[idx]
freq_in_hertz = abs(freq * frate)
print(freq_in_hertz)
# 439.8975
Related Topics
Why Is "Extends T" Allowed But Not "Implements T"
Java Byte Array to String to Byte Array
Java Simpledateformat("Yyyy-Mm-Dd'T'Hh:Mm:Ss'Z'") Gives Timezone as Ist
How to Restart a Java Application
Converting Symbols, Accent Letters to English Alphabet
Using Heapdumponoutofmemoryerror Parameter for Heap Dump for Jboss
Which Java Collection Should I Use
How to Read and Copy the Http Servlet Response Output Stream Content for Logging
The Performance Impact of Using Instanceof in Java
Using Pairs or 2-Tuples in Java
Abstract Class VS Interface in Java
Convert Latitude/Longitude Point to a Pixels (X,Y) on Mercator Projection
Converting Between Java.Time.Localdatetime and Java.Util.Date
What's the Difference Between Primitive and Reference Types
Why Are Interface Variables Static and Final by Default
Handling Passwords Used for Auth in Source Code
How to Bundle a Native Library and a Jni Library Inside a Jar