来自.wav文件的峰值频率

时间:2015-10-21 15:24:20

标签: c# wav naudio audio-processing

我有一个.wav文件,当我在弹吉他音符时由我录制。然后我使用下面的程序来读取我的.wav文件数据。我使用了Naudio库。

AudioFileReader readertest = new AudioFileReader(@"E:\song\music.wav");
int bytesnumber = (int)readertest.Length;
var buffer = new float[bytesnumber];
readertest.Read(buffer, 0, bytesnumber);

for (int i = 0; i < buffer.Length; i++)
{
    Console.Write(buffer[i] + "\n");
}

输出如下。(输出的一部分)。

       0.00567627
       0.007659912
       0.005187988
       0.005706787
       0.005218506
       0.003051758
       0.004669189
       0.0007324219
       0.004180908
      -0.001586914
       0.00402832
      -0.003479004
       0.003143311
      -0.004577637
       0.001037598
      -0.005432129
      -0.001800537
      -0.005157471

我对此输出数据包含的内容感到困惑。我想拍摄音符的峰值频率。如何将上述数据转换为频率?

1 个答案:

答案 0 :(得分:3)

您看到的数据是浮点格式的原始样本。这是表示音频信号的波形数据。当发送到播放设备时,它会产生声音。

要获得频率图,您需要通过FFT函数传递样本数据块以获得基本分析,并作为每个频率仓的一对值(XY)返回。由此您可以计算信号中频率的功率电平。对于数组中的每个元素,幂函数基本上是10 * Log10(Sqrt(X*X + Y*Y))。 (你可能从未想过你会在Trig课程之外使用毕达哥拉斯定理!)

结果数组中的项目数与传递给FFT时的项数相同。每个值代表频率n * Fs / N,其中n是数组的偏移量,N是数组长度,Fs是采样率。取下半部分样本并使用它们。数组上半部分中的任何内容对您都没用,因此请确保您的采样率足够高,以使您感兴趣的频率低于采样率的一半。

传递给FFT的缓冲区大小将在频率分辨率,响应时间和窗口函数容差之间进行权衡。太短的缓冲区将会出现令人讨厌的光谱流失,并且您的频率分辨率会超出窗口,时间太长而且可能会迟到识别音调。当然,它必须是FFT的2的幂,所以选择正确的值可能需要一些工作。测试各种选项,看看哪种选择最合适。

Mark在NAudioWpfDemo示例应用程序中编写了一些用于FFT可视化的代码。查看包含幂函数的SpectrumAnalyzer自定义控件(在SpectrumAnalyzer.GetYPosLong中)。另请查看包含FFT聚合代码示例的SampleAggregator类。