【发布时间】:2012-11-14 10:38:13
【问题描述】:
如何简单分析wave文件的频率?没有额外的模块。
【问题讨论】:
如何简单分析wave文件的频率?没有额外的模块。
【问题讨论】:
“分析”是什么意思?它可能意味着很多不同的东西,但我知道的最简单的方法之一是使用convolution,您可以轻松地为discrete functions 实现它(您将在数组中找到点或尝试离散步骤):
这可以通过以下方式轻松完成:
for i in main_array:
from = i - len(convolution_kernel)/2
// Todo: check boundaries
result[i] = 0
for j in convolution_kernel:
result[i] += convolution_kernel[j] * main_array( from+j)
或者你可以使用循环卷积(想法取自 eryksuns 评论):
result = [sum(f[m]*g[n-m] for m in xrange(len(f))) for n in xrange(len(g))]
这将使您能够测试某个信号是否存在于另一个信号中(您将尝试 10、20、50 等频率...并获得最佳结果)。
您也可以google determine wave frequency 或研究一下Fourier transformation(它是很多信号处理算法的基础)。
【讨论】:
result = [sum(f[m]*g[(n-m)%len(g)] for m in xrange(len(f))) for n in xrange(len(g))]。
g[n-m]。
如果您的波形文件仅包含一个音符,您只需检测波形的周期性即可获得基频(不是谐波)。通过寻找 0-crossings 来做到这一点。
【讨论】:
免责声明:信号处理不是我的专长,这个答案可能有点粗略和粗略;随时纠正/我:)
我会研究傅立叶分析。 Fourier transformation 将您的输入从时域转换为频域。让我再解释一下:
例如,在对声音进行采样时,您可以确定采样频率和位深度。我相信 CD 的采样频率为 44.1 kHz,分辨率为 16 位。样本。这意味着音乐每秒采样 44,100 次并转换为 16 位值。音乐表示为长度为 44,100 的向量(或数组)。它是时间的函数,因此这是时域。
另一方面,对数据进行傅里叶变换,您可以将数据表示为频率的函数。您仍然会有一个 44,100 个元素长的向量,但每个元素将代表幅度 - 您在每个频率上采样了多少“信号”!换句话说,您的信号在整个采样周期内总共包含多少给定频率的信号。
您应该研究离散傅里叶分析和快速傅里叶变换 (FFT) 的实现。
这个问题更多地涉及 FFT 分析: Scipy/Numpy FFT Frequency Analysis
编辑:
我在网上无耻地窃取了一些图形:
FFT 公式:
时域与频域:
【讨论】:
如果您不想实现整个 FFT 算法并且不需要任何其他模块,那么我会推荐 Goertzel Algorithm,它实际上是针对特定频率的傅里叶变换,并为您提供该频率下的功率一个样本:
define goertzel(sample, target_frequency, sample_rate):
s_prev = 0
s_prev2 = 0
normalized_frequency = target_frequency / sample_rate
coeff = 2 * cos(2 * PI * normalized_frequency)
for element in sample:
s = element + coeff * s_prev - s_prev2
s_prev2 = s_prev
s_prev = s
end
power = s_prev2 * s_prev2 + s_prev * s_prev - coeff * s_prev * s_prev2
return power
【讨论】: