# What should my reference value be when converting FFT bin amplitudes to dB?

I want to transform my FFT output values into a dB scale, but I'm struggling to determine the function I should run each bin amplitude through. My understanding of the decibel scale is that a value representing an intensity must be divided by some reference intensity. The log of this ratio, times 20, will represent the dB scale value:

$$\text{dB} = 20 \log_{10}\frac{\text{intensity}}{\text{intensity}_{\text{ref}}}$$

I should be able to pass each an FFT bin amplitude value into this equation as $$\text{intensity}$$, and the result will be the dB level of that bin.

Unfortunately, I'm not sure what $$\text{intensity}_{\text{ref}}$$ should be. Based on my reading, I believe it should represent the maximum possible intensity. If the readings were samples from a wave, this would be easy (the highest possible reading for 8-bit audio would be 255; for 16-bit it would be 65535, etc). However, I'm not sure that FFT outputs have such a predictable range or scale.

One option would be normalizing the amplitude values (dividing each value by the maximum amongst all bins for all FFT windows computed for the signal). This way, the bin with the highest amplitude would be at 0 dB and all others would be negative values relative to that maximum. However, this would only work if I pre-computed every FFT window for an entire signal. What if I was trying to compute dB values for an FFT of a just a single window?

So my question is: what is $$\text{intensity}_{\text{ref}}$$? I'm still relatively new to signal processing, so if there's an easy way to guarantee some range of FFT amplitude values or any other obvious solution I'm missing please let me know.

You tagged this , so, that's basically your answer, because, yes, the output of a DFT is very much predictable!

What you choose, however, as reference amplitude is up to you to define as useful to you. I can but make a recommendation:

Assume you're transforming a constant vector of $$N$$ maximum (ADC) values; that'll give you, depending on the normalization that your DFT applies, an all-0 vector with the equivalent energy in the DC-bin. That'd be a useful value for the full-scale maximum; frequency shifting and superposition with other signals can never yield a more powerful bin.

I think I figured it out.

The step I was missing was scaling my FFT output values by multiplying each amplitude by $$\frac{2}{N}$$ where $$N$$ is the length of my Fourier transform. I came to this realization thanks to these two resources.

By including this scaling step, the FFT output values will be in proportion with the sampled wave values that served as input to the FFT algorithm. Now, it becomes clear that $$intensity^{ref}$$ is equal to the maximum possible sample value from the time domain. For signed 16-bit audio, this is $$\lceil\frac{65535}{2}\rceil = 32768$$. This answer helped me understand this.

• That's not universally true – different DFT implementations apply different normalizations. That's why my answer recommends simply trying out what your DFT does. – Marcus Müller Mar 19 '19 at 20:50
• @MarcusMüller I see. I had trouble understanding the last paragraph of your answer because I'm not familiar with the terms ADC or DC. I also wasn't sure exactly what you meant by " a constant vector of $N$ maximum values." Does this mean a vector in which every element is the maximum possible value? I haven't been studying signal processing concepts for very long, so I definitely have some pretty major knowledge gaps. – Miles Henrichs Mar 19 '19 at 21:58
• Does this mean a vector in which every element is the maximum possible value? Yes, that was exactly what I wanted to say :) – Marcus Müller Mar 19 '19 at 22:01
• @MarcusMüller Interesting idea! I tried creating a vector that looks like $[32768 \text{ } 32768 \text{ .. } 32768]$ and the FFT result I got back was all zeroes except for the first bin, which had value $134201344$. I suppose this would be the maximum possible FFT output without any scaling? If I scale the FFT result according to how I described in my answer, the first bin contains $32764$. Any idea why it is this instead of $32768$, which would be what I'd expect? – Miles Henrichs Mar 19 '19 at 22:15
• yep, that's right, based on FFTW, but doing its own normalization! (ifft(fft(x)) == x in Matlab, but in FFTW, it's x·N, iirc.) – Marcus Müller Mar 20 '19 at 15:32