我有n音讯的WASAPI回环记录的工作执行情况和数据的FFT。 大多数我得到的数据仅仅是理所应当的,但每过一段时间(10秒到几分钟的时间间隔),它显示了几乎所有频率的幅度。
Basicly画面从滚动右至左与时间和频率上从底部最低频率正在进行对数标度。 该行是错误的。 至于我可以告诉那些不应该在那里。
我得到的音频缓冲器和寄样品给聚合器(适用于海明窗),它实现了n音讯FFT。 我已经检查了数据(FFT结果)之前,我修改它以任何方式(画面不是从原始FFT输出,但desibel缩放)确认FFT结果是给这些行。 我也可以指出该图片修饰为LockBits,所以我想我有什么问题存在的逻辑,但是这就是为什么我检查这说明了同样的问题FFT输出数据。
好吧,我可能是错的,问题可能我在什么地方说是不是,但它确实看起来它从FFT或缓冲器的数据(数据本身或样品的聚集)起源。 不知怎的,我怀疑缓冲区本身被破坏这样的。
如果任何人有任何想法可能是什么造成这一点,我将不胜感激!
UPDATE
所以我决定提请全FFT结果的范围,而不是它的一半。 这表明一些奇怪的事情。 我不知道FFT的,但我认为傅立叶变换应该给围在中间反映的结果。 这当然不是这里的情况。
画面是线性标度,因此画面的正中间是FFT结果的中间点。 底部是第一和顶部是最后一个。
我正在玩一个10kHz的正弦波,这给两条水平线存在,但顶部是超越我。 它似乎也像线围绕图片的底部季度镜像,这样觉得奇怪,我也是如此。
更新2
所以,我从4096提高了FFT的大小为8192,并试图再次。 这是我与正弦频率搞乱输出。
这似乎结果反映两次。 一旦在中间,然后再次上半部和下半部。 和庞大的线现在都没有了。而这看起来就行只出现在底部的一半了。
经过与不同的FFT一些进一步的测试长度似乎线路都在该帐户完全随机的。
更新3
我做了一些测试有很多东西。 我加入了最新的东西是重叠的样本,让我重新使用样品阵列的后半段,在未来FFT的开始。 海明和汉宁窗口它给了我巨大的强度(很喜欢第二张图片我张贴),但与BlackmannHarris。 禁用重叠消除了对每一个窗口函数的最大错误。 就像上面图片中的小错误仍然即使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 needs
private 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!
}
和样品聚合类:
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; }
}
这是我的想法。 我可能会虽然错过了一些东西。 希望这可以帮助!