Python中的部分正确频率检测

时间:2015-10-21 22:42:05

标签: python audio signals frequency

我找到了一种算法,它使用自相关和抛物线插值来估计音频信号的频率。

# 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

我知道人类听觉的范围是 20Hz 20kHz 。采样率 44100Hz ,我可以准确地写入和读取 22049Hz 。但是,该算法会误认为某些频率。

给定 840Hz 的信号,它读取 420Hz 。在 20000Hz 时,算法计算 512Hz 。该算法在准确的估计之间振荡并返回不正确的频率。

我对信号处理知之甚少。

1 个答案:

答案 0 :(得分:0)

如果您想估算纯模拟信号的频率,傅里叶变换完全符合您的需求。

import numpy as np

SAMPLE_RATE = 48000
FREQUENCY = 840.0

# simulated pure signal
t = np.linspace(0, 1, SAMPLE_RATE)
signal = np.sin(2 * np.pi * FREQUENCY * t)

# compute the magnitude of the Fourier Transform and its corresponding frequency values
freq_magnitudes = np.abs(np.fft.fft(signal))
freq_values = np.fft.fftfreq(SAMPLE_RATE, 1/SAMPLE_RATE)

# find the max. magnitude
max_positive_freq_idx = np.argmax(freq_magnitudes[:SAMPLE_RATE//2 + 1])

print(freq_values[max_positive_freq_idx]) # 840.0

如果您不熟悉傅里叶变换,例如看看史蒂芬史密斯的第8章The Scientist and Engineer's Guide to Digital Signal Processing