Bonjour,
dans le cadre d'un projet de reconnaissance vocale, je suis amené à comparer la signature d'un son (en terme de fréquences) à d'autres signatures qui sont déjà connues.
Concrètement, on détecte les "pics" (=formants) dans le spectre d'un son, qui sont caractéristiques de ce son. On mémorise les fréquences de ces pics sous forme de n-uplets. On mémorise les n-uplets de sons de référence, ie de sons que l'on connait. Il y en a des milliers.
Pour chaque nouveau son à identifier, on compare le spectre (ie le n-uplet des fréquences de ses "pics") de ce son au n-uplet de chaque spectre de référence.
Vous comprenez donc que cela nécessite de faire énormément de comparaisons!
Et il me faudrait un moyen de faire ces comparaisons rapidement. Actuellement, on est obligé de comparer le spectre inconnu (ie le n-uplet) à tous les spectres de référence (ie à tous les n-uplets des sons connus)!
C'est bien trop gourmand.
Je précise quand même comment fonctionne la comparaison, puisque ça impose quelques contraintes.
Quand on veut comparer deux spectres, on compare en fait leurs n-uplets.
Pour cela on compare chaque composante du spectre1 (notée C indice i) à celles du spectre 2 (notée C indice i ' ):
-on recherche la composante C'i (c'est une fréquence) dans le spectre2 qui est la plus proche de la composante du spectre1 (C i).
-si la différence Di=|Ci-C'i| est supérieure à 0.5 (kHz) alors on considère que la composante Ci n'a pas d'équivalent dans le spectre2 et on fixe Di=1 (arbitrairement).
-sinon on mémorise Di et on refait la même chose pour les composantes suivantes du spectre1. La différence totale entre les deux spectres est la somme des différences entre composantes, ie D = sum(Di, i=1..n).
Exemple:
On sait que le spectre (nommé spectre2) contenant les fréquences caractéristiques 1, 2, 5 et 7 Khz correspond au son "e". => le n-uplet associé à ce spectre est (1;3;5;7)
Admettons que l'on ait le spectre1 d'un son inconnu, dont les fréquences caractéristiques sont 1, 2.4, 3.3 et 7.1 Khz => le n-uplet associé à ce spectre est (1; 2.4; 3.3 ; 7.1)
- on recherche la composante la plus proche de C1=1 dans le spectre 2, c'est C'1=1, donc D1=0
- on recherche la composante la plus proche de C2=2.4 dans le spectre 2, c'est C'2=3, donc D2=3-2.4=0.6>0.5 donc D1=1 (arbitraire)
- on recherche la composante la plus proche de C3=3.3 dans le spectre 2, c'est C'3=3, donc D3=0.3
- on recherche la composante la plus proche de C4=7.1 dans le spectre 2, c'est C'4=7, donc D4=0.1
- la différence totale D est la somme des Di ie D = 1.4
Voilà.
Cela fait pas mal de calculs pour une seule comparaison (il peut y avoir des dizaines de millions de comparaisons par seconde!).
Ce que je voudrais, ce serait de pouvoir trouver une fonction de hashage qui permettrait par simple comparaison des hashs de deux n-uplets dire si leur différence totale D sera supérieur à une valeur donnée ou pas.
Je suis ouvert à d'autres approches ;D
Je sais que ce post est long, mais j'espère avoir été suffisamment clair!
Merci de m'avoir lu.
Bonne soirée.
-----