Como obtenho as frequências de cada valor em uma FFT?

148

Eu tenho um resultado FFT. Eles são armazenados em duas doublematrizes: uma matriz de peças real e uma matriz de peças imaginárias. Como determino as frequências que correspondem a cada elemento nessas matrizes?

Em outras palavras, eu gostaria de criar uma matriz que armazene as frequências para cada componente real e imaginário da minha FFT.

Rango
fonte
Eu faço isso em c # .net. Pode me ajudar?
Rango
9
Se você não entender a relevância das partes reais e imaginárias de uma FFT, não obterá resultados significativos; portanto, você deve procurar alguns tutoriais de processamento de sinais e FFT para entender como interpretar os resultados. Eu acho que é bem provável que, para onde quer que você esteja usando, esteja querendo a magnitude da FFT ou da densidade espectral de potência.
the_mandrill
Obrigado! Eu quero ficar frequências de pico de cada frame (tamanho do quadro depende em comprimento da janela e Desvio Comprimento)
Rango

Respostas:

350

O primeiro compartimento na FFT é CC (0 Hz), o segundo compartimento é Fs / N, onde Fsestá a taxa de amostragem e No tamanho da FFT. O próximo compartimento é 2 * Fs / N. Para expressar isso em termos gerais, o enésimo bin é n * Fs / N.

Portanto, se sua taxa de amostragem Fsé de 44,1 kHz e seu tamanho de FFT Né 1024, os compartimentos de saída de FFT estão em:

  0:   0 * 44100 / 1024 =     0.0 Hz
  1:   1 * 44100 / 1024 =    43.1 Hz
  2:   2 * 44100 / 1024 =    86.1 Hz
  3:   3 * 44100 / 1024 =   129.2 Hz
  4: ...
  5: ...
     ...
511: 511 * 44100 / 1024 = 22006.9 Hz

Observe que, para um sinal de entrada real (partes imaginárias são zero), a segunda metade da FFT (posições de N / 2 + 1a N - 1) não contém informações adicionais úteis (elas possuem simetria conjugada complexa com as primeiras N / 2 - 1posições). O último compartimento útil (para aplicações práticas) está em N / 2 - 1, o que corresponde a 22006,9 Hz no exemplo acima. O compartimento at N / 2representa energia na frequência Nyquist, ou seja Fs / 2(= 22050 Hz neste exemplo), mas isso geralmente não é de uso prático, pois os filtros anti-aliasing normalmente atenuam quaisquer sinais acima e abaixo Fs / 2.

Paul R
fonte
8
Nota - a resposta está um pouco errada - o 512º intervalo contém o nível de 22050, o limite de nyquist. Os compartimentos de 0 a N / 2, inclusive, contêm valores úteis.
David van brink
4
Obrigado pela edição e esclarecimento ... Acho que é aqui que revelo alguma falta de praticidade. Eu: Mas mestre, FFT trabalha até o nyquist! Você: Padawan, você realmente deve filtrar isso.
David van brink
5
Eu gostaria de poder estrelar respostas. Esta resposta é ainda melhor do que a pergunta original!
Skylion
14
@PaulR - Queria agradecer por esta maravilhosa resposta que me serviu ao longo dos anos. Eu visitava essa resposta antes de ter uma conta no StackOverflow e esqueci de agradecer uma vez que me inscrevi. Recentemente, eu estava analisando as coisas da FFT e lembrei-me da sua resposta e a visitei agora. Quando cheguei aqui, lembrei-me de agradecer ... então, obrigado! Sempre que tenho um debate com alguém sobre como interpretar qual é o ponto de cada um dos eixos horizontais da FFT, aponto para esse link.
rayryeng
6
@rayryeng: muito obrigado - acho que esse foi o reconhecimento mais legal que já tive em ~ 5 anos de responder perguntas aqui no SO!
Paul R
55

Dê uma olhada na minha resposta aqui .

Resposta para comentar:

Na verdade, a FFT calcula a correlação cruzada do sinal de entrada com as funções seno e cosseno (funções básicas) em uma faixa de frequências igualmente espaçadas. Para uma determinada saída FFT, existe uma frequência correspondente (F), conforme a resposta que eu publiquei. A parte real da amostra de saída é a correlação cruzada do sinal de entrada cos(2*pi*F*t)e a parte imaginária é a correlação cruzada do sinal de entrada com sin(2*pi*F*t). A razão pela qual o sinal de entrada está correlacionado sine cosfunciona é considerar as diferenças de fase entre o sinal de entrada e as funções básicas.

Tomando a magnitude da saída FFT complexa, você obtém uma medida de quão bem o sinal de entrada se correlaciona com os sinusóides em um conjunto de frequências, independentemente da fase do sinal de entrada. Se você está apenas analisando o conteúdo de frequência de um sinal, quase sempre terá a magnitude ou magnitude ao quadrado da saída complexa da FFT.

Jason B
fonte
A parte real e imaginária é o resultado da FFT usado para? Por favor, explique para mim. Obrigado
Rango
5
essa resposta merece mais amor.
bright-star
1
Será que a magnitude das saídas complexas deve ser dobrada cada uma? (se eu restringir minha interpretação para a metade inferior)
Lobo
18

Eu usei o seguinte:

public static double Index2Freq(int i, double samples, int nFFT) {
  return (double) i * (samples / nFFT / 2.);
}

public static int Freq2Index(double freq, double samples, int nFFT) {
  return (int) (freq / (samples / nFFT / 2.0));
}

As entradas são:

  • i: Bin para acessar
  • samples: Taxa de amostragem em Hertz (ou seja, 8000 Hz, 44100Hz, etc.)
  • nFFT: Tamanho do vetor FFT
roberto
fonte
7
As pessoas não podem saber exatamente o que você representa com samplesou nFFT. Então, por favor, torne-o mais explicativo.
mostar
14
A resposta aceita diz que deveria ser i * samples / nFFT. Por que o extra está 2aí? Estou esquecendo de algo?
yati sagade
13

Os coeficientes de saída da FFT (para entrada complexa de tamanho N) são de 0 a N-1 agrupados como frequência [LOW, MID, HI, HI, MID, LOW].

Eu consideraria que o elemento em k tem a mesma frequência que o elemento em Nk, pois para dados reais, FFT [Nk] = conjugado complexo de FFT [k].

A ordem de varredura da frequência BAIXA para ALTA é

0,

 1,
 N-1,

 2,
 N-2

 ...

 [N/2] - 1,
 N - ([N/2] - 1) = [N/2]+1,

 [N/2]

Existem [N / 2] +1 grupos de frequência do índice i = 0 a [N / 2], cada um com o frequency = i * SamplingFrequency / N

Portanto, a frequência no compartimento FFT [k] é:

if k <= [N/2] then k * SamplingFrequency / N
if k >= [N/2] then (N-k) * SamplingFrequency / N
robert.b
fonte
5

Seu k th frequência do resultado FFT é 2 * pi * k / N.

Neo
fonte
6
Eu acho que isso vai ser em radianos
Barnaby