Я нашел алгоритм, который использует автокорреляцию и параболическую интерполяцию для оценки частоты звукового сигнала.
# correct the signal.
auto = scipy.signal.fftconvolve(signal, signal[::-1], mode='full')
auto = auto[len(auto)/2:]
# find the first minimum point in the signal.
difference = numpy.diff(auto)
start = matplotlib.mlab.find(difference > 0)[0]
# find the peak from that position.
peak = numpy.argmax(auto[start:]) + start
# calculate the period using parabolic interpolation.
period = 1/2.0 * (auto[peak-1] - auto[peak+1]) / (auto[peak-1] - 2 * auto[peak] + auto[peak+1]) + peak
frequency = sample_rate / period
Я знаю, что диапазон человеческого слуха составляет от 20 Гц до 20 кГц. При частоте дискретизации 44100 Гц я могу точно писать и читать 22049 Гц. Однако алгоритм ошибается на некоторых частотах.
Для сигнала 840 Гц он читает 420 Гц. При 20000 Гц алгоритм вычисляет 512 Гц. Алгоритм колеблется между точными оценками и возвращением неверной частоты.
Я не очень разбираюсь в обработке сигналов.