JTransform 的 FFT 大小与 MATLAB 相比

发布于 2025-01-07 01:36:06 字数 895 浏览 2 评论 0原文

我目前正在使用 JTransforms 库来计算 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 函数?

I'm currently using the JTransforms-library to calculate the DFT of a one-second signal at a FS of 44100 Hz. The code is quite simple:

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

See this page for the documentation of JTransform's DoubleFFT_1D class.
http://incanter.org/docs/parallelcolt/api/edu/emory/mathcs/jtransforms/fft/DoubleFFT_1D.html

The question is: what is SIZE supposed to be? I know it's probably the window size, but can't seem to get it to work with the most common values I've come across, such as 1024 and 2048.

At the moment I'm testing this function by generating a signal of a 1kHz sinusoid. However, when I use the code above and I'm comparing the results with MATLAB's fft-function, they seem to be from a whole different magnitude. E.g. MATLAB gives results such as 0.0004 - 0.0922i, whereas the above code results in results like -1.7785E-11 + 6.8533E-11i, with SIZE set to 2048. The contents of the signal-array are equal however.

Which value for SIZE would give a similar FFT-function as MATLAB's built-in fft?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深白境迁sunset 2025-01-14 01:36:06

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

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


从您的评论来看,您似乎正在尝试创建频谱图。为此,您必须权衡以下因素:光谱分辨率、时间分辨率和计算时间。这是我的 1 秒频谱图(Matlab)代码,针对 1 秒信号的每个 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

使用 512 个样本块创建的频谱图
对于此图像,我们沿频率轴(y 轴)有 512 个样本,范围从 [-22050 Hz 22050 Hz]。沿时间轴(x 轴)有 86 个样本,覆盖约 1 秒。
使用 4096 个样本块创建的频谱图
对于此图像,我们现在沿频率轴(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 个频谱)。希望这是有道理的。

According to the documentation, SIZE looks like it should be the number of samples in signal. If it's truly a 1 s signal at 44.1 kHz, then you should use SIZE = 44100. Since you're using complex data, signal should be an array twice this size (real/imaginary in sequence).

If you don't use SIZE = 44100, your results will not match what Matlab gives you. This is because of the way Matlab (and probably JTransforms) scales the fft and ifft functions based on the length of the input - don't worry that the amplitudes don't match. By default, Matlab calculates the FFT using the full signal. You can provide a second argument to fft (in Matlab) to calculate the N-point FFT and it should match your JTransforms result.


From your comments, it sounds like you're trying to create a spectrogram. For this, you will have to figure out your tradeoff between: spectral resolution, temporal resolution, and computation time. Here is my (Matlab) code for a 1-second spectrogram, calculated for each 512-sample chunk of a 1s signal.

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
For this image we have 512 samples along the frequency axis (y-axis), ranging from [-22050 Hz 22050 Hz]. There are 86 samples along the time axis (x-axis) covering about 1 second.
Spectrogram created with 4096-sample chunks
For this image we now have 4096 samples along the frequency axis (y-axis), ranging from [-22050 Hz 22050 Hz]. The time axis (x-axis) again covers about 1 second, but this time with only 10 chunks.

Whether it's more important to have fast time resolution (512-sample chunks) or high spectral resolution (4096-sample chunks) will depend on what kind of signal you're working with. You have to make a decision about what you want in terms of temporal/spectral resolution, and what you can achieve in reasonable computation time. If you use SIZE = 4096, for example, you will be able to calculate the spectrum ~10x/s (based on your sampling rate) but the FFT may not be fast enough to keep up. If you use SIZE = 512 you will have poorer spectral resolution, but the FFT will calculate much faster and you can calculate the spectrun ~86x/s. If the FFT is still not fast enough, you could then start skipping chunks (e.g. use SIZE=512 but only calculate for every other chunk, giving ~43 spectrums per 1s signal). Hopefully this makes sense.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文