c# – 如何使用NAudio实时计算FFT(ASIO输出)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 如何使用NAudio实时计算FFT(ASIO输出),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2672字,纯文字阅读大概需要4分钟。
内容图文
![c# – 如何使用NAudio实时计算FFT(ASIO输出)](/upload/InfoBanner/zyjiaocheng/818/83f18b7e856f4c61a1a262a77c217195.jpg)
我正在编写吉他(小提琴)英雄的克隆作为本学年的最终项目.
我的想法是从我的电子小提琴中获取输入,通过FFT进行分析,做一些逻辑并绘制并通过扬声器输出.也许是并行线程中的一些步骤.
我已经实现了Asio低延迟输入输出,但我在实现实时FFT时遇到了很大的问题.
这是一个与sampleAggregator一起设置asioOut的代码.样本聚合器应存储每次调用AudioAvailable()时添加的样本,并在样本数超过fftLength时触发FFT计算.
private static int fftLength = 8192;
private SampleAggregator sampleAggregator = new SampleAggregator(fftLength);
void asioStartPlaying(object sender, EventArgs e)
{
sampleAggregator.PerformFFT = true;
sampleAggregator.FftCalculated += new EventHandler<FftEventArgs>(FftCalculated);
var asioOut = new AsioOut();
BufferedWaveProvider wavprov = new BufferedWaveProvider(new WaveFormat(48000, 1));
asioOut.AudioAvailable += new EventHandler<AsioAudioAvailableEventArgs> (asio_DataAvailable);
asioOut.InitRecordAndPlayback(wavprov, 1, 25);
asioOut.Play();
}
void asio_DataAvailable(object sender, AsioAudioAvailableEventArgs e)
{
byte[] buf = new byte[e.SamplesPerBuffer*4];
for (int i = 0; i < e.InputBuffers.Length; i++)
{
Marshal.Copy(e.InputBuffers[i], buf, 0, e.SamplesPerBuffer*4);
Marshal.Copy(buf, 0, e.OutputBuffers[i], e.SamplesPerBuffer*4);
}
for (int i = 0; i < buf.Length; i=i+4)
{
float sample32 = BitConverter.ToSingle(buf, i);
sampleAggregator.Add(sample32);
}
e.WrittenToOutputBuffers = true;
}
SampleAggregator取自NAudio fft result gives intensity on all frequencies C#.
Asio以Int32LSB样本类型输出数据.在buf中,值为0到255.
这是在计算fft时调用的函数(从SampleAggregator类触发).
void FftCalculated(object sender, FftEventArgs e)
{
for (var i = 0; i < e.Result.Length; i++)
{
Debug.WriteLine("FFT output.");
Debug.WriteLine(e.Result[i].X);
Debug.WriteLine(e.Result[i].Y);
}
}
但FFT总是输出NaN.
我认为转换为float存在问题.
有人能指出我正确的方向吗?
EDIT_1:我将DataAvailable()中的循环更改为
for (int i = 0; i < e.SamplesPerBuffer * 4; i++)
{
float sample32 = Convert.ToSingle(buf[i]);
sampleAggregator.Add(sample32);
}
FFT现在输出数据.但我认为他们不正确.错误必须是asio样本和浮点值之间的转换.但我对字节操作不太满意.
e.GetAsInterleavedSamples能以某种方式提供帮助吗?
来自FFT的原始数据样本:
X:-5,304741
Y:-0,7160959
X:6,270798
Y:-0,4169312
X:-8,851931
Y:-0,4485725
我注意到,来自FFT的原始数据中的前几个和最后几个值在某种程度上比其他数据大.使计算量级变得棘手.
解决方法:
这个问题就像我想到的那样,将来自Asio的样本数据(buf数组中连续4个字节)转换为fft浮点数. BitConvertor应该做的伎俩,但它在某种程度上使fft输出NaN在我的情况下.所以我尝试了这种转换.
for (int i = 0; i < e.SamplesPerBuffer * 4; i=i+4)
{
float sample = Convert.ToSingle(buf[i] + buf[i+1] + buf[i+2] + buf[i+3]);
sampleAggregator.Add(sample);
}
而且效果很好.即使采样率为192 000.
内容总结
以上是互联网集市为您收集整理的c# – 如何使用NAudio实时计算FFT(ASIO输出)全部内容,希望文章能够帮你解决c# – 如何使用NAudio实时计算FFT(ASIO输出)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。