我有一个.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
我对此输出数据包含的内容感到困惑。我想拍摄音符的峰值频率。如何将上述数据转换为频率?
答案 0 :(得分:3)
您看到的数据是浮点格式的原始样本。这是表示音频信号的波形数据。当发送到播放设备时,它会产生声音。
要获得频率图,您需要通过FFT函数传递样本数据块以获得基本分析,并作为每个频率仓的一对值(X
和Y
)返回。由此您可以计算信号中频率的功率电平。对于数组中的每个元素,幂函数基本上是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
类。