Introduction: Translate Songs to Be Played on Arduino
I wanted to create a way to play the Stranger Things theme song on the Arduino for a separate project. Translating the notes turned out, at least for me, very tedious. After some digging around to see what others had already accomplished I only found Shvelo's musicxml_to_arduino project which was written in Ruby. I hadn't done much with Ruby and didn't know anything about musicxml (MXL) files so I decided to create my own windows app based on the Ruby code and see what MXL files were all about.
Step 1: MXL Files
The best source I found for MXL files is musescore.com with a huge collection user submitted sheet enhanced music. An MXL file is a compressed xml file that contains voice, instrument, note and duration definitions. I downloaded this version of the Stranger Things theme song by Riley Apperson.
Many formats of the music are available for download but MXL contains the information needed for the conversion to something an Arduino can play.
Image 2 above shows the contents start with PK which was an immediate give away that the file was compressed with PK Zip.
Image 3 is the same file uncompressed containing a standard XML format.
Step 2: MXL File Data
There's a couple of things to look at in the data. Remember we have to keep notes and the overall song simple because without something more powerful than an Arduino or some additional hacks we can only play one note at a time.
- Note Step - E
- Note Octave - 3
- Duration - 1ms ish
- Voice - The voice is going to be layered notes on top of each other. You may have to find a simple version of the song or pluck out which parts of each voice you want.
I took this information, parsed it out using a C# and put it into arduino code to output music.
Step 3: Arduino Code
After parsing the data from the MXL file I then placed that into the arduino code. Durations have to be played with to get the song to come out how you feel it should. You can find the Arduino code I wrote on GitHub.
int notes[] = {NOTE_C3, NOTE_E3, NOTE_G3, NOTE_B3, NOTE_C4
int durations[] = {750, 750, 750, 750, 750
Looking now I'm seeing that a multidimensional array would be more efficient. The notes and durations correspond so if there are 5 notes there should be 5 durations.
Each note is defined to a tone
- #define NOTE_B0 31
- #define NOTE_C1 33
- #define NOTE_CS1 35
- #define NOTE_D1 37
Each note in the array is then looped through then played using the note definition shown above.
tone(8, notes[thisNote],noteDuration);
Note that the Arduino Uno has a file size limit so the amount of notes has to be shortened to meet that limit. The app I wrote has a note limiter that can be changed to meet your needs.
Step 4: C#
I wrote a small app in c# to decompress the mxl, parse out the music data then output the arduino format to a textarea. The source code for this app is on GitHub.
Note that the Arduino Uno has a file size limit so the amount of notes has to be shortened to meet that limit. The app I wrote has a note limiter that can be changed to meet your needs.
Step 5: Arduino Wiring
This is super simple. I just used a piezo from a walkie talkie then connected Positive (red) to Pin 8 and Negative (black) to Ground.
Step 6: Preview of Audio
Here's a preview of the audio the arduino produces.
Attachments
Step 7: Files
All files needed are on GitHub here https://github.com/MrRedBeard/DotNet-MXL-Parsing-for-Arduino
Just the MXL Parser can be downloaded here.
Arduino code is in one file but needs to be separated into 2. audio.ino and pitches.h on line 50. Grab that code from GitHub as well.
Stranger Things theme song MXL sample file provided by Riley Apperson on musescore.com
Step 8: Future of the App
Let me start by saying I don't mind helping others with their projects but as far as the app is concerned I don't plan to do much else with it unless another project comes up. With that said if someone else wants to contribute and/or run with it I will gladly be onboard and will contribute where I can.
If you want to contribute go out to GitHub https://github.com/MrRedBeard/DotNet-MXL-Parsing-for-Arduino and get started. Shoot me a message or just start publishing code to a new branch with details on what you changed.
If anything in this Instructable needs to be further explained or corrected just comment below and let me know.
11 Comments
1 year ago on Step 1
Is there a free version that I can download xml files off of?
Question 2 years ago on Introduction
Hi im really interested in your project and wanted to ask you some question that could help me with my school project. If you see this, pls reach out to svs.reis@gmail.com
2 years ago
Hello, how to write this in python. so that i can play sounds using raspberry pi gpio
Question 5 years ago on Step 1
Thank you so much for this tutorial and providing the program you wrote! I had a question.. How did you manage to decompress the .mxl file? Or did you just keep searching until you found an uncompressed version? Thank you!
Answer 5 years ago
c# has a method to decompress PK Zip but you can also use 7Zip to get the uncompressed XML file.
Answer 5 years ago
Thanks! PK Zip worked great. I'll also mention for others out there that the free MuseScore software reads and writes both compressed and uncompressed MusicXML files, so that's a good option.
Answer 5 years ago
Awesome!
5 years ago
if you save the data song in the flash memory (where the program is saved), you will can save longer songs. There are some libraries that make that job.
Reply 5 years ago
I'm not familiar with that. I will do some searches but do you have a specific reference?
5 years ago
musescore.com not accessable
Reply 5 years ago
Thanks. Got it fixed it should have been https://musescore.com/