我成功地使用NAudio成功地将音频数据流传输到输出设备(扬声器):
private void OnDataAvailable(object sender, WaveInEventArgs e)
{
var buffer = e.Buffer;
var bytesRecorded = e.BytesRecorded;
Debug.WriteLine($"Bytes {bytesRecorded}");
样本输出:
Bytes 19200
Bytes 19200
Bytes 19200
Bytes 19200
Bytes 19200
Bytes 19200
Bytes 19200
Bytes 19200
Bytes 19200
Bytes 19200
Bytes 19200
Bytes 23040
Bytes 19200
Bytes 19200
Bytes 19200
Bytes 19200
Bytes 19200
然后我使用https://stackoverflow.com/a/20414331
将其转换(FFT)为x和y值var buffer = e.Buffer;
var bytesRecorded = e.BytesRecorded;
//Debug.WriteLine($"Bytes {bytesRecorded}");
var bufferIncrement = _waveIn.WaveFormat.BlockAlign;
for (var index = 0; index < bytesRecorded; index += bufferIncrement)
{
var sample32 = BitConverter.ToSingle(buffer, index);
_sampleAggregator.Add(sample32);
}
示例输出:
x: -9.79634E-05, y: -9.212703E-05
x: 6.897306E-05, y: 2.489315E-05
x: 0.0002080683, y: 0.0004317867
x: -0.0001720883, y: -6.681971E-05
x: -0.0001245111, y: 0.0002880402
x: -0.0005751926, y: -0.0002682915
x: -5.280507E-06, y: 7.297558E-05
x: -0.0001143928, y: -0.0001156801
x: 0.0005231025, y: -0.000153206
x: 0.0001011164, y: 7.681748E-05
x: 0.000330695, y: 0.0002293986
不确定这是否可能,或者我只是误解了流的回归,但我想获得音频流的频率以便用飞利浦Hue做一些事情。上面的x,y值是在CIE颜色空间中使用的小的方法。我做错了什么,或者我完全误解了OnDataAvailable中缓冲区中的数据是什么?
谢谢!
编辑:
我已根据评论修改了OnDataAvailable代码,Autotune程序的教程如下:
private void OnDataAvailable(object sender, WaveInEventArgs e)
{
var buffer = e.Buffer;
float sample32 = 0;
for (var index = buffer.Length > 1024 ? buffer.Length - 1024 : buffer.Length; index < e.BytesRecorded; index += 2)
{
var sample = (short) ((buffer[index + 1] << 8) | buffer[index + 0]);
sample32 = sample / 32768f;
Debug.WriteLine(sample32);
LightsController.SetLights(Convert.ToByte(Math.Abs(sample32) * 255));
_sampleAggregator.Add(sample32);
}
var floats = BytesToFloats(buffer);
if (sample32 != 0.0f)
{
var pitchDetect = new FftPitchDetector(sample32);
var pitch = pitchDetect.DetectPitch(floats, floats.Length);
Debug.WriteLine($"Pitch {pitch}");
}
}
希望我只使用缓冲区中的最后一组元素,因为它似乎无法清除自己,而且我只对最新的可用数据集感兴趣才能获得频率目前的音频。但是,当调用DetectPitch方法时,我仍会偶尔获得索引异常。我哪里错了?我希望用频率来改变色调灯泡的颜色和亮度。
答案 0 :(得分:1)
使用
fPeak = SamplingRate * BinNumberOfPeak / FFTLength ;