Suponha o seguinte:
- A frequência fundamental de um sinal foi estimada usando FFT e alguns métodos de estimativa de frequência e fica entre dois centros de bin
- A frequência de amostragem é fixa
- Esforço computacional não é um problema
Conhecendo a frequência, qual é a maneira mais precisa de estimar o valor de pico correspondente dos sinais fundamentais?
Uma maneira pode ser zerar o sinal de tempo para aumentar a resolução da FFT, de modo que o centro da bandeja esteja mais próximo da frequência estimada. Nesse cenário, um ponto sobre o qual não tenho certeza é se consigo zerar tanto quanto quero ou se há algumas desvantagens em fazê-lo. Outro é o centro de posição em que eu devo selecionar após o preenchimento zero como o de onde estou obtendo o valor de pico (porque não é possível atingir exatamente a frequência de interesse, mesmo após o preenchimento zero).
No entanto, também estou me perguntando se existe outro método que possa fornecer melhores resultados, por exemplo, um estimador que use os valores de pico dos dois centros de caixa ao redor para estimar o valor de pico na frequência de interesse.
imax
está o pico da FFT) fornecerá resultados precisosRespostas:
O primeiro algoritmo que vem à mente é o algoritmo de Goertzel . Esse algoritmo geralmente assume que a frequência de interesse é um múltiplo inteiro da frequência fundamental. No entanto, este artigo aplica o algoritmo (generalizado) ao caso em que você está interessado.
Outro problema é que o modelo de sinal está incorreto. Ele usa
2*%pi*(1:siglen)*(Fc/siglen)
. Deve ser usado2*%pi*(0:siglen-1)*(Fc/siglen)
para que a fase saia corretamente.Eu também acho que há um problema com a frequência
Fc=21.3
muito baixa. Sinais com valor real de baixa frequência tendem a exibir viés quando se trata de problemas de estimativa de fase / frequência.Eu também tentei uma pesquisa de grade grossa para a estimativa de fase, e ela fornece a mesma resposta que o algoritmo de Goertzel.
Abaixo está um gráfico que mostra o viés nas duas estimativas (Goertzel: azul, Grosso: vermelho) para duas frequências diferentes:
Fc=21.3
(sólida) eFc=210.3
(tracejada). Como você pode ver, o viés para a frequência mais alta é muito menor.O gráfico eixo é a fase inicial que muda de 0 para 2 π .x 2π
fonte
Se você estiver disposto a usar vários compartimentos FFT vizinhos, não apenas 2, a interpolação Sinc com janela entre os resultados complexos da bandeja pode produzir uma estimativa muito precisa, dependendo da largura da janela.
A interpolação Windinc Sinc é comumente encontrada em amplificadores de áudio de alta qualidade, portanto, os trabalhos sobre esse assunto terão fórmulas de interpolação adequadas com a análise de erros.
fonte
[1] JL Flanagan e RM Golden, "Phase vocoder", Bell Systems Technical Journal, vol. 45, pp. 1493–1509, 1966.
[2] K. Dressler, “Extração sinusoidal usando uma implementação eficiente de uma FFT de alta resolução”, no Proc. 9ª Int. Conf. sobre efeitos de áudio digital (DAFx-06), Montreal, Canadá, setembro de 2006, pp. 247–252.
fonte
Um método é encontrar o máximo e ajustar uma parábola a respeito e, em seguida, usar o máximo da parábola como estimativa de frequência e magnitude. Você pode ler tudo aqui: https://ccrma.stanford.edu/~jos/sasp/Sinusoidal_Peak_Interpolation.html
fonte
Eu tive muita dificuldade com esse problema exato alguns anos atrás.
Eu postei esta pergunta:
/programming/4633203/extracting-precise-frequencies-from-fft-bins-using-phase-change-between-frames
Acabei fazendo os cálculos do zero e postei uma resposta para minha própria pergunta.
Estou surpreso por não ter encontrado nenhuma exposição semelhante na Internet.
Vou postar a resposta novamente aqui; observe que o código foi projetado para um cenário em que estou sobrepondo minha janela FFT em 4x.
π
Este quebra-cabeça leva duas chaves para desbloqueá-lo.
A primeira chave é entender como a sobreposição da janela da FFT introduz uma rotação na fase do compartimento.
A segunda chave vem do Gráfico 3.3 e 3.4 aqui (obrigado a Stephan Bernsee pela permissão para copiar as fotos aqui).
Gráfico 3.3:
Gráfico 3.4:
Código:
fonte
Este código python fornecerá um resultado muito preciso (usei-o para muitas notas musicais e obtive erros inferiores a 0,01% do semitom) com interpolação parabólica (método usado com sucesso por McAulay Quatieri, Serra, etc. em harmônico + residual técnicas de separação)
fonte
As frequências com as quais você está lidando (21,3Hz amostrados em 8kHz) são muito baixas. Por serem sinais de valor real, exibirão um viés na estimativa de fase para ** qualquer ** frequência.
Esta imagem mostra um gráfico do viés (
phase_est - phase_orig
) paraFc = 210.3;
(em vermelho) versus o viés paraFc = 21.3;
. Como você pode ver, o deslocamento é muito mais significativo para o21.3
caso.Outra opção é reduzir sua taxa de amostragem. A curva verde mostra o viés para
Fs = 800
vez de8000
.fonte
goertzel = atan(imag(y(2)),real(y(2)))*180/%pi + 90;
. :-) Vai cavar um pouco mais. Assista esse espaço.p
porp2 = (abs(y(3)) - abs(y(1)))/(2*(2*abs(y(2)) - abs(y(3)) - abs(y(1)))); phase2 = y0 - 0.25*(ym1-yp1)*p2;
, obterá MUITAS melhores respostas - mesmo paraFc=210
. Não tenho certeza de que a versão atual dop
lhe dará algo sensato. A fórmula de interpolação é para interpolação da AMPLITUDE de uma parábola, masp
está interpolando a fase que é ... estranha.p = (yp1 - ym1)/(2*(2*y0 - yp1 - ym1))
correto , EXCETO que a localização do pico ( ) estará incorreta algumas vezes se você estiver usando PHASES em vez de amplitudes. Isso ocorre porque as fases podem pular em torno do limite de +/- 180 graus. Tudo o que é necessário para corrigi-lo para a fase é alterar essa linha para o meup2
cálculo acima.