Как интерпретировать результат из функции KissFFT kiss_fftr (FFT для реального сигнала) - PullRequest
2 голосов
/ 02 ноября 2011

Я использую реальную функцию KissFFT для преобразования некоторых реальных аудиосигналов. Я в замешательстве, так как я ввожу реальный сигнал с nfft сэмплами, но в результате получаем nfft / 2 + 1 комплексные частотные бины.

от README KissFFT:

Реальный (т.е. не сложный) код оптимизации работает только для бфутов четной длины. Он выполняет два FFT половинной длины параллельно (упакованные в real & imag), а затем комбинирует их с помощью твида. Результатом являются nfft / 2 + 1 комплексные частотные элементы от DC до Найквиста.

Так что у меня нет конкретных знаний о том, как интерпретировать результат. Я предполагаю, что данные упакованы как r[0]i[0]r[1]i[1]...r[nfft/2]i[nfft/2], где r [0] будет постоянным током, i [0] - первый частотный блок, r [1] - второй, и так далее. Это тот случай?

Ответы [ 2 ]

4 голосов
/ 02 ноября 2011

Да. Причина, по которой kiss_fftr создает только двоичные элементы Nfft / 2 + 1, заключается в том, что ДПФ реального сигнала сопряженно-симметричен. Коэффициенты, соответствующие отрицательным частотам (-pi: 0 или pi: 2pi, в зависимости от того, что вам нравится думать об этом), являются сопряженными коэффициентами из [0: pi).

Обратите внимание, что выходные [0] и выходные [Nfft / 2] ячейки (DC и Nyquist) имеют ноль в мнимой части. Я видел, как некоторые библиотеки упаковывают эти две реальные части в первый комплекс, но я рассматриваю это как нарушение договора, которое приводит к трудным для диагностики, почти правильным ошибкам.

Совет: Если вы используете float для своего типа данных (по умолчанию), вы можете преобразовать выходной массив в float complex * (c99) или std :: complex * (c ++). Упаковка для структуры kiss_fft_cpx совместима. Причина, по которой он не использует их по умолчанию, заключается в том, что kiss_fft работает с другими типами, кроме float и double, и на старых компиляторах ANSI C, в которых отсутствуют эти функции.

Вот надуманный пример (предполагается, что компилятор c99 и тип == float)

float get_nth_bin_phase(const float * in, int nfft, int whichbin )
{
  kiss_fftr_cfg st = kiss_fftr_alloc(1024,0,0,0);
  float complex * out = malloc(sizeof(float complex)*(nfft/2+1));
  kiss_fftr(st,in,(kiss_fft_cpx*)out);

  whichbin %= nfft;
  if ( whichbin <= nfft/2 ) 
    ph = cargf(out[whichbin]);
  else
    ph = cargf( conjf( out[nfft-whichbin] ) );
  free(out);
  kiss_fft_free(st);
  return ph;
}
0 голосов
/ 02 ноября 2011

r [1] и i [1] результата fftr составляют комплексный вектор.Вместе они дают вам величину (sqrt суммы квадратов двух компонентов) и фазу (через atan2 ()) первого частотного бина.

...