I calculated FFT for a speech wav-file using scipy.fftpack. How do I read (understand) the return of FFT? I have read that it supposed to be like so: y[0] is 0Hz loudness, y[1] is 1Hz loundess, ... y[n] is nHz loudness ... But seems like it is not like that exactly.

Q1: What will I get when I do abs(y)? I know that we get list of complex numbers from FFT and need to square() or abs() them. But what we will have after that? Is this Decibels?

Q2: Why do we need normalize wav-data before doing FFT? What does depend on this? Before and after normalization I get different results from FFT. If I do normalization, then results of FFT are measured by hundreds, if I don't the results are measured by 1.x small values... Is this Decibels also?

# Read wav-data
fs, data = wavfile.read('eric.wav')

# this is a two channel soundtrack, I get the first track
wavdata = data.T[0]

# this is 16-bit track, b is now normalized on [-1,1)
wavdata = wavdata / (2.0**15)

Q3: What is length of the returned list from FFT? Seems like the length of the result depends on length of given sound file... But in Q1 I supposed to get list of frequencies and their loudness independently from a given source of data. For now, if I cut in half wavdata I will get twice shorter resulting list from FFT...

Complete simple code:

import matplotlib.pyplot as plt
from scipy.fftpack import fft
from scipy.io import wavfile

# load the data 
fs, data = wavfile.read('eric.wav')

# this is a two channel soundtrack, I get the first track 
a = data.T[0]

# calculate fourier transform
y = fft(a)

# show 
plt.plot(abs(y), 'g')

Q4: What do I process results form FFT to get it in form Db vs Hz?

Wav-file could be found here: https://aacapps.com/lamp/voices Thanks.

  • $\begingroup$ Indeed, these are too many questions in one. To start with, it’s no true that y[1] corresponds to 1 Hz. You must calculate the frequencies of corresponding bins, which are separated by fs/N - N being the size of FFT. $\endgroup$
    – jojeck
    Feb 1, 2018 at 20:23

2 Answers 2


One rarely takes an FFT of a whole audio file, or a half. Usually only a sequence of shorter segments some number of milliseconds in duration. The length of the "list of frequencies" will be half of the FFT length (for strictly real data) and the frequencies related to each y[i] will then be proportional to the sample rate and inversely proportional to your chosen FFT length. Thus y[1] will only represent the output of a leaky narrow-band filter centered at 1 Hz if the FFT length is equal to the sample rate.

Decibels are more related to the log of the abs() or log magnitude of the FFT results. But without a calibrated microphone and DAC, the resulting decibels will be relative to some arbitrary level or offset. Normalization merely changes the arbitrary offset.

  • $\begingroup$ Ok. Thanks. Could you give some high level algorithm or explanation of what to do to decompose a phrase to Db vs Hz form? Like: 1. Split wav-data to 1sec slices. 2. Get FFT for a slice 3 ... $\endgroup$
    – artberry
    Feb 1, 2018 at 20:54
  • $\begingroup$ That sounds like it should be a new question (not a comment). And the answer will likely depend on what you want to do with the results. $\endgroup$
    – hotpaw2
    Feb 1, 2018 at 23:26
  • $\begingroup$ Ok. I asked it here: dsp.stackexchange.com/questions/46906/… $\endgroup$
    – artberry
    Feb 1, 2018 at 23:57

The frequencies corresponding to the bins depend on the length of your sample. The $y[n]$ bin corresponds to a frequency in the sampled-time realm of $\frac n N$, for an input vector of $N$ samples. In real time, this works out to $\frac n {T_s N}$, where $T_s$ is the sample interval.

As a more real-world example, if you're sampling at 44kHz and you want the bins to be 1Hz each, you need to collect exactly 44,000 samples.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.