audio – How to interpolate the peak amplitude of an fft output?

I want to find the peak amplitude of an audio signal in a given frequency area.
My problem is that if the signal has a strong resonating frequency between 2 fft bins, then both bins are way below the actual amp.

I wrote this example python code, which:

  1. Generates a sine with amp 1 at a frequency, which perfectly fits the 34th bin. As expected the plot shows a peak of 1.

  2. Generates a sine with amp 1 at a frequency, which is exactly between the frequency of the 33rd and 34th bin. The graph only shows a peak of around 0.75 instead of 1.

I tried some different interpolation methods, but none yielded much more than a peak of 0.75. Also note that I don’t need the amp of a specific frequency, but rather the peak amp in a given frequency domain.

import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate as interp

for i in (34,33.5):
    freq = i/2048*24000
    readd = np.sin(2*np.pi*freq*np.arange(4096)/48000)

    Y_k = np.fft.fft(readd)[0:2048]/4096 # FFT function from numpy
    Y_k[1:] = 2*Y_k[1:]
    fft = np.abs(Y_k)

    x = range(0,6)
    y = fft[31:37]
    xnew = np.linspace(0, 5, num=81, endpoint=True)
    f = interp.interp1d(x,y,kind='cubic')
    plt.plot(x, y, 'o', xnew, interp.krogh_interpolate(x,y,xnew),'-', xnew, f(xnew), 'o')

Read more here: Source link