Início > DSP, Programação > Fundamental Frequency Estimation Methods

Fundamental Frequency Estimation Methods

Oi Pessoal…

Eu escrevi algo bem superficial neste blog sobre Frequencia fundamental (F0), recebi alguns emails perguntando sobres os métodos utilizados para se estimar as frequencias dentro de arquivos de áudios, como aplicar estes métodos e quais deles possuem melhor desempenho!

Testei os seguintes métodos:

  • Transformada de Fourrier
  • Zero Crossing
  • Auto-correlação

Auto-Correlação como esperado possue o pior desempenho, aplicar correlação em um sinal de áudio para depois encontrar o maior valor dentro dos dados correlacionados toma muito tempo de processamento!

Transformada de Fourrier possue um desempenho melhor comparado ao método anterior, submeter o sinal a transformada de fourrier é uma boa alternativa  para encontrar frequencias diversas dentro de arquivos de áudios.

Zero Crossing o grande campeão chega a ser quinze (15) vezes mais rápido do que a auto-correlação e pensando friamente é muito mais fácil e rápido encontrar quais são os pontos de variações dentro do sinal, sem submeter o sinal a fourrier.

Tela dos testes:

Source:

from __future__ import division
from numpy.fft import rfft
from numpy import argmax, mean, diff, log, fromstring
from matplotlib.mlab import find
from scipy.signal import fftconvolve, kaiser
from time import time
import sys
import wave

def parabola(data,x):

v1=1/2*(data[x-1]-data[x+1])/(data[x-1]-2*data[x]+data[x+1])+x
v2=data[x]-1/4*(data[x-1]-data[x+1])*(v1 – x)
return (v1, v2)

def Fundamental_Frequency_zero_crossing(signal, fs):

values = find((signal[1:] >= 0) & (signal[:-1] < 0))
crossingValues = [i – signal[i] / (signal[i+1] – signal[i]) for i in values]
return fs / mean(diff(crossingValues))

def Fundamental_Frequency_fft(signal, fs):

janela = signal * kaiser(len(signal),100)
f = rfft(janela)
i = argmax(abs(f))
real = parabola(log(abs(f)), i)[0]
return fs * real / len(janela)

def Fundamental_Frequency_autocorrelation(signal, fs):

correlacao = fftconvolve(signal, signal[::-1], mode=’full’)
correlacao = correlacao[len(correlacao)/2:]
d = diff(correlacao)
inicio = find(d > 0)[0]
pico = argmax(correlacao[inicio:]) + inicio
picox, picoy = parabola(correlacao, pico)
return fs / picox

filename = sys.argv[1]
spf = wave.open(filename,’r’)
signal = spf.readframes(-1)
signal = fromstring(signal, ‘Int16’)
fs = spf.getframerate()
print ‘\n ** Arquivo Aberto ** “%s”\n’ % filename
print ‘Calculando a Frequencia por FFT:’,
start_time = time()
print ‘%f Hz’   % Fundamental_Frequency_fft(signal, fs)
print ‘Tempo: %.3f s\n’ % (time() – start_time)
print ‘Calculando a Frequencia por zero crossing:’,
start_time = time()
print ‘%f Hz’ % Fundamental_Frequency_zero_crossing(signal, fs)
print ‘Tempo: %.3f s\n’ % (time() – start_time)
print ‘Calculando a Frequencia por autocorrelação:’,
start_time = time()
print ‘%f Hz’ % Fundamental_Frequency_autocorrelation(signal, fs)
print ‘Tempo: %.3f s\n’ % (time() – start_time)

Até

Eng Eder de Souza

Categorias:DSP, Programação Tags:,
  1. agosto 2, 2011 às 5:36 pm

    Muito interessante esse tópico!! gostei! eu queria tirar uma dúvida… eu fiz um software de reconhecimento de fala usando uma API da Microsoft para o PT-BR que não foi liberada publicamente, dava uns errinhos mas funcionava legal🙂
    Agora será que usando esse método em ligações de reconhecimento de fala na URA iria bem? hehehe

    • ederwander
      agosto 2, 2011 às 7:06 pm

      Olá Caio a resposta é Não, a frequencia fundamental varia muito e não é recomendada para reconhecimentos de fala, uma boa pedida para reconhecimento de palavras isoladas é o Dinamic Time Warping, desenvolvi alguns algoritmos para este fim e funciona bem…

      Eng Eder de Souza

  2. Lucas
    agosto 26, 2011 às 5:14 pm

    Obrigado!!!!

  3. Juliana
    setembro 19, 2011 às 1:46 pm

    Oi Eder. Eu estou pensando em fazer um software onde eu preciso reconhecer a frequência, atribuí-la a uma nota/figura musical e calcular seu tempo de execução. Nesse caso, você saberia me dizer qual desses métodos melhor se aplica? Obrigada. Juliana.

    • ederwander
      setembro 19, 2011 às 3:03 pm

      Oi Juliana,

      A auto-correlação ou FFT possue bons resultados para identificar frequencias, tome cuidado se estiver trabalhando com detecção de frequencias em instrumentos, estes métodos podem não trabalhar bem com ondas complexas, procure por cepstrum para estes casos.

      Outro ponto importante é como você ira trabalhar os dados de origem se será em realtime ou arquivos gravados… Alguns métodos se tornam inviáveis por tomar muito processamento.

      De uma olhada neste meu post “https://ederwander.wordpress.com/2011/09/09/experimental-guitar-tuner/” nele utilizo o método AMDF em meus testes consegui bons resultados, no final do post tem o link onde você pode ver o source inclusive nele está implementado como converter uma frequencia em Nota🙂;

      Eng Eder de Souza

  1. No trackbacks yet.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: