Estou usando a Função de diferença de magnitude média para estimar a frequência fundamental de um sinal de áudio quase periódico. O AMDF é definido como
onde é o comprimento do sinal. Esta função exibe um mínimo quando o sinal é deslocado em uma quantidade igual ao seu período.
Este é o código que estou usando para extrair o pitch (no Matlab):
a = amdf(f);
a = a/max(a);
[p l] = findpeaks(-a, 'minpeakprominence', 0.6);
pitch = round(sample_freq/l(1);
No entanto, estou lidando com um sinal de áudio em que a frequência fundamental é muito baixa:
Como conseqüência, surge um problema de duplicação de afinação: o mínimo detectado corresponde à metade do período do sinal (ou seja, o segundo harmônico):
Tentei extrair o pico maior e não apenas o primeiro, mas às vezes esse problema permanece. Como posso melhorar meu código e / ou a função AMDF para lidar com problemas básicos?
fonte
Respostas:
É o que chamamos no negócio de detecção de pitch, o " problema da oitava ".
Primeiro de tudo, eu mudaria o AMDF para ASDF. E eu não reduziria o tamanho da janela à medida que o atraso aumenta. (Além disso, estou mudando a notação para o que considero mais convencional. " " é um sinal de tempo discreto.)x[n]
A função de diferença quadrática média (ASDF) de na vizinhança da amostra x [ n 0 ] é:x[n] x[n0]
é afunção e, se k for par, então ⌊ k⌊⋅⌋ k .⌊k2⌋=⌊k+12⌋=k2
floor()
Agora, expanda o quadrado e considere a aparência dos somatórios como (não que N esteja indo para o infinito, mas para lhe dar uma idéia se N for grande). O ASDF está diretamente relacionado à autocorrelação. É essencialmente a autocorrelação virada de cabeça para baixo. Estes passos eu deixarei para você. dê uma olhada nesta resposta.N→∞ N N
Então agora considere esta "autocorrelação" de comprimento finito (na vizinhança da amostra ) definida no ASDF:x[n0]
Onde
Desde e Q x [ k , n 0 ] ≥ 0 para todos os atrasos k , isso significa que R x [ k , n 0 ] ≤ R x [ 0 , n 0 ] para todos os atrasos k .Qx[0,n0]=0 Qx[k,n0]≥0 k Rx[k,n0]≤Rx[0,n0] k
Suponha por um minuto que seja periódico com o período P (e P seja um número inteiro), entãox[n] P P
e e R x [ m P ,Qx[mP,n0]=0 para qualquer número inteiro de períodos ( m é um inteiro). Então você obtém um pico em k = 0 e em k igual a qualquer outro múltiplo de P se xRx[mP,n0]=Rx[0,n0]≥Rx[k,n0] m k=0 k P é periódico. Se x [ n ] nãoforperfeitamente periódico, o que poderíamos esperar é o maior pico em k = 0 , outro pico (mas um pouco menor) em k = P (o período que estamos procurando) e picos progressivamente menores para múltiplos maiores de P .x[n] x[n] k=0 k=P P
Portanto, o problema da oitava ocorre devido a algumas razões. Primeiro de tudo, não é necessariamente um número inteiro. Esse é um problema de interpolação, não é grande coisa.P
A segunda razão e o problema mais difícil é o da sub-harmônica . Considere que você está ouvindo um belo tom periódico exatamente a A-440 Hz e soa como um A que está 9 semitons acima do meio C. Agora, suponha que alguém adicione ao som uma amplitude muito pequena (como 60 dB) A -220? Como será e matematicamente qual será o período "verdadeiro"?
Escolhendo o pico "certo" para o período.
Digamos que você execute sua anotação através de um filtro de bloqueio de DC, de modo que a média de seja zero. Acontece que faz com que a média da autocorrelação R x [ k , n 0 ] para cada n 0 também seja zero (ou próxima se N for grande). Isso significa que R x [ k , n 0 ] deve somar (acima de k ) cerca de zero, o que significa que há tanta área acima de zero quanto abaixo.x[n] Rx[k,n0] n0 N Rx[k,n0] k
Ok, então representa a potência de x [ n ] nas proximidades de n = n 0 e deve ser não negativo. R x [ k , n 0 ] nunca excede R x [ 0 , n 0 ], mas pode ficar tão grande quanto quando x [ n ] é periódico. R x [ P , n 0 ]Rx[0,n0] x[n] n=n0 Rx[k,n0] Rx[0,n0] x[n] se x [ nRx[P,n0]=Rx[0,n0] . Portanto, se x [ n ] é periódico com o período P e você tem um monte de picos espaçados por P e você tem uma idéia de quão altos devem ser esses picos. E se o componente DC de R x [ k , n 0 ] for zero, significa entre os picos, eledeveter valores negativos.x[n+P]=x[n] x[n] P P Rx[k,n0]
Se era "quase periódico", um ciclo de x [ n ] parecerá muito com um ciclo adjacente, mas não tanto quanto um ciclo de x [ n ] mais abaixo no sinal no tempo. Isso significa que o primeiro pico R x [ P , n 0 ] será maior que o segundo em R x [ 2 P , n 0 ] ou o terceiro R x [ 3 P , n 0 ]x[n] x[n] x[n] Rx[P,n0] Rx[2P,n0] Rx[3P,n0] . Pode-se usar a regra para sempre escolher o pico mais alto e esperar que o pico mais alto seja sempre o primeiro. Mas, por causa de sub-harmônicos inaudíveis, às vezes não é esse o caso. Às vezes, o segundo ou possivelmente o terceiro pico é um pouco mais alto. Além disso, como o período provavelmente não é um número inteiro de amostras, mas k em R x [ k , n 0 ] é sempre um número inteiro, portanto o pico verdadeiro provavelmente estará entre os valores inteiros de k . Mesmo se você interpolar onde está o pico suave (o que eu recomendo e a interpolação quadrática é boa o suficiente) e quão alto é realmente entre o número inteiro kP k Rx[k,n0] k k , seu alg de interpolação pode atingir um pico um pouco mais alto ou um pouco mais baixo do que realmente é. Portanto, escolher o pico absolutamente mais alto pode resultar na escolha espúria do segundo sobre o primeiro pico (ou vice-versa) quando você realmente queria o outro.
Então, de alguma forma, você precisa reduzir os picos ao aumentar para que o primeiro pico tenha uma pequena vantagem sobre o segundo, e o segundo sobre o quarto (a próxima oitava abaixo), etc. Como você faz isso?k
Para fazer isso, multiplicando com uma função decrescente de k de modo que o pico a k = 2 P é reduzido por algum factor, em relação a um pico idêntica em k = P . Acontece que a função de energia (não a exponencial) faz isso. então calculeRx[k,n0] k k=2P k=P
Portanto, se era perfeitamente periódico com o período P e ignorava problemas de interpolação para P não inteiro , entãox[n] P P
mas
O fator pelo qual o pico de um tom de uma oitava mais baixa é reduzido é a razão
Essa é a maneira consistente de ponderar, desenfatizar ou prejudicar o pico correspondente ao tom sub-harmônico uma oitava abaixo.
fonte
Heuristicamente, a frequência fundamental da fala sonora estará no intervalo [70, 400] Hz. Portanto, o primeiro passo seria aplicar um filtro passa-banda para isolar aproximadamente essa banda.
Em segundo lugar, você pode aplicar uma função de ponderação ao espectro de potência. Perto do fundamental, o peso deve estar próximo de 1, enquanto mais próximo ao final da banda, o peso deve estar próximo de 0. Esse peso é normalizado, é claro. Eu recomendaria algo super-linear: quadrático, quadrático, etc - para realmente matar as oitavas.
fonte