# What's the maximum energy for a finite signal?

I'm trying to calculate the spectral density of a signal. What I'm expecting is a scale in dbFS where 0 dbFS would be the maximal theorical energy if all my signal is concentrated in a single frequency (without clipping, of course).

So, I'll calculate a ratio :

float dbfs = 20.Math.log10(freq_energy/max_theorical_energy);


As an example, I'm using a 16 bits signal sampled at 44100 Hz with 2048 samples for each "sound packet". To get that maximal theorical energy, I suppose I generate a signal at 44100/2048 Hz (around 21 Hz). So, in one "sound packet", I will get one single complete sine cycle. And, as temporal_energy = frequency_energy (Parseval Theorem), I used that routine to find that max_theorical_energy, based on the energy of that theorical temporal signal :

double max_energy
for (int i=0 ; i<2048 ; i++) {
max_energy+=Math.pow( Math.abs ( Math.sin(2*Math.Pi/2048) * Math.pow(2, 15) ), 2);
//2^15 = 32000 = maximum absolute value of a 16 bit signal
}


Then, I generated signals at a given frequencie (210 Hz for example) and compared the energy of that signal to my theorical result. As the values for each frequencies are complex, I used that routine to get the energy of my signal (still generating 2048 samples for each "sound packet) :

double signal_energy = 0d;
// datas[] represent the values of my signal after a FFT
for (int i = 0 ; i<datas.length ; i++) {
signal_energy+= Math.pow(datas[i].getReal(), 2) + Math.pow(datas[i].getImaginary(), 2)
}


So, now, if I calculate the ratio signal_energy / max_theorical_energy, I'm expecting something around 1. But the result is 1.xxxxE8 ! It's very far from 1...

So, what's wrong ? Where are my mistakes ?

Thank you for your help.

• How is your FFT algorithm normalized? Are you using a window function? – endolith Dec 21 '18 at 16:19
• No, I'm not using any window function. And for my FFT, I'm using a classical "reordering then butterfly" function. I tested my FFT algorythm with few examples (like the one I found on wikipedia) and it seems working. I'm sure it's a "small nothing" which is the cause of my problem but, the smallest it is, the harder it is to find it... – Dr_Click Dec 21 '18 at 16:27
• So if you have a 0 dBFS sine wave that fits perfectly into a single bin, with FFT of length N, the amplitude at that bin is 0.5 * N? This is my note to self to remember: gist.github.com/endolith/236567 – endolith Dec 21 '18 at 16:33
• @endolith : thank you for your answers and for your help. I will keep your link for future explorations of signal processing. Merry Christmas – Dr_Click Dec 21 '18 at 16:34

Ok, I finally got it !

There were two mistakes in my code.
First one : when calculating the max_energy, I just "forgot" to index "i" (when I was talking about a "small nothing"...)

double max_energy
for (int i=0 ; i<2048 ; i++) {
max_energy+=Math.pow( Math.abs ( Math.sin(i*2*Math.Pi/2048) * Math.pow(2, 15) ), 2);
//2^15 = 32000 = maximum absolute value of a 16 bit signal
}


And second mistake : when I'm calculating the maximal energy with frequencies, I have to divide by the number of samples. So, my routine is becoming :

double signal_energy = 0d;
// datas[] represent the values of my signal after a FFT
for (int i = 0 ; i<datas.length ; i++) {
signal_energy+= Math.pow(datas[i].getReal(), 2) + Math.pow(datas[i].getImaginary(), 2)/datas.length
}


And, now, it works. The ratio is 1.00000xxx