得到离散傅里叶变换数组的结果
本文关键字:数组 结果 变换 傅里叶 | 更新日期: 2023-09-27 18:01:42
我刚刚写了dft的实现。下面是我的代码:
int T = 2205;
float[] sign = new float[T];
for (int i = 0, j = 0; i < T; i++, j++)
sign[i] = (float)Math.Sin(2.0f * Math.PI * 120.0f * i/ 44100.0f);
float[] re = new float[T];
float[] im = new float[T];
float[] dft = new float[T];
for (int k = 0; k < T; k++)
{
for (int n = 0; n < T; n++)
{
re[k] += sign[n] * (float)Math.Cos(2.0f* Math.PI * k * n / T);
im[k] += sign[n] * (float)Math.Sin(2.0f* Math.PI * k * n / T);;
}
dft[k] = (float)Math.Sqrt(re[k] * re[k] + im[k] * im[k]);
}
所以采样频率是44100 Hz,我有一个120Hz窦波的50ms片段。根据结果,我有一个峰值的dft函数在pont 7和2200。我是否做错了什么,如果没有,我应该如何解释结果?
我尝试了AFORGE的FFT方法。这是我的代码。
int T = 2048;
float[] sign = new float[T];
AForge.Math.Complex[] input = new AForge.Math.Complex[T];
for (int i = 0; i < T; i++)
{
sign[i] = (float)Math.Sin(2.0f * Math.PI * 125.0f * i / 44100.0f);
input[i].Re = sign[i];
input[i].Im = 0.0;
}
AForge.Math.FourierTransform.FFT(input, AForge.Math.FourierTransform.Direction.Forward);
AForge.Math.FourierTransform.FFT(input, AForge.Math.FourierTransform.Direction.Backward);
我期望得到原来的符号,但我得到了一些不同的东西(一个只有正值的函数)。这正常吗?提前感谢!
你的代码看起来是正确的,但它可以更有效,DFT通常由FFT算法解决(快速傅立叶变换,它不是一个新的变换,它只是一个算法,以更有效的方式解决DFT)。
即使你不想实现FFT(这是有点难以理解,很难使其工作在形式的数据不是2^n
)或使用一些开源的代码,你可以使你实现有点快,例如看到2.0f * Math.PI * K / T
内循环之外是一个常数,因此可以计算一次为每个k(内循环外移动它),然后乘以你cos/sin
n
功能。
关于位置和解释,你已经改变了你的域,现在你的x轴,即表中数据的索引,对应的不是时间而是频率。你有44100Hz
的采样,你有2205
的采样,这意味着每1个采样代表频率等于44100Hz / 2205 = 20Hz
的输入信号的一个幅度。你的震级峰值在第7点(指数6),因为你的信号是120Hz,所以6 * 20Hz = 120Hz
是你可以预期的。
秒峰值似乎代表一些高频,但它只是一个伪信号,因为你的采样率是44100Hz
,你不能测量高于44100Hz / 2
的频率(奈奎斯特定律),如果你的截止点,之后的频率DFT数据是无效的。这就是为什么你的表的后半部分是无效的,它基本上是你的前半部分,但镜像,你可以忽略它。
编辑//从你的问题中我可以看出你对音频处理感兴趣,你可能想要谷歌NForge。Net库,这是一个很棒的音频和视觉处理的开源库,它的作者在codeproject.com上有很多关于它的许多特性的好文章。