Sommario:

Rilevatore di note musicali Arduino: 3 passaggi
Rilevatore di note musicali Arduino: 3 passaggi

Video: Rilevatore di note musicali Arduino: 3 passaggi

Video: Rilevatore di note musicali Arduino: 3 passaggi
Video: I buzzer - Facciamo suonare Arduino - I Sensori di Arduino 3 2024, Dicembre
Anonim
Image
Image

Rilevare le note musicali dal segnale audio è difficile soprattutto su Arduino a causa della memoria e della potenza di elaborazione limitate. In genere, la nota non è un'onda sinusoidale pura che rende difficile il rilevamento. Se prendiamo la trasformata di frequenza di vari strumenti musicali, potrebbe contenere più armoniche in base alla nota suonata. Ogni strumento ha la sua combinazione distintiva di varie armoniche. In questo codice, ho cercato di creare un programma che possa coprire il maggior numero possibile di strumenti. Puoi fare riferimento al video allegato in cui ho provato a testare i vari tipi di strumenti, i vari tipi di toni generati dalla tastiera e persino il suono della voce sono controllati. L'accuratezza del rilevamento varia da strumento a strumento. Per alcuni strumenti (ad esempio il pianoforte) in un intervallo limitato (200-500Hz) è accurato, mentre per alcuni strumenti ha una bassa precisione (ad esempio l'armonica).

Questo codice utilizza un codice FFT precedentemente sviluppato chiamato EasyFFT.

La dimostrazione del codice è mostrata nel video sopra con vari tipi di suoni strumentali e vocali.

Forniture

- Arduino Nano/Uno o superiore

- Modulo microfono per Arduino

Passaggio 1: Algoritmo per il rilevamento delle note

Come accennato nel passaggio precedente, il rilevamento è difficile a causa della presenza di più frequenze nei campioni audio.

Il programma funziona nel seguente flusso:

1. Acquisizione dati:

- questa sezione preleva 128 campioni dai dati audio, la separazione tra due campioni (frequenza di campionamento) dipende dalla frequenza di interesse. In questo caso, stiamo utilizzando la spaziatura tra due campioni per applicare la funzione della finestra di Hann e il calcolo dell'ampiezza/RMS. Questo codice esegue anche un azzeramento approssimativo sottraendo 500 dal valore analogread. Questo valore può essere modificato se necessario. Per un caso tipico, questi valori funzionano bene. Inoltre, è necessario aggiungere un po' di ritardo per avere una frequenza di campionamento di circa 1200Hz. nel caso di una frequenza di campionamento di 1200Hz può essere rilevata una frequenza massima di 600 HZ.

for(int i=0;i<128;i++) { a=analogRead(Mic_pin)-500; //spostamento zero approssimativo sum1=sum1+a; //al valore medio sum2=sum2+a*a; // al valore RMS a=a*(sin(i*3.14/128)*sin(i*3.14/128)); // Finestra di Hann in=4*a; // ridimensionamento per il ritardo di conversione da float a intMicroseconds(195); // in base all'intervallo di frequenza operativa }

2. FFT:

Una volta che i dati sono pronti, la FFT viene eseguita utilizzando EasyFFT. Questa funzione EasyFFT è stata modificata per correggere FFT per 128 campioni. Il codice viene inoltre modificato per ridurre il consumo di memoria. La funzione originale EasyFFT progettata per avere fino a 1028 campioni (con la scheda compatibile), mentre abbiamo bisogno solo di 128 campioni. questo codice riduce il consumo di memoria di circa il 20% rispetto alla funzione EasyFFT originale.

Una volta eseguita la FFT, il codice restituisce i primi 5 picchi di frequenza più dominanti per ulteriori analisi. Queste frequenze sono disposte in ordine decrescente di ampiezza.

3. Per ogni picco il codice rileva eventuali note ad esso associate. questo codice esegue la scansione solo fino a 1200 Hz. Non è necessario avere nota uguale alla frequenza con ampiezza massima.

Tutte le frequenze sono mappate tra 0 e 255, qui viene rilevata la prima ottava, ad esempio, da 65,4 Hz a 130,8 rappresenta un'ottava, da 130,8 Hz a 261,6 Hz rappresenta un'altra. Per ogni ottava, le frequenze sono mappate da 0 a 255. qui mappatura a partire da C a 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);}

I valori dell'array NoteV vengono utilizzati per assegnare la nota alle frequenze rilevate.

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

4. Dopo aver calcolato la nota per ogni frequenza, può succedere che esistano più frequenze che suggeriscono la stessa nota. Per avere un codice di output accurato considera anche le ripetizioni. Il codice somma tutti i valori di frequenza in base all'ordine di ampiezza e alle ripetizioni e raggiunge il picco della nota con l'ampiezza massima.

Passaggio 2: applicazione

L'uso del codice è semplice, tuttavia, ci sono anche molteplici limitazioni che devono essere tenute a mente mentre lo si fa. Il codice può essere copiato poiché viene utilizzato per il rilevamento delle note. I punti seguenti devono essere considerati durante l'utilizzo.

1. Assegnazione dei pin:

In base al Pin allegato, l'assegnazione deve essere modificata. Per il mio esperimento, l'ho tenuto su Analog pin 7, void setup() {Serial.begin(250000); Mic_pin = A7; }

2. Sensibilità del microfono:

La sensibilità del microfono deve essere modificata tale forma d'onda può essere generata con una buona ampiezza. Per lo più, il modulo Microfono viene fornito con un'impostazione di sensibilità. selezionare la sensibilità appropriata in modo che il segnale non sia troppo piccolo e non si spezzi a causa dell'ampiezza maggiore.

3. Soglia di ampiezza:

Questo codice si attiva solo se l'ampiezza del segnale è sufficientemente alta. questa impostazione deve essere impostata manualmente dall'utente. questo valore dipende dalla sensibilità del microfono e dall'applicazione.

if(somma2-somma1>5){

..

nel codice sopra, sum2 fornisce il valore RMS mentre sum 1 fornisce il valore medio. quindi la differenza tra questi due valori dà l'ampiezza del segnale sonoro. nel mio caso funziona correttamente con un valore di ampiezza intorno a 5.

4. Per impostazione predefinita, questo codice stamperà la nota rilevata. tuttavia, se si prevede di utilizzare la nota per altri scopi, è necessario utilizzare il numero assegnato direttamente. per esempio C=0;C#=1, D=2, D#=3 e successivi.

5. Se lo strumento ha una frequenza maggiore, il codice potrebbe fornire un'uscita falsa. la frequenza massima è limitata dalla frequenza di campionamento. quindi puoi giocare al di sotto dei valori di ritardo per ottenere un output ottimale. in ritardo di codice sotto di 195 microsecondi. che può essere ottimizzato per ottenere un output ottimale. Ciò influenzerà il tempo di esecuzione complessivo.

{ a=analogRead(Mic_pin)-500; //spostamento zero approssimativo

somma1=somma1+a; //al valore medio sum2=sum2+a*a; // al valore RMS a=a*(sin(i*3.14/128)*sin(i*3.14/128)); // Finestra di Hann in=4*a; // ridimensionamento per il ritardo di conversione da float a intMicroseconds(195); // in base all'intervallo di frequenza operativa }

6. questo codice funzionerà solo fino alla frequenza di 2000Hz. eliminando il ritardo tra i campionamenti si possono ottenere circa 3-4 kHz di frequenze di campionamento.

Precauzioni:

  • Come menzionato nel tutorial EasyFFT, la FFT consuma un'enorme quantità di memoria di Arduino. Quindi se hai un programma che ha bisogno di memorizzare alcuni valori si consiglia di utilizzare una scheda con una memoria maggiore.
  • Questo codice può funzionare bene per uno strumento/cantante e male per un altro. Il rilevamento accurato in tempo reale non è possibile a causa di limitazioni computazionali.

Passaggio 3: estivo

Il rilevamento delle note è un lavoro ad alta intensità di calcolo, ottenere un output in tempo reale è molto difficile, specialmente su Arduino. Questo codice può fornire circa 6,6 campioni/secondo (per un ritardo di 195 microsecondi aggiunto). questo codice funziona bene con il pianoforte e altri strumenti.

Spero che questo codice e questo tutorial siano utili nel tuo progetto relativo alla musica. in caso di dubbi o suggerimenti non esitate a commentare o inviare un messaggio.

Nel prossimo tutorial, modificherò questo codice per il rilevamento degli accordi musicali. quindi restate sintonizzati.

Consigliato: