Fréquence fondamentale d'un signal sonore par autocorrélation
Répondre à la discussion
Affichage des résultats 1 à 7 sur 7

Fréquence fondamentale d'un signal sonore par autocorrélation



  1. #1
    iPhysics

    Fréquence fondamentale d'un signal sonore par autocorrélation


    ------

    Bonjour à tous,

    J'espère que le forum "Physique" dans lequel je poste ma demande est adéquat, puisque ma demande concerne un cours de traitement du signal. Voici mon problème :

    A partir d'un échantillon vocal de quelques secondes, (j'ai une librairie de son que j'appelle aléatoirement allant généralement de 3 à 5 secondes) il m'est demandé de normaliser puis de séparer le tout en fenêtres (par exemple 30ms) avec un pas (par exemple de 15ms). Pour illustrer de manière claire ce contexte, mon signal est numérique et possède une fréquence d'échantillonnage de 16000Hz et j'ai à ce stade une liste de vecteurs "data" correspondant à tous les points, prenant une valeur entre 0 et 1 de 0 à 30ms, puis de 15 à 45ms, puis de 30 à 60ms etc. A partir d'un plot de l'énergie de chaque frame, je demande à l'utilisateur de mon programme d'entrer une énergie seuil à partir de laquelle on considère que des voyelles sont prononcées (je n'ai pas trouvé de moyen peu faillible de rentrer ce seuil automatiquement en n'utilisant que l'énergie de mes frames).

    Maintenant que le contexte est bien établi, voici mon problème : il m'est demandé d'utiliser une fonction d'autocorrélation pour chaque fenêtre mon signal numérique afin de déterminer la fréquence fondamentale ("pitch") pour chacune de ces fenêtres, en ne prenant que celles dont l'énergie dépasse le seuil entré par l'utilisateur. N'ayant jamais vu l'autocorrélation en cours, l'enseignant nous a fourni une fonction xcorr.py, laquelle retourne un vecteur "lags" et un vecteur "corr" de taille 101 (je rappelle qu'avec des frames de 30ms et un fs de 16000Hz mes fenêtres sont des vecteurs de taille 480). L'enseignant nous donne également un indice en nous disant, sans expliquer toutefois la fonction, que la distance entre les deux plus hauts sommets de la fonction d'autocorrélation dans le domaine temporel était une bonne approximation de la période fondamentale (1/f0).

    J'ai alors utilisé une fonction find_peaks pour trouver les sommets du vecteur "corr" et après un tri, j'ai pu en ressortir les indices de deux plus hauts sommets. En prenant l'inverse de la distance entre ces deux sommets, le tout multiplié par ma fréquence d'échantillonnage afin d'avoir un équivalent temporel me voilà avec un vecteur f0 me donnant la valeur trouvée pour chaque fenêtre. Lorsque je trace tout cela en graphique, catastrophe : je me retrouve avec beaucoup de fenêtres ayant un f0 astronomique (certaines au dessus de 3000Hz, ce qui ne correspond absolument pas à la voix d'un humain (ici j'étudie d'abord une voix d'homme qui plus est)).
    En affichant graphiquement le vecteur "corr" je me rend compte en effet qu'avec le bruit du signal, les perturbations peuvent créer des sommets proches du sommet le plus haut et donc fausser les résultats. Cependant même avec quelques astuces du style prendre les sommets du vecteur des sommets afin d'être sûr d'éviter ce genre d'incidents, aucun résultat retournant comme prévu des valeurs proches de disons 150Hz.

    Je vous serais infiniment reconnaissant si vous pouviez me donner une piste. Il est fort possible également que mes erreurs soient dues à mon incompréhension de l'autocorrélation, d'autant que prendre la distance entre des points d'un vecteur de 101 points qu'est mon corr, pas sûr que cela vaille la même chose que la distance entre les points de mes fenêtres de 480 points... Je suis dans le flou quant à cela, quant à mon utilité ici du vecteur lags etc.

    Je vous remercie d'avance, si vous souhaitez des éléments de mon code (en python) afin de mieux m'aider, je peux vous fournir cela. Désolé du pavé mais il me semble que planter le décor était intéressant pour comprendre mon problème.

    -----

  2. #2
    gts2

    Re : Fréquence fondamentale d'un signal sonore par autocorrélation

    Bonjour,

    Plutôt que le code Python, c'est vous fournissiez un graphe du résultat de l'autocorrélation.

  3. #3
    iPhysics

    Re : Fréquence fondamentale d'un signal sonore par autocorrélation

    11.png 12.png 13.png 14.png

    Voici 4 images tirées de mon programme, l'une d'elle représente la f0 pour chaque frame en prenant comme formule 1/(maxcorr1 - maxcorr2) * 16000
    Les 3 autres images représentent la fonction de corrélation pour des frames données. Une grande partie possède une allure semblable à la frame 171 ou 57 (beaucoup ne sont pas représentées car la fenêtre n'atteint pas le seuil d'énergie) mais mêmes dans ces cas f0 monte vers les 500Hz, et pour certaines frames c'est alors pire et on se retrouve dans la configuration de la frame 201 qui donne une fréquence très élevée.

  4. #4
    gts2

    Re : Fréquence fondamentale d'un signal sonore par autocorrélation

    Pour 171, je trouve à la louche 25 soit 640 Hz, un peu élevée ?
    Pour 201, ce n'est pas une voyelle, il faut que vous trouviez un moyen d'éliminer ce genre de trame, il n'y a pas de formant, autrement dit pas de pic "propre"
    Pour 57, j'ai simulé pour avoir qqch qui ressemble (sinus à 2f0 + sinus à 3f0), le problème est que la pic le plus important est après (fréquence < 320 Hz)
    Capture d’écran.png

    Le fait de prendre 101 points vient de deux raisons :
    - lorsqu'on approche de l'extrémité, il n'y a plus grand chose à corréler : voir la figure suivante pour laquelle on a un sinus qui devrait donner un sinus, on voit qu'à la fin on ne voit plus grand chose.
    autocorrsin.png
    - il n'est pas nécessaire d'aller au-delà de la fréquence la plus basse attendue, ici cela donne 16000/50=320 ce qui me parait quand même élevée

    Donc
    Pour 171, pb d'échelle de fréquence ??
    Pour 201, pic hors cadre ?
    Pour 57, plus simple à comprendre, mais pb informatique pour éliminer ce genre de courbe.

  5. A voir en vidéo sur Futura
  6. #5
    iPhysics

    Re : Fréquence fondamentale d'un signal sonore par autocorrélation

    Merci pour cette réponse,

    en effet je réalise que la fréquence la plus basse est le pitch d'une voix d'enfant, alors à quoi s'attendre de cet algo... Le problème est qu'il n'y a aucun moyen pour moi de changer la taille du vecteur (le "maxlag" m'est imposé à 50 (" a maxlag = the lowest f0 possible (50 Hz)" dans le protocole). Pour l'estimation du pitch, ledit protocole nous demande de développer deux algorithmes différents (autocorrélation et "cepstrum"), peut être que ce travail est prévu pour avoir une mauvaise approximation avec le premier algorithme qui sait ?

    Parce qu'en effet, même pour des signaux où tout va bien, 640Hz dépasse tout ce que j'ai pu entendre de la bouche d'un humain. N'ayant pas vu la notion d'autocorrélation, peut-être y a-t-il un changement d'échelle à faire, peut être que la distance entre deux indices dans la fonction d'autocorrélation ne vaut pas 1/16 ms, j'avoue que la documentation de la fonction ne m'aide pas vraiment là dessus.

    Pour celui à 201Hz, comment peut-on voir à vue d'oeil qu'il ne s'agit pas d'une voyelle ? C'est quand la fonction n'est pas "smooth" ? Le traitement de signal m'intéresse énormément mais je débute et il est vrai que la méthode utilisée pour détecter les "voiced/unvoiced sounds" est un peu bancale. Au passage voici le plot de l'énergie par frame (j'ai joué le rôle de l'utilisateur et ait choisi une valeur seuil de 6 pour les voyelles) Nom : 15.png
Affichages : 588
Taille : 29,5 Ko

    Et enfin pour 57, peut-être que je pourrais bidouiller un peu pour prendre 2 frames pour certains cas sous certaines conditions, mais il est clair que cela commence à devenir un problème bien plus complexe..

  7. #6
    gts2

    Re : Fréquence fondamentale d'un signal sonore par autocorrélation

    Pour ce qui est de l'autocorréllation avec les mains, pour obtenir la donnée i, on décale le signal d'un pas i et on fait le produit scalaire avec le signal de départ.
    Si on a une sinusoïde, quand on a décalé d'une période, les deux signaux sont identiques et on a un maximum, ce qui permet de déterminer la période et donc la fréquence.
    Donc un point correspond bien à une période d'échantillonnage.
    "(le "maxlag" m'est imposé à 50 (" a maxlag = the lowest f0 possible (50 Hz)" dans le protocole)" là c'est pas clair : maxlag = décalage maxi donc une durée, dont l'inverse est la fréquence la plus basse possible. Donc sauf cas très particulier, je ne vois pas comment prenant le 50 Te va donner du 50Hz (cela voudrait que la fréquence d'échantillonnage de l'autocorrélation serait de 2500 Hz sans rapport simple avec les 16000 Hz.

    Une voyelle est constitué essentiellement de deux formants l'un basse fréquence, l'autre haute, on a un signal à peu près périodique, donc on voit des pics clairement séparés. Ce n'est pas le cas sinon.
    Vous avez vu des choses sur la parole avant ?

  8. #7
    iPhysics

    Re : Fréquence fondamentale d'un signal sonore par autocorrélation

    Ah je comprends mieux ! J'avais cru comprendre qu'on prenait une même fonction décalée mais je ne comprenais pas en quoi on pouvait déterminer la période, maintenant cela me paraît beaucoup plus clair !

    Pour ce qui est du maxlag en effet je trouve cela un peu étrange. En lisant ce message j'ai eu un petit tilt, peut être que j'ai mal compris ce qu'on attendait de moi. En fait, la fonction xcorr qui nous est fourni nous demande de passer un maxlag en paramètre correspondant donc à "the lowest f0 possible (50Hz)", j'ai interprété cela comme "passez en paramètre maxlag = 50", mais du coup, si je passais en paramètre maxlag = 320 cela correspondrait du coup à une fréquence la plus basse de 50Hz. Je vais essayer ainsi, cela devrait résoudre pas mal de mes problèmes.

    Je ne suis pas encore arrivé à cette étape du projet, mais l'étape qui suit l'approximation du pitch, c'est l'approximation des formants (avec un algo LPC). Cela pourra sûrement m'être utile pour un tri plus efficace, je pense d'ailleurs du coup avoir compris comment détecter une voyelle à l'oeil !

    Nous avions utilisé la parole pour illustrer l'une ou l'autre application du cours théorique (portant surtout sur les filtres analogiques/numériques et les différentes transformées de Fourier (FFT, DTFT, ...)), mais c'est la première fois que nous étudions la parole en tant que telle et pas seulement comme une illustration.

Discussions similaires

  1. [Numérique] passer d'un signal binaire à la génération d'un signal sonore
    Par invite83ff31e4 dans le forum Électronique
    Réponses: 6
    Dernier message: 07/07/2016, 08h34
  2. Réponses: 4
    Dernier message: 18/02/2015, 13h25
  3. Traitement du Signal - Fonction d'autocorrélation
    Par invite04edecf8 dans le forum Mathématiques du supérieur
    Réponses: 3
    Dernier message: 04/08/2011, 12h50
  4. Autocorrélation d'un signal porte (rectangle) périodique
    Par invitea78e0a21 dans le forum Mathématiques du supérieur
    Réponses: 4
    Dernier message: 09/12/2009, 11h48
  5. Autocorrélation d'un signal fini
    Par inviteb54cf757 dans le forum Mathématiques du supérieur
    Réponses: 0
    Dernier message: 12/03/2007, 14h33