Eu criei um algoritmo de detecção de afinação usando HPS e estou enfrentando um problema. Eu sou iniciante no processamento de sinais e este site me ajudou antes, então eu deveria perguntar.
Para arremessos mais altos ( eg. >C6:1046.50hz
), estou começando a obter dados de lixo do HPS. Quanto mais alto o tom, mais lixo fico (com lixo, quero dizer frequências que não são erros de oitava nem harmônicos e estão em torno de 1Hz a 20Hz)
O que eu observei empírico:
os resultados são piores para agudos mais altos, se o fundamental estiver acima da A6 ou mais, recebo apenas dados de lixo.
o FFT funciona bem mesmo para um tom muito alto (com o mínimo, quero dizer que seu pico mostra o fundamental ou um de seus harmônicos, mas não o lixo)
se eu diminuir o número de harmônicos que considero para o HPS, o lixo diminui, mas isso dificulta a discriminação entre o fundamental e o harmônico.
Aqui está o meu algoritmo:
->raw buffer -> hann window, 16384 samples, 50% overlap -> zero padding -> FFT -> HPS
Qualquer ajuda é apreciada!
ATUALIZAÇÃO 1: Então, quero acrescentar mais algumas coisas:
- A taxa de amostragem em que estou gravando é de 44100 Hz
- Observei que esse comportamento é pouco visível em um violão, mas muito visível em um piano digital (para a mesma nota tocada)
Aqui está o meu algoritmo hps, talvez alguém com maior experiência possa detectar um problema.
int hps(float* spectrum, int spectrumSize, int harmonics) { int i, j, maxSearchIndex, maxBin; maxSearchIndex = spectrumSize/harmonics; maxBin = 1; for (j=1; j<=maxSearchIndex; j++) { for (i=1; i<=harmonics; i++) { spectrum[j] *= spectrum[j*i]; } if (spectrum[j] > spectrum[maxBin]) { maxBin = j; } } // Fixing octave too high errors int correctMaxBin = 1; int maxsearch = maxBin * 3 / 4; for (i=2; i<maxsearch; i++) { if (spectrum[i] > spectrum[correctMaxBin]) { correctMaxBin = i; } } if (abs(correctMaxBin * 2 - maxBin) < 4) { if (spectrum[correctMaxBin]/spectrum[maxBin] > 0.2) { maxBin = correctMaxBin; } } return maxBin; }