Размер в БПФ JTransform по сравнению с MATLAB - PullRequest
2 голосов
/ 21 февраля 2012

В настоящее время я использую библиотеку JTransforms для вычисления ДПФ односекундного сигнала при частоте FS 44100 Гц.Код довольно прост:

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.

В данный момент я тестирую эту функциюпутем генерации сигнала синусоиды 1 кГц.Однако когда я использую приведенный выше код и сравниваю результаты с fft -функцией MATLAB, они, похоже, имеют совершенно другую величину.Например, MATLAB дает результаты, такие как 0.0004 - 0.0922i, тогда как приведенный выше код приводит к результатам, подобным -1.7785E-11 + 6.8533E-11i, с SIZE, установленным на 2048. Однако содержимое массива сигналов равно.* даст такую ​​же FFT-функцию, как встроенная в MATLAB fft?

1 Ответ

3 голосов
/ 21 февраля 2012

Согласно документации, SIZE выглядит так, как должно быть количество образцов в signal. Если это действительно сигнал 1 с на частоте 44,1 кГц, то вам следует использовать SIZE = 44100. Поскольку вы используете сложные данные, signal должен быть массивом, в два раза превышающим этот размер (действительный / мнимый в последовательности).

Если вы не используете SIZE = 44100, ваши результаты не будут соответствовать тому, что дает вам Matlab. Это связано с тем, что Matlab (и, вероятно, JTransforms) масштабирует функции fft и ifft в зависимости от длины входного сигнала - не беспокойтесь, что амплитуды не совпадают. По умолчанию Matlab рассчитывает БПФ, используя полный сигнал. Вы можете предоставить второй аргумент fft (в Matlab) для вычисления N-точечного БПФ, и он должен соответствовать вашему результату JTransforms.


Судя по вашим комментариям, вы пытаетесь создать спектрограмму . Для этого вам нужно будет найти компромисс между: спектральным разрешением, временным разрешением и временем вычисления. Вот мой (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
Для этого изображения у нас есть 512 выборок вдоль оси частот (ось Y), в диапазоне от [-22050 Гц и 22050 Гц]. Есть 86 образцов вдоль оси времени (ось X), охватывающей около 1 секунды. Spectrogram created with 4096-sample chunks
Для этого изображения теперь у нас есть 4096 выборок вдоль оси частот (ось Y) в диапазоне от [-22050 Гц до 22050 Гц]. Ось времени (ось X) снова охватывает около 1 секунды, но на этот раз только 10 фрагментов.

Будет ли более важно иметь быстрое временное разрешение (фрагменты с 512 выборками) или высокое спектральное разрешение (фрагменты с 4096 выборками), будет зависеть от того, с каким типом сигнала вы работаете. Вы должны принять решение о том, что вы хотите с точки зрения временного / спектрального разрешения, и что вы можете достичь за разумное время вычислений. Например, если вы используете SIZE = 4096, вы сможете рассчитать спектр ~ 10x / с (на основе вашей частоты дискретизации), но БПФ может быть недостаточно быстрым, чтобы не отставать. Если вы используете SIZE = 512, у вас будет худшее спектральное разрешение, но БПФ будет вычисляться намного быстрее, и вы можете рассчитать спектр ~ 86x / с. Если БПФ все еще недостаточно быстр, вы можете начать пропускать фрагменты (например, использовать SIZE=512, но рассчитывать только для каждого другого фрагмента, давая ~ 43 спектра на сигнал 1 с). Надеюсь, это имеет смысл.

...