2012-02-20 129 views
2

我目前使用JTransforms-library来计算44100Hz FS的一秒信号的DFT。该代码非常简单:JTransform的FFT与MATLAB相比的大小

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函数?

回答

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秒信号的每个512样本块计算1秒谱图。

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赫兹22050赫兹]。沿着时间轴(x轴)覆盖约1秒的86个样本。 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计算速度要快得多,并且可以计算出spectrun〜86x/s。如果FFT仍然不够快,则可以开始跳过块(例如,使用SIZE=512,但仅计算每个其他块,每1s信号给出〜43个频谱)。希望这是有道理的。

+0

它确实有效,但它需要永久完成工作。我不认为这是应该的。不过谢谢。 – gleerman 2012-02-20 21:25:55

+0

'永远'是什么意思?你可以发布更多的代码,以便我可以看到你在做什么?如果您将数据输入为真实数据并使用'fft.realForwardFull',则应该获得(大)速度优势。 – aganders3 2012-02-20 21:48:30

+0

我正在开发一个Android项目,我试图让FFT实时计算。这意味着,当下一秒记录时,计算并显示电流的FFT。这需要一分多钟。代码的其他部分用于过去的处理,但是日志显示它是上面的代码,它会一直占用。更具体地说,在fft计算中,GC似乎正在广泛运行,其中SIZE设置为44100(或22050)。 – gleerman 2012-02-21 11:09:53