与MATLAB相比,JTransform的FFT大小

时间:2012-02-20 20:44:09

标签: java matlab fft

我目前正在使用JTransforms-library来计算FS为44100 Hz的一秒信号的DFT。代码非常简单:

DoubleFFT_1D fft = new DoubleFFT_1D(SIZE);
fft.complexForward(signal);                 // signal: 44100 length array with audio bytes.

有关JTransform DoubleFFT_1D课程的文档,请参阅此页面。 http://incanter.org/docs/parallelcolt/api/edu/emory/mathcs/jtransforms/fft/DoubleFFT_1D.html

问题是:SIZE应该是什么?我知道它可能是窗口大小,但似乎无法使用我遇到的最常见的值,例如1024和2048.

目前我正在通过生成1kHz正弦波信号来测试此功能。但是,当我使用上面的代码并且我将结果与MATLAB的fft - 函数进行比较时,它们似乎是完全不同的。例如。 MATLAB给出0.0004 - 0.0922i之类的结果,而上面的代码产生类似-1.7785E-11 + 6.8533E-11i的结果,SIZE设置为2048.但是信号数组的内容相等。

SIZE的哪个值会产生与MATLAB的内置fft类似的FFT函数?

1 个答案:

答案 0 :(得分:3)

根据文档,SIZE看起来应该是signal中的样本数量。如果它真的是44.1 kHz的1 s信号,那么你应该使用SIZE = 44100。由于您使用的是复杂数据,signal应该是此大小的两倍(序列中的实/虚)。

如果您不使用SIZE = 44100,您的结果将与Matlab提供的结果不符。这是因为Matlab(可能还有JTransforms)根据输入的长度缩放fftifft函数的方式 - 不要担心幅度不匹配。默认情况下,Matlab使用完整信号计算FFT。您可以为fft(在Matlab中)提供第二个参数来计算N点FFT,它应该与您的JTransforms结果匹配。


根据您的评论,听起来您正在尝试创建spectrogram。为此,您必须在以下两者之间进行权衡:光谱分辨率,时间分辨率和计算时间。这是我的(Matlab)代码,用于1秒频谱图,针对1s信号的每个512样本块进行计算。

fs = 44100; % Hz
w = 1; % s

t = linspace(0, w, w*fs);
k = linspace(-fs/2, fs/2, w*fs);

% simulate the signal - time-dependent frequency
f = 10000*t; % Hz
x = cos(2*pi*f.*t);

m = 512; % SIZE
S = zeros(m, floor(w*fs/m));
for i = 0:(w*fs/m)-1
    s = x((i*m+1):((i+1)*m));
    S(:,i+1) = fftshift(fft(s));
end

Spectrogram created with 512-sample chunks
对于此图像,我们沿频率轴(y轴)有512个样本,范围为[-22050 Hz 22050 Hz]。沿时间轴(x轴)有86个样本覆盖约1秒。 Spectrogram created with 4096-sample chunks
对于此图像,我们现在沿频率轴(y轴)有4096个样本,范围为[-22050 Hz 22050 Hz]。时间轴(x轴)再次覆盖约1秒,但这次只有10个块。

快速时间分辨率(512个样本块)或高光谱分辨率(4096个样本块)是否更重要取决于您正在使用的信号类型。您必须根据时间/光谱分辨率以及在合理的计算时间内可以实现的目标来决定您想要的内容。例如,如果您使用SIZE = 4096,您将能够计算频谱~10x / s(基于您的采样率),但FFT可能不够快,无法跟上。如果使用SIZE = 512,光谱分辨率会较差,但FFT的计算速度会快得多,您可以计算出~86x / s的光谱。如果FFT仍然不够快,则可以开始跳过块(例如,使用SIZE=512但仅计算每个其他块,每1s信号给出~43个频谱)。希望这是有道理的。