FFT 频谱中的毛刺
Glitches in FFT Spectrum
我的 FFT 以某种方式工作。我用一些频率扫描对其进行了测试,我可以清楚地看到峰值,但我在整个频谱中发现了一些奇怪的毛刺和强烈的噪音。信号上下跳动,有时一些条会消失。我试图读取值并有时得到 NaN 。我在这里做错了什么?
void FFTLive()
{
int sampleCount = 8192;
NAudio.Dsp.Complex[] complex = new NAudio.Dsp.Complex[sampleCount];
float[] dat = new float[sampleCount];
source.clip.GetData(dat, source.timeSamples);
for (int i = 0; i < sampleCount; i++)
{
complex[i].X = dat[i];
complex[i].Y = 0;
}
NAudio.Dsp.FastFourierTransform.FFT(false, (int)Mathf.Log(sampleCount, 2), complex);
for (int i = 0; i < sampleCount; i++)
{
float value = 10 * Mathf.Abs(Mathf.Log10((complex[i].X * complex[i].X + complex[i].Y * complex[i].Y)));
Debug.DrawLine(new Vector3(-10 + (float)(i / 20), -16 + value, 40), new Vector3(-9 + (float)(i / 20), -16 + value, 40), Color.green, 0.002f);
}
}
更新
我添加了 window 并检查了 0,但它看起来仍然有大量噪音。
for (int i = 0; i < sampleCount; i++)
{
complex[i].X = dat[i]*(float)NAudio.Dsp.FastFourierTransform.BlackmannHarrisWindow(i,sampleCount);
complex[i].Y = 0;
}
NAudio.Dsp.FastFourierTransform.FFT(false, (int)Mathf.Log(sampleCount, 2), complex);
for (int i = 0; i < sampleCount / 4; i++)
{
float value = 0;
if (complex[i].X + complex[i].Y != 0)
value = 10 * Mathf.Abs(Mathf.Log10(100 * (complex[i].X * complex[i].X + complex[i].Y * complex[i].Y)));
Debug.DrawLine(new Vector3(-10 + (float)(i / 20), -16, 40), new Vector3(-9 + (float)(i / 20), -16 + value, 40), Color.green, 0.0002f);
}
更新 2
解决了。我忘记了采样数据是 2 个通道,所以我把这两个混在一起导致了所有的故障。所以我将数据数组分成两半,只取第二个应该来自一个通道的条目。
至少有两个问题。
您没有检查最后一个 Log10() 的幅度输入是否不为零。这将导致 NaN。
您没有在 FFT 之前使用 non-rectangular window 函数来移除 windowing 伪影(来自 non-integer-periodic 波形,波形在结束和开始之间是不连续的FFT孔径)。尝试使用 Von Hann 或 Hamming window.
我的 FFT 以某种方式工作。我用一些频率扫描对其进行了测试,我可以清楚地看到峰值,但我在整个频谱中发现了一些奇怪的毛刺和强烈的噪音。信号上下跳动,有时一些条会消失。我试图读取值并有时得到 NaN 。我在这里做错了什么?
void FFTLive()
{
int sampleCount = 8192;
NAudio.Dsp.Complex[] complex = new NAudio.Dsp.Complex[sampleCount];
float[] dat = new float[sampleCount];
source.clip.GetData(dat, source.timeSamples);
for (int i = 0; i < sampleCount; i++)
{
complex[i].X = dat[i];
complex[i].Y = 0;
}
NAudio.Dsp.FastFourierTransform.FFT(false, (int)Mathf.Log(sampleCount, 2), complex);
for (int i = 0; i < sampleCount; i++)
{
float value = 10 * Mathf.Abs(Mathf.Log10((complex[i].X * complex[i].X + complex[i].Y * complex[i].Y)));
Debug.DrawLine(new Vector3(-10 + (float)(i / 20), -16 + value, 40), new Vector3(-9 + (float)(i / 20), -16 + value, 40), Color.green, 0.002f);
}
}
更新 我添加了 window 并检查了 0,但它看起来仍然有大量噪音。
for (int i = 0; i < sampleCount; i++)
{
complex[i].X = dat[i]*(float)NAudio.Dsp.FastFourierTransform.BlackmannHarrisWindow(i,sampleCount);
complex[i].Y = 0;
}
NAudio.Dsp.FastFourierTransform.FFT(false, (int)Mathf.Log(sampleCount, 2), complex);
for (int i = 0; i < sampleCount / 4; i++)
{
float value = 0;
if (complex[i].X + complex[i].Y != 0)
value = 10 * Mathf.Abs(Mathf.Log10(100 * (complex[i].X * complex[i].X + complex[i].Y * complex[i].Y)));
Debug.DrawLine(new Vector3(-10 + (float)(i / 20), -16, 40), new Vector3(-9 + (float)(i / 20), -16 + value, 40), Color.green, 0.0002f);
}
更新 2
解决了。我忘记了采样数据是 2 个通道,所以我把这两个混在一起导致了所有的故障。所以我将数据数组分成两半,只取第二个应该来自一个通道的条目。
至少有两个问题。
您没有检查最后一个 Log10() 的幅度输入是否不为零。这将导致 NaN。
您没有在 FFT 之前使用 non-rectangular window 函数来移除 windowing 伪影(来自 non-integer-periodic 波形,波形在结束和开始之间是不连续的FFT孔径)。尝试使用 Von Hann 或 Hamming window.