title: Calculate power of FFT Frequency component
body: <p>I am trying to calculate the power measured in dB of an FFT frequency component for 48000 samples of audio data with a sample rate of 48000 Hz using numpy. The file I am testing has a full power (0 dB) sine wave of 1000 Hz. I am expecting a result of 0 dB when I calculate the Root Mean Squared value of the energy band with the most energy, however, I get the following:</p>
  
  <pre><code>1000.0Hz 41.8387130383 dB
  </code></pre>
  
  <p>Would any one have an explanation as to why I am getting a different result? My code is below. </p>
  
  <p>'data' is a numpy array of 48000 samples with 32 bit precision. As I understand, I need to normalize the fft result by the length of the data sample.</p>
  
  <pre><code>p = np.fft.fft(data)
  uniquePts = math.ceil(len(data)+1/2.0)
  p = p[0:uniquePts]
  freqs = np.fft.fftfreq(len(p))
  </code></pre>
  
  <p>normalize the fft result by the length of the data sample</p>
  
  <pre><code>p = np.divide(p,float(len(data)))
  p = np.abs(p)
  p = np.power(p,2)
  </code></pre>
  
  <p>multiply the FFT result by two to account for the fact that we halved the total number elements in the return FFT array</p>
  
  <pre><code>if len(data) % 2 &gt; 0:
    p[1:len(p)] = np.multiply(p[1:len(p)], 2)
  else:
    p[1:len(p) - 1] = np.multiply(p[1:len(p) -1], 2)
  </code></pre>
  
  <p>At this point, I find the FFT component with the most energy represented by <code>idx</code>:</p>
  
  <pre><code>data_size=48000 #1 second of audio
  idx=np.argmax(np.abs(p)**2) 
  rms = math.sqrt(p[idx])
  dbRep = 20 * math.log10((1.0 * rms)/data_size)
  print abs(freqs[i] * frate), dbRep
  </code></pre>