2009-08-30 7 views
1

Désolé de poser une question similaire à celle que j'ai déjà posée (FFT Problem (Returns random results)), mais j'ai recherché la détection de hauteur et l'autocorrélation et j'ai trouvé du code pour le pitch détection utilisant l'autocorrélation. J'essaie de faire la détection de hauteur d'un utilisateur chantant. Le problème est, il continue de retourner des résultats aléatoires. J'ai un code de http://code.google.com/p/yaalp/ que j'ai converti en C++ et modifié (ci-dessous). Mon taux d'échantillonnage est de 2048 et la taille des données est de 1024. Je détecte la hauteur d'une onde sinusoïdale et d'une entrée micro. La fréquence de l'onde sinusoïdale est 726.0, et sa détection à 722.950820 (qui im ​​ok avec), mais sa détection de la hauteur du micro comme un nombre aléatoire d'environ 100 à environ 1050.L'autocorrélation renvoie des résultats aléatoires avec une entrée micro (en utilisant un filtre passe-haut)

Je suis maintenant en utilisant un filtre passe-haut pour supprimer le décalage DC, mais cela ne fonctionne pas. Est-ce que je le fais bien, et si oui, que puis-je faire pour le réparer? Toute aide serait grandement appréciée!

(fixe)

Merci,

Niall. Edit: Changement du code pour implémenter un filtre passe-haut avec une coupure de 30hz (à partir de What Are High-Pass and Low-Pass Filters?, quelqu'un peut-il me dire comment convertir le filtre passe-bas en convolution en un passe-haut?) Mais il revient toujours résultats aléatoires. Le brancher sur un hôte VST et utiliser des plugins VST pour comparer les spectres n'est malheureusement pas une option pour moi. Edit: Correction, merci pour l'aide de tout le monde, mais je ne l'ai jamais eu à travailler, maintenant en utilisant le nouveau code.

+1

BTW: Votre gestion de la mémoire devrait être améliorée car vous ne désaffectez jamais la mémoire que vous avez allouée mais je suis sûr que vous savez et que vous voulez d'abord que l'algorithme fonctionne. Mais tu ne devrais pas oublier ça! – mmmmmmmm

+3

Pourquoi est-ce marqué C++? Ce code n'est vraiment pas C++. – GManNickG

+0

Pas une seule ligne C++, mais Niall aime ça. – gimpf

Répondre

0

Je ne vois pas le problème dans votre code, mais je ne suis pas bon en C. Mais je vais essayer ce qui suit pour trouver le problème:

  • terme avec des données où le résultat connue en , par exemple avec sin (x) en tant qu'entrée
  • initiée avec la petite taille de données (par exemple 2)

comparer les résultats avec les corrects connus. Vous devriez être en mesure de trouver ceux sur Internet, ou les faire à la main.

Si aléatoire signifie: même entrée, sortie différente, vous avez probablement un bug dans l'initialisation des variables. Utilisez un débogueur et une entrée connue pour vérifier que toutes les variables, en particulier tous les éléments des tableaux, sont correctement initialisées.

+0

L'entrée d'une onde sinusoïdale donne un résultat plus ou moins précis, mais l'entrée du micro donne un résultat aléatoire d'environ 100 à environ 1050. Mais j'ai vérifié que les données du micro sont correctes. – Niall

1

Le problème est dans votre fonction findBestCandidates():

Dans cette fonction vous accédez au tableau « entrées » de 0 à « longueur - 1 ». Lorsque vous appelez cette fonction à l'intérieur de la fonction detectPitchCalculation(), la fonction 'inputs' est 'results' et la 'longueur' est 'nHiPeriodInSamples'. Mais les 'résultats' ne sont attribués et remplis que 'nHiPeriodInSamples - nLowPeriodInSamples - 1'. Donc, si 'nLowPeriodInSamples' est supérieur à 0, vous accédez à la mémoire non allouée et aléatoire dans la fonction findBestCandidates()!

EDIT:

Un autre bug est que vous remplissez chaque entrée « nResolution » de la série 'résultats en fonction detectPitchCalculation() mais l'accès à chaque entrée dans la fonction findBestCandidates() (via les « intrants » argument).Mais puisque vous appelez detectPitchCalculation() avec un 'nResolution = 1' cela n'explique pas votre problème spécifique ... donc je vais regarder un peu plus. Mais ce serait certainement un problème si vous l'appelez avec des résolutions plus élevées.

+0

J'ai changé nHiPeriodInSamples en nHiPeriodInSamples - nLowPeriodInSamples - 1, mais il retourne toujours des valeurs aléatoires pour l'entrée micro. – Niall

+0

Laissez le '- 1' de côté car la longueur est 'nHiPeriodInSamples - nLowPeriodInSamples', ce qui signifie que vous pouvez accéder aux index de 0 à 'nHiPeriodInSamples - nLowPeriodInSamples - 1'. Mais cela ne résoudra pas votre problème aléatoire, je vais jeter un autre regard sur votre programme. – mmmmmmmm

2

Je ne suis pas un expert du son, mais si vous échantillonnez avec 44100 (j'imagine des échantillons par seconde) et que vous utilisez 1024 points de données. Vous travaillez avec environ 1/40ème de seconde de données. Je ne suis pas surpris que le pitch actuel varie beaucoup, selon le morceau que vous choisissez. Si vous voulez trouver la hauteur moyenne ou principale d'une voix, je m'attends à avoir besoin d'environ 1 seconde de données.

+0

Donc, plus d'échantillons par seconde donneraient un résultat plus ou moins précis? – Niall

+2

@Nail: il me semble que @Jens aurait raison de suggérer que vous avez besoin de beaucoup plus d'échantillons que 1024. Si je ne me trompe pas, vous avez reçu une indication similaire de @avakar sur votre question précédente: http: // stackoverflow .com/questions/1351381/fft-problem-retourne-random-results/1351398 # 1351398 –

1

À une fréquence d'échantillonnage de 44,1 kHz, 1024 échantillons ne représentent qu'un peu plus de 23 ms de données. N'est-il pas possible que ce soit simplement des données insuffisantes pour calculer la hauteur d'un chanteur humain? Je veux dire, le son que je peux faire pendant 23 ms n'est probablement pas quelque chose sur lequel j'ai beaucoup de contrôle de la hauteur; Je m'attendrais à ce que ce genre de mesure soit effectuée sur des périodes légèrement plus longues.

+0

Alors, est-ce que plus d'échantillons par seconde donneraient un résultat plus ou moins précis? – Niall

+1

Mon cher, vous devriez avoir au moins un rapide coup d'oeil de compréhension avant d'essayer de codifier quelque chose! Plus d'échantillons -> plus de temps; plus d'échantillons par seconde: moins de temps pour la même quantité d'échantillons. Moins d'échantillons par seconde -> plus de temps pour une quantité donnée d'échantillons. – gimpf

Questions connexes