Table des matières:

Détecteur de notes de musique Arduino : 3 étapes
Détecteur de notes de musique Arduino : 3 étapes

Vidéo: Détecteur de notes de musique Arduino : 3 étapes

Vidéo: Détecteur de notes de musique Arduino : 3 étapes
Vidéo: Arduino Music: Note Detector 2024, Novembre
Anonim
Image
Image

La détection des notes de musique à partir du signal audio est difficile à faire, en particulier sur Arduino en raison de la mémoire et de la puissance de traitement limitées. Généralement, la note n'est pas une onde sinusoïdale pure qui rend la détection difficile. Si nous prenons la transformation de fréquence de divers instruments de musique, elle peut contenir plusieurs harmoniques en fonction de la note jouée. Chaque instrument a sa propre combinaison de signature de diverses harmoniques. Dans ce code, j'ai essayé de faire un programme qui puisse couvrir autant d'instruments que possible. Vous pouvez vous référer à la vidéo ci-jointe dans laquelle j'ai essayé de tester les différents types d'instruments, les différents types de sons générés par le clavier et même le son de la voix sont vérifiés. La précision de la détection varie d'un instrument à l'autre. Pour certains instruments (par exemple le piano) dans une plage limitée (200-500 Hz), il est précis, tandis que certains instruments ont une faible précision (par exemple, l'harmonica).

Ce code utilise un code FFT précédemment développé appelé EasyFFT.

La démonstration du code est montrée dans la vidéo ci-dessus avec différents types de sons d'instruments ainsi que des voix.

Fournitures

-Arduino Nano/Uno ou supérieur

- Module micro pour Arduino

Étape 1: Algorithme de détection de notes

Comme mentionné à l'étape précédente, la détection est difficile en raison de la présence de plusieurs fréquences dans les échantillons audio.

Le programme fonctionne dans le flux suivant:

1. Acquisition de données:

- cette section prend 128 échantillons de données audio, la séparation entre deux échantillons (fréquence d'échantillonnage) dépendant de la fréquence d'intérêt. Dans ce cas, nous utilisons l'espacement entre deux échantillons pour appliquer la fonction de fenêtre de Hann ainsi que le calcul d'amplitude/RMS. Ce code effectue également une mise à zéro approximative en soustrayant 500 de la valeur de lecture analogique. Cette valeur peut être modifiée si nécessaire. Pour un cas typique, ces valeurs fonctionnent bien. De plus, un certain délai doit être ajouté pour avoir une fréquence d'échantillonnage d'environ 1200 Hz. dans le cas d'une fréquence d'échantillonnage de 1200 Hz, une fréquence maximale de 600 Hz peut être détectée.

for(int i=0;i<128;i++) { a=analogRead(Mic_pin)-500; //décalage à zéro approximatif sum1=sum1+a; //à la valeur moyenne sum2=sum2+a*a; // à la valeur RMS a=a*(sin(i*3.14/128)*sin(i*3.14/128)); // Fenêtre de Hann dans=4*a; // mise à l'échelle pour la conversion float en int delayMicroseconds(195); // basé sur la plage de fréquence de fonctionnement }

2. FFT:

Une fois les données prêtes, la FFT est effectuée à l'aide d'EasyFFT. Cette fonction EasyFFT est modifiée pour corriger la FFT pour 128 échantillons. Le code est également modifié pour réduire la consommation de mémoire. La fonction originale EasyFFT conçue pour avoir jusqu'à 1028 échantillons (avec la carte compatible), alors que nous n'avons besoin que de 128 échantillons. ce code réduit la consommation de mémoire d'environ 20 % par rapport à la fonction EasyFFT d'origine.

Une fois la FFT terminée, le code renvoie les 5 pics de fréquence les plus dominants pour une analyse plus approfondie. Ces fréquences sont classées par ordre décroissant d'amplitude.

3. Pour chaque pic, le code détecte les notes possibles qui lui sont associées. ce code ne scanne que jusqu'à 1200 Hz. Il n'est pas nécessaire d'avoir la même note que la fréquence avec une amplitude max.

Toutes les fréquences sont mappées entre 0 et 255, ici la première octave est détectée, par exemple, 65,4 Hz à 130,8 représente une octave, 130,8 Hz à 261,6 Hz en représente une autre. Pour chaque octave, les fréquences sont mappées de 0 à 255. ici mappage à partir de C à C'.

if(f_peaks>1040){f_peaks=0;} if(f_peaks>=65,4 && f_peaks=130.8 && f_peaks=261.6 && f_peaks=523.25 && f_peaks =1046 && f_peaks<=2093) {f_peaks=255*((f_peaks/1046)-1);}

Les valeurs du tableau NoteV sont utilisées pour attribuer la note aux fréquences détectées.

octet NoteV[13]={8, 23, 40, 57, 76, 96, 116, 138, 162, 187, 213, 241, 255};

4. Après avoir calculé la note pour chaque fréquence, il se peut qu'il existe plusieurs fréquences qui suggèrent la même note. Pour avoir un code de sortie précis, prend également en compte les répétitions. Le code additionne toutes les valeurs de fréquence en fonction de l'ordre d'amplitude et des répétitions et pointe la note avec une amplitude maximale.

Étape 2: Candidature

L'utilisation du code est simple, cependant, il y a aussi plusieurs limitations qui doivent être gardées à l'esprit pendant qu'il. Le code peut être copié car il est utilisé pour la détection de notes. Les points ci-dessous doivent être pris en compte lors de son utilisation.

1. Affectation des broches:

Sur la base de l'affectation des broches ci-jointe doit être modifiée. Pour mon expérience, je l'ai gardé sur la broche analogique 7, void setup() {Serial.begin(250000); Mic_pin = A7; }

2. Sensibilité du microphone:

La sensibilité du microphone doit être modifiée, une telle forme d'onde peut être générée avec une bonne amplitude. La plupart du temps, le module Microphone est livré avec un réglage de sensibilité. la sensibilité appropriée doit être sélectionnée de telle sorte que le signal ne soit ni trop petit ni trop écrêté en raison d'une amplitude plus élevée.

3. Seuil d'amplitude:

Ce code ne s'active que si l'amplitude du signal est suffisamment élevée. ce paramètre doit être défini manuellement par l'utilisateur. cette valeur dépend de la sensibilité du microphone ainsi que de l'application.

si(somme2-somme1>5){

..

dans le code ci-dessus, sum2 donne la valeur RMS tandis que sum 1 donne la valeur moyenne. donc la différence entre ces deux valeurs donne l'amplitude du signal sonore. dans mon cas, cela fonctionne correctement avec une valeur d'amplitude d'environ 5.

4. Par défaut, ce code imprimera la note détectée. cependant, si vous prévoyez d'utiliser la note à d'autres fins, le numéro directement attribué doit être utilisé. par exemple C=0;C#=1, D=2, D#=3 et au-delà.

5. Si l'instrument a une fréquence plus élevée, le code peut donner une fausse sortie. la fréquence maximale est limitée par la fréquence d'échantillonnage. vous pouvez donc jouer en dessous des valeurs de retard pour obtenir une sortie optimale. dans un délai de code inférieur à 195 microsecondes. qui peut être modifié pour obtenir un rendement optimal. Cela affectera le temps d'exécution global.

{ a=analogRead(Mic_pin)-500; //décalage approximatif du zéro

somme1=somme1+a; //à la valeur moyenne sum2=sum2+a*a; // à la valeur RMS a=a*(sin(i*3.14/128)*sin(i*3.14/128)); // Fenêtre de Hann dans=4*a; // mise à l'échelle pour la conversion float en int delayMicroseconds(195); // basé sur la plage de fréquence de fonctionnement }

6. ce code ne fonctionnera que jusqu'à la fréquence 2000Hz. en éliminant le retard entre l'échantillonnage, environ 3-4 kHz des fréquences d'échantillonnage peuvent être obtenues.

Précautions:

  • Comme mentionné dans le didacticiel EasyFFT, la FFT consomme une énorme quantité de mémoire d'Arduino. Donc, si vous avez un programme qui a besoin de stocker des valeurs, il est recommandé d'utiliser une carte avec une mémoire plus élevée.
  • Ce code peut fonctionner bien pour un instrument/chanteur et mauvais pour un autre. Une détection précise en temps réel n'est pas possible en raison de limitations de calcul.

Étape 3: estival

La détection de notes est un travail intensif en calcul, obtenir une sortie en temps réel est très difficile, en particulier sur Arduino. Ce code peut donner environ 6,6 échantillons/secondes (pour un délai de 195 microsecondes ajouté). ce code fonctionne bien avec le piano et certains autres instruments.

J'espère que ce code et ce tutoriel seront utiles dans votre projet lié à la musique. en cas de doute ou de suggestion, n'hésitez pas à commenter ou à envoyer un message.

Dans le prochain tutoriel, je modifierai ce code pour la détection d'accords musicaux. alors restez à l'écoute.

Conseillé: