gleerman
gleerman

Reputation: 1813

Size in JTransform's FFT compared to MATLAB

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?

Upvotes: 2

Views: 1932

Answers (1)

aganders3
aganders3

Reputation: 5955

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.

Upvotes: 4

Related Questions