Criando um espectrograma

10

Eu tenho tentado elaborar a lógica para esta tarefa e planejo usar o pacote de origem KissFFT para executar a transformação rápida de fourier. Informe-me se isso parecer correto:

  1. Aloque uma estrutura FFT, ie. kiss_fft_alloc(N,0,NULL,NULL) Onde Nestá o tamanho da janela que estou usando. O buffer de entrada será uma matriz de Nelementos do tipo kiss_fft_scalar. O buffer de saída será uma matriz de N/2 + 1elementos do tipo kiss_fft_cpx.
  2. Decodifique N(tamanho da janela) o número de amostras PCM.
  3. Para cada amostra PCM, calcule a média da amplitude de cada canal (amostras não assinadas) e a escala de 0 a 2 (divida por 65536,0), armazenando o resultado no buffer de entrada.
  4. Execute a janela (ou seja, Hanning) no buffer de entrada.
  5. Execute uma transformação rápida de Fourier no buffer de entrada, armazenando no buffer de saída. Desde que eu estou usando valores reais como entrada, eu posso usar kiss_fftr().
  6. Para os N/2valores de saída, obtenha a magnitude ao quadrado dos dados transformados e converta os valores na escala de dB com a seguinte fórmula: 10 * log10 (re * re + im * im)
  7. Plote os N/2valores da etapa 6.
  8. Descarte a primeira metade do buffer de entrada, decodificando as próximas amostras de PCM (tamanho da janela / 2) e realizando a escala e a janelagem dos dados. Isso deve deslizar efetivamente a janela de entrada e evitar a necessidade de refazer a matemática nas amostras processadas de PCM.
  9. Passe para a etapa 5, repetindo essas etapas até que todas as amostras sejam processadas.
  10. Libere a memória usada de kiss_fft_alloc().

Foi sugerido que eu subtraísse um valor da janela de entrada antes de executar a FFT, para que o valor DC resultante tenha uma magnitude zero. Devo subtrair a média ou a média dos dados de entrada?

Além disso, quais são as coisas que preciso considerar ao escolher o tamanho da janela? Além disso, ele deve ser um número par, de acordo com as instruções do KissFFT, existe um benefício em usar um tamanho de janela pequeno, ou seja. fornecerá um gráfico melhor? Presumo que um tamanho de janela grande reduz o número de FFTs que devem ser executadas; esse é o único benefício em usar um tamanho de janela grande?

Por fim, quando chego ao ponto em que os dados estão prontos para plotar, como faço para plotá-los? Quando eu trabalhei em alguma lógica gráfica de forma de onda no passado, apenas plotei 3 valores para cada pixel ao longo do eixo (amplitude mínima, amplitude máxima, amplitude RMS), mas não sei o que devo fazer com dados do espectrograma.x

Agradecemos antecipadamente por toda e qualquer orientação que você possa fornecer.

raynebc
fonte

Respostas:

8

Parece muito bom para mim. No passo 3, porém, você realmente deseja escalar o sinal de -1 a 1, caso contrário, você está adicionando DC. Você mencionou subtrair a média - eu não recomendaria fazer isso para um espectrograma, já que isso efetivamente filtra a DC, que o espectrograma deve mostrar se estiver lá.

Escolher um tamanho de janela tem tudo a ver com compensações. Uma janela maior fornecerá uma resolução de frequência mais nítida, mas com uma resolução de tempo mais desfocada. Uma janela mais curta dará o oposto: resolução de tempo mais nítida, mas resolução de frequência mais desfocada. A escolha apropriada do tamanho da janela dependerá dos dados que você está tentando analisar. Normalmente, será uma potência de 2 apenas porque as FFTs tendem a gostar de potências de 2. Uma regra prática decente é que sua janela deve ter pelo menos aproximadamente o dobro do tempo que o período da frequência mais baixa que você gostaria de poder com precisão resolver.

Você pode se perguntar se é possível lidar melhor com essa troca, e existem técnicas para isso: elas geralmente envolvem espectrogramas de computação com vários tamanhos de FFT diferentes ao mesmo tempo e combinam-nos. Há boas informações visuais nesta página da Web: http://www.izotope.com/tech/aes_adapt/

Se o tamanho da sua janela for muito pequeno, duas frequências muito próximas podem ser indistinguíveis uma da outra, pois ambas terminam no mesmo compartimento da FFT. Se o tamanho da sua janela for muito grande, dois eventos próximos no tempo podem ser combinados ou um transitório agudo pode se transformar em um ataque gradual. Confira a página que publiquei para algumas maneiras de visualizar isso.

Um tamanho de janela maior não reduz necessariamente o número de FFTs. Você optou por calcular um espectrograma usando uma transformada de Fourier de curta duração, onde há uma sobreposição de metade do tamanho da FFT. Você poderia usar um fator de sobreposição mais alto, se quisesse. A escolha do tamanho de uma janela é muito mais uma questão de compensar o tempo / frequência do que quantas FFTs você precisa calcular. Ao projetar um espectrograma (ou qualquer STFT), você pode escolher o tamanho da janela e o tamanho do salto , a distância entre os blocos, como parâmetros independentes.

Quando você o desenha, o tempo normalmente está no eixo x, a frequência está no eixo y (geralmente uma escala logarítmica, escala Mel, etc., em vez de uma escala linear) e, em seguida, as magnitudes são representadas com a intensidade da cor, ou seja, cores muito escuras correspondem a pequenas magnitudes e cores muito brilhantes correspondem a grandes magnitudes.

schnarf
fonte
Seu link parece estar morto. Você poderia atualizá-lo?
Daniel Wolf