Πίνακας περιεχομένων:

Ανιχνευτής μουσικών σημειώσεων Arduino: 3 βήματα
Ανιχνευτής μουσικών σημειώσεων Arduino: 3 βήματα

Βίντεο: Ανιχνευτής μουσικών σημειώσεων Arduino: 3 βήματα

Βίντεο: Ανιχνευτής μουσικών σημειώσεων Arduino: 3 βήματα
Βίντεο: Ανιχνευτής Μετάλλων επ. 4: Πώς είναι να μεγαλώνεις στην επαρχία ως μεταλάς; 2024, Νοέμβριος
Anonim
Image
Image

Η ανίχνευση μουσικών σημειώσεων από το ηχητικό σήμα είναι δύσκολο να γίνει ειδικά στο Arduino λόγω περιορισμένης μνήμης και ισχύος επεξεργασίας. Γενικά, η νότα δεν είναι ένα καθαρό ημιτονοειδές κύμα που κάνει την ανίχνευση δύσκολη. Αν πάρουμε τον μετασχηματισμό συχνότητας διαφόρων μουσικών οργάνων, μπορεί να περιέχει πολλές αρμονικές με βάση τη νότα που παίζεται. Κάθε όργανο έχει τον δικό του συνδυασμό από διάφορες αρμονικές. Σε αυτόν τον κώδικα, προσπάθησα να φτιάξω ένα πρόγραμμα που μπορεί να καλύψει όσο το δυνατόν περισσότερα όργανα. Μπορείτε να ανατρέξετε στο συνημμένο βίντεο στο οποίο προσπάθησα να δοκιμάσω τους διάφορους τύπους οργάνων, τους διάφορους τύπους τόνων που δημιουργούνται από το πληκτρολόγιο και ακόμη και τον ήχο της φωνής. Η ακρίβεια της ανίχνευσης διαφέρει από όργανο σε όργανο. Για κάποιο όργανο (δηλαδή πιάνο) σε περιορισμένη εμβέλεια (200-500Hz) είναι ακριβές, ενώ για κάποιο όργανο έχει χαμηλή ακρίβεια (δηλαδή αρμονική).

Αυτός ο κώδικας χρησιμοποιεί έναν προηγουμένως ανεπτυγμένο κώδικα FFT που ονομάζεται EasyFFT.

Η επίδειξη του κώδικα εμφανίζεται στο παραπάνω βίντεο με διάφορους τύπους ήχου οργάνων καθώς και φωνητικούς.

Προμήθειες

- Arduino Nano/Uno ή παραπάνω

- Μονάδα μικροφώνου για Arduino

Βήμα 1: Αλγόριθμος για την ανίχνευση σημειώσεων

Όπως αναφέρθηκε στο προηγούμενο βήμα, η ανίχνευση είναι δύσκολη λόγω της παρουσίας πολλαπλών συχνοτήτων στα ηχητικά δείγματα.

Το πρόγραμμα λειτουργεί με την ακόλουθη ροή:

1. Απόκτηση δεδομένων:

- αυτή η ενότητα λαμβάνει 128 δείγματα από δεδομένα ήχου, ο διαχωρισμός μεταξύ δύο δειγμάτων (συχνότητα δειγματοληψίας) ανάλογα με τη συχνότητα ενδιαφέροντος. Σε αυτήν την περίπτωση, χρησιμοποιούμε το διάστημα μεταξύ δύο δειγμάτων που χρησιμοποιείται για την εφαρμογή της λειτουργίας παραθύρου Hann καθώς και υπολογισμού πλάτους/RMS. Αυτός ο κώδικας κάνει επίσης μηδενικό μηδενισμό αφαιρώντας 500 από την τιμή ανάγνωσης. Αυτή η τιμή μπορεί να αλλάξει εάν απαιτείται. Για μια τυπική περίπτωση, αυτές οι τιμές λειτουργούν καλά. Επιπλέον, πρέπει να προστεθεί κάποια καθυστέρηση για να έχει συχνότητα δειγματοληψίας περίπου 1200Hz. στην περίπτωση συχνότητας δειγματοληψίας 1200Hz μπορεί να ανιχνευθεί μέγιστη συχνότητα 600 HZ.

για (int i = 0; i <128; i ++) {a = analogRead (Mic_pin) -500; // τραχύ μηδέν μετατόπιση sum1 = sum1+a; // στη μέση τιμή sum2 = sum2+a*a; // σε τιμή RMS a = a*(sin (i*3.14/128)*sin (i*3.14/128)); // Παράθυρο Hann στο = 4*a; // κλιμάκωση για καθυστέρηση μετατροπής float σε int Μικροδευτερόλεπτα (195); // με βάση το εύρος συχνοτήτων λειτουργίας}

2. FFT:

Μόλις τα δεδομένα είναι έτοιμα, το FFT εκτελείται χρησιμοποιώντας το EasyFFT. Αυτή η λειτουργία EasyFFT έχει τροποποιηθεί για να διορθώσει το FFT για 128 δείγματα. Ο κώδικας έχει επίσης τροποποιηθεί για να μειώσει την κατανάλωση μνήμης. Η αρχική λειτουργία EasyFFT έχει σχεδιαστεί για να έχει έως και 1028 δείγματα (με τη συμβατή πλακέτα), ενώ χρειαζόμαστε μόνο 128 δείγματα. Αυτός ο κωδικός μειώνει την κατανάλωση μνήμης περίπου 20% σε σύγκριση με την αρχική λειτουργία EasyFFT.

Μόλις ολοκληρωθεί το FFT, ο κώδικας επιστρέφει τις κορυφαίες 5 κορυφαίες κορυφές συχνότητας για περαιτέρω ανάλυση. Αυτή η συχνότητα είναι διατεταγμένη κατά φθίνουσα σειρά πλάτους.

3. Για κάθε κορυφή, ο κώδικας ανιχνεύει πιθανές σημειώσεις που σχετίζονται με αυτό. αυτός ο κωδικός σαρώνει μόνο έως 1200 Hz. Δεν είναι απαραίτητο να έχετε την ίδια σημείωση με τη συχνότητα με μέγιστο πλάτος.

Όλες οι συχνότητες χαρτογραφούνται μεταξύ 0 και 255, εδώ ανιχνεύεται η πρώτη οκτάβα, για παράδειγμα, 65,4 Hz έως 130,8 αντιπροσωπεύει μια οκτάβα, 130,8 Hz έως 261,6 Hz αντιπροσωπεύει μια άλλη. Για κάθε οκτάβα, οι συχνότητες αντιστοιχίζονται από 0 έως 255. εδώ η χαρτογράφηση ξεκινάει από το Γ έως το Γ '.

εάν (f_peaks > 1040) {f_peaks = 0;} εάν (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);}

Οι τιμές του πίνακα NoteV χρησιμοποιούνται για την εκχώρηση της σημείωσης στις εντοπισμένες συχνότητες.

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

4. Μετά τον υπολογισμό της σημείωσης για κάθε συχνότητα, ενδέχεται να υπάρχουν πολλές συχνότητες που υποδηλώνουν την ίδια νότα. Για να έχετε έναν ακριβή κωδικό εξόδου, λαμβάνετε επίσης υπόψη τις επαναλήψεις. Ο κώδικας αθροίζει όλες τις τιμές συχνότητας με βάση τη σειρά πλάτους και τις επαναλήψεις και κορυφώνει τη νότα με το μέγιστο πλάτος.

Βήμα 2: Εφαρμογή

Η χρήση του κώδικα είναι απλή, ωστόσο, υπάρχουν επίσης πολλοί περιορισμοί που πρέπει να ληφθούν υπόψη κατά τη χρήση του. Ο κώδικας μπορεί να αντιγραφεί καθώς χρησιμοποιείται για την ανίχνευση σημειώσεων. Τα παρακάτω σημεία πρέπει να ληφθούν υπόψη κατά τη χρήση του.

1. Ανάθεση καρφιτσών:

Με βάση το συνημμένο, η ανάθεση Pin πρέπει να τροποποιηθεί. Για το πείραμά μου, το κράτησα στο Analog pin 7, void setup () {Serial.begin (250000); Mic_pin = A7; }

2. Ευαισθησία μικροφώνου:

Η ευαισθησία του μικροφώνου πρέπει να τροποποιηθεί, έτσι ώστε η κυματομορφή να μπορεί να δημιουργηθεί με καλό πλάτος. Κυρίως, η μονάδα μικροφώνου διαθέτει ρύθμιση ευαισθησίας. κατάλληλη ευαισθησία για να επιλεγεί έτσι ώστε το σήμα να μην είναι πολύ μικρό και επίσης να μην αποσυνδέεται λόγω μεγαλύτερου πλάτους.

3. Όριο πλάτους:

Αυτός ο κωδικός ενεργοποιείται μόνο εάν το πλάτος του σήματος είναι αρκετά υψηλό. αυτή η ρύθμιση πρέπει να οριστεί χειροκίνητα από τον χρήστη. αυτή η τιμή εξαρτάται από την ευαισθησία του μικροφώνου καθώς και την εφαρμογή.

αν (sum2-sum1> 5) {

..

στον παραπάνω κωδικό, το sum2 δίνει τιμή RMS ενώ το άθροισμα 1 δίνει μέση τιμή. έτσι η διαφορά μεταξύ αυτών των δύο τιμών δίνει το πλάτος του ηχητικού σήματος. στην περίπτωσή μου, λειτουργεί σωστά με τιμή πλάτους περίπου 5.

4. Από προεπιλογή, αυτός ο κωδικός θα εκτυπώσει τη σημείωση που εντοπίστηκε. Ωστόσο, εάν σκοπεύετε να χρησιμοποιήσετε τη σημείωση για κάποιον άλλο σκοπό, θα πρέπει να χρησιμοποιηθεί ο απευθείας εκχωρημένος αριθμός. για παράδειγμα C = 0; C#= 1, D = 2, D#= 3 και μετά.

5. Εάν το όργανο έχει υψηλότερη συχνότητα, ο κωδικός μπορεί να δώσει ψευδή έξοδο. η μέγιστη συχνότητα περιορίζεται από τη συχνότητα δειγματοληψίας. έτσι μπορείτε να παίξετε κάτω από τιμές καθυστέρησης για να έχετε τη βέλτιστη απόδοση. στον παρακάτω κωδικό καθυστέρηση 195 μικρών δευτερολέπτων. το οποίο μπορεί να τροποποιηθεί για να έχει τη βέλτιστη απόδοση. Αυτό θα επηρεάσει το συνολικό χρόνο εκτέλεσης.

{a = analogRead (Mic_pin) -500; // τραχιά μηδενική μετατόπιση

sum1 = sum1+a; // στη μέση τιμή sum2 = sum2+a*a; // σε τιμή RMS a = a*(sin (i*3.14/128)*sin (i*3.14/128)); // Παράθυρο Hann στο = 4*a; // κλιμάκωση για καθυστέρηση μετατροπής float σε int Μικροδευτερόλεπτα (195); // με βάση το εύρος συχνοτήτων λειτουργίας}

6. Αυτός ο κωδικός θα λειτουργεί μόνο μέχρι τη συχνότητα 2000Hz. με την εξάλειψη της καθυστέρησης μεταξύ δειγματοληψίας περίπου 3-4 kHz συχνοτήτων δειγματοληψίας μπορεί να επιτευχθεί.

Προφυλάξεις:

  • Όπως αναφέρεται στο σεμινάριο EasyFFT, το FFT τρώει τεράστια ποσότητα μνήμης του Arduino. Έτσι, εάν έχετε ένα πρόγραμμα που πρέπει να αποθηκεύσει κάποιες τιμές, συνιστάται να χρησιμοποιήσετε έναν πίνακα με υψηλότερη μνήμη.
  • Αυτός ο κώδικας μπορεί να λειτουργεί καλά για ένα όργανο/τραγουδιστής και κακός για ένα άλλο. Σε πραγματικό χρόνο Η ακριβής ανίχνευση δεν είναι δυνατή λόγω υπολογιστικών περιορισμών.

Βήμα 3: Summery

Η ανίχνευση σημειώσεων είναι υπολογιστικά εντατική, η λήψη πραγματικού χρόνου είναι πολύ δύσκολη, ειδικά στο Arduino. Αυτός ο κωδικός μπορεί να δώσει περίπου 6,6 δείγματα /δευτερόλεπτα (για 195 μικροδευτερόλεπτα προστέθηκε καθυστέρηση). αυτός ο κώδικας λειτουργεί καλά με το πιάνο και μερικά άλλα όργανα.

Ελπίζω ότι αυτός ο κώδικας και το σεμινάριο θα είναι χρήσιμα στο έργο σας που σχετίζεται με τη μουσική. σε περίπτωση οποιασδήποτε αμφιβολίας ή πρότασης μη διστάσετε να σχολιάσετε ή να στείλετε μήνυμα.

Στο επόμενο σεμινάριο, θα τροποποιήσω αυτόν τον κώδικα για την ανίχνευση μουσικών χορδών. οπότε μείνετε συντονισμένοι.

Συνιστάται: