声音样本的数学分析(作为数字数组)

时间:2008-09-17 20:27:29

标签: vb.net audio audio-analysis

我需要找到一个样本的频率,存储(在vb中)作为一个字节数组。样本是一个正弦波,已知频率,所以我可以检查),但数字有点奇怪,我的数学foo很弱。 全系列值0-255。 99%的数字在235到245的范围内,但有一些异常值降至0和1,其余1%则高达255。 如何对此进行归一化以去除异常值(计算235-245间隔,因为它可能随着不同的样本而变化),以及如何计算过零点以获得频率? 如果这个描述是垃圾,请道歉!

7 个答案:

答案 0 :(得分:7)

FFT可能是最好的答案,但是如果你真的想通过你的方法来做,那试试这个:

要进行标准化,首先要制作一个直方图,以计算从0到255的每个值的出现次数。然后从每一端丢弃X%的值,例如:

for (i=lower=0;i< N*(X/100); lower++)
  i+=count[lower];
//repeat in other direction for upper

现在使用

进行标准化
A[i] = 255*(A[i]-lower)/(upper-lower)-128

将结果丢弃在-128..127范围之外。

现在你可以计算过零点。为了确保您不会受到噪音的愚弄,您可能希望跟踪最后几个点的斜率,并且仅在平均斜率正确的情况下计算交叉点。

答案 1 :(得分:5)

攻击这个问题的标准方法是考虑一个数据块,希望至少是实际频率的两倍(获取更多数据也不错,所以高估一点是好的),然后采用{{3}并猜测频率对应于得到的FFT频谱中的最大数字。

顺便说一下,之前已经问过非常类似的问题 - 你也可以搜索这些答案。

答案 2 :(得分:3)

使用傅立叶变换,它比计算零交叉更加噪声不敏感

编辑:@WaveyDavey

我发现了一个用于进行FFT的F#库:From here

  

事实证明,最好的免费   我为F#找到的实现   到目前为止用户仍然很棒   FFTW库。他们的网站有一个   预编译的Windows DLL。我写过   最小的绑定允许   从F#线程安全访问FFTW,   同时拥有大师和简单的界面。   性能非常出色,32位   Windows XP Pro仅高达35%   比64位Linux慢。

现在我确定你可以从VB.net,C#等调用F#lib,这应该在他们的文档中

答案 3 :(得分:2)

如果我从你的描述中理解得很清楚,你所拥有的是一个信号,它是一个正弦加一个常数加上一些随机故障的组合。说,像

x[n] = A*sin(f*n + phi) + B + N[n]

其中N [n]是你要摆脱的“小故障”噪音。

如果毛刺是单样本长的,您可以使用中值滤波器去除它们,中值滤波器必须大于毛刺长度。在故障的两边。长度为1的毛刺意味着你将有足够的中位数为3个样本的长度。

y[n] = median3(x[n])

计算中位数:取你想要过滤的x的样本(x [n-1],x [n],x [n + 1]),对它们进行排序,输出是中间的。

现在噪声信号消失,摆脱恒定信号。我知道缓冲区的长度有限且已知,因此您只需计算整个缓冲区的平均值即可。摘要它。

现在你有了单个窦信号。您现在可以通过计算过零点来计算基频。计算前一个样本低于0的样本数量。该时间段是缓冲区样本的总量除以此值,频率是该时间段的对数(1 / x)。

答案 4 :(得分:1)

虽然我会与大多数人一起说,看起来你想要的是一个fft解决方案(fft算法非常快),如果fft不是任何理由的答案,你可能想尝试拟合正弦曲线使用拟合程序并读取拟合频率的数据。

使用Fityk,您可以加载数据,并适合a*sin(b*x-c) 2*pi/b,其中{{1}}会在拟合后为您提供频率。

Fityk可以从一个gui,一个脚本命令行使用,并且有一个C ++ API,因此可以直接包含在你的程序中。

答案 5 :(得分:0)

我用Google搜索“基本fft”。 Visual Basic FFT你的问题尖叫FFT,但要小心,使用FFT而不了解一点关于DSP可能导致你不理解或不知道它们来自哪里的结果。

答案 6 :(得分:0)

将频率分析器放在http://www.relisoft.com/Freeware/index.htm并运行它并查看代码。