NAudio fft结果给出所有频率C#的强度

NAudio fft结果给出所有频率C#的强度,第1张

概述我有一个工作实现NAudio的wasapi环回录制和数据的FFT. 我得到的大多数数据都是应该的,但每隔一段时间(10秒到几分钟的间隔),它几乎在所有频率上显示振幅. 基本上,图像从右到左滚动,时间和频率从底部的最低频率开始以对数标度进行.这些线是错误.据我所知,那些不应该在那里. 我得到音频缓冲区并将样本发送到聚合器(应用汉明窗口),该聚合器实现了NAudio FFT.在我以任何方式修改它之前检 我有一个工作实现NAudio的wasAPI环回录制和数据的FFT.
我得到的大多数数据都是应该的,但每隔一段时间(10秒到几分钟的间隔),它几乎在所有频率上显示振幅.

基本上,图像从右到左滚动,时间和频率从底部的最低频率开始以对数标度进行.这些线是错误.据我所知,那些不应该在那里.

我得到音频缓冲区并将样本发送到聚合器(应用汉明窗口),该聚合器实现了NAudio FFT.在我以任何方式修改它之前检查了数据(FFT结果)(图像不是来自原始FFT输出,而是desibel缩放),确认FFT结果给出了那些线.我还可以指出图片是用LockBits修改的,所以我认为那里的逻辑有问题,但这就是为什么我检查了显示相同问题的FFT输出数据.

好吧,我可能是错的,问题可能在某个地方,我说它不是,但它似乎真的来自FFT或缓冲数据(数据本身或样本的聚合).不知怎的,我怀疑缓冲区本身是否像这样被破坏了.

如果有人知道可能导致这种情况的话,我会非常感激!

UPDATE

所以我决定绘制整个FFT结果范围而不是它的一半.它表现出一些奇怪的.我不确定FFT,但我认为傅里叶变换应该给出一个反映在中间的结果.这当然不是这种情况.

图像是线性比例的,因此图像的中间位置是FFT结果的中间点.底部是第一个,顶部是最后一个.

我正在播放一个10kHz的正弦波,它给出了两条水平线,但顶部超出了我的范围.看起来这些线条在图片的底部四分之一处被镜像,所以这对我来说也很奇怪.

更新2

所以我将FFT大小从4096增加到8192再次尝试.这是我输出正弦频率的输出.

似乎结果反映了两次.一旦在中间,然后再在上半部和下半部.巨大的线条现在已经消失了……看起来这些线条现在只出现在下半部分了.

在使用不同的FFT长度进行一些进一步测试之后,该线路中的线条似乎是完全随机的.

更新3

我做了很多测试.我添加的最新内容是样本重叠,以便在下一个FFT开始时重用示例数组的后半部分.在汉明和汉恩的窗户上,它给了我很大的强度(就像我发布的第二张照片一样)但不是布莱克曼哈里斯.禁用重叠会删除每个窗口函数上的最大错误.即使使用BH窗口,顶部图片中的较小错误仍然存​​在.我仍然不知道为什么会出现这些线条.

我当前的表单允许控制使用哪个窗口功能(前面提到的三个),重叠(开/关)和多个不同的绘图选项.这允许我在更改时比较所有影响方效果.

我会进一步调查(我很确定我在某些方面犯了一个错误)但是很好的建议非常受欢迎!

解决方法 问题在于我处理数据数组的方式.现在就像一个魅力.

代码(删除多余的,可能会增加错误):

// Other inputs are also usable. Just look through the NAudio library.private IWaveIn waveIn; private static int fftLength = 8192; // NAudio fft wants powers of two!// There might be a sample aggregator in NAudio somewhere but I made a variation for my needsprivate SampleAggregator sampleAggregator = new SampleAggregator(fftLength);public Main(){    sampleAggregator.FftCalculated += new EventHandler<FftEventArgs>(FftCalculated);    sampleAggregator.PerformFFT = true;    // Here you decIDe what you want to use as the waveIn.    // There are many options in NAudio and you can use other streams/files.    // Note that the code varIEs for each different source.    waveIn = new WasAPILoopbackCapture();     waveIn.DataAvailable += OnDataAvailable;    waveIn.StartRecording();}voID OnDataAvailable(object sender,WaveInEventArgs e){    if (this.Invokerequired)    {        this.BeginInvoke(new EventHandler<WaveInEventArgs>(OnDataAvailable),sender,e);    }    else    {        byte[] buffer = e.Buffer;        int bytesRecorded = e.BytesRecorded;        int bufferIncrement = waveIn.WaveFormat.BlockAlign;        for (int index = 0; index < bytesRecorded; index += bufferIncrement)        {            float sample32 = BitConverter.ToSingle(buffer,index);            sampleAggregator.Add(sample32);        }    }}voID FftCalculated(object sender,FftEventArgs e){    // Do something with e.result!}

和Sample Aggregator类:

using NAudio.Dsp; // The Complex and FFT are here!class SampleAggregator{    // FFT    public event EventHandler<FftEventArgs> FftCalculated;    public bool PerformFFT { get; set; }    // This Complex is NAudio's own!     private Complex[] fftBuffer;    private FftEventArgs fftArgs;    private int fftPos;    private int fftLength;    private int m;    public SampleAggregator(int fftLength)    {        if (!IsPowerOfTwo(fftLength))        {            throw new ArgumentException("FFT Length must be a power of two");        }        this.m = (int)Math.Log(fftLength,2.0);        this.fftLength = fftLength;        this.fftBuffer = new Complex[fftLength];        this.fftArgs = new FftEventArgs(fftBuffer);    }    bool IsPowerOfTwo(int x)    {        return (x & (x - 1)) == 0;    }    public voID Add(float value)    {        if (PerformFFT && FftCalculated != null)        {            // Remember the window function! There are many others as well.            fftBuffer[fftPos].X = (float)(value * FastFourIErtransform.HammingWindow(fftPos,fftLength));            fftBuffer[fftPos].Y = 0; // This is always zero with audio.            fftPos++;            if (fftPos >= fftLength)            {                fftPos = 0;                FastFourIErtransform.FFT(true,m,fftBuffer);                FftCalculated(this,fftArgs);            }        }    }}public class FftEventArgs : EventArgs{    [DeBUGgerStepThrough]    public FftEventArgs(Complex[] result)    {        this.Result = result;    }    public Complex[] Result { get; private set; }}

这就是我想的.我可能错过了一些东西.希望这可以帮助!

总结

以上是内存溢出为你收集整理的NAudio fft结果给出所有频率C#的强度全部内容,希望文章能够帮你解决NAudio fft结果给出所有频率C#的强度所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/1261840.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存