This is a personal toy/demo/exploration project. I welcome questions or suggestions, but can't commit to anything.
Turn a MIDI file into something that can be played on an Arduino.
Initial Proof of Concept:
- Download a MIDI file
- Open in GarageBand. Try to figure out which track and/or channel you want.
- Read through the MIDI file, output a valid C header file
- Include the header file in your Arduino code and call
play_<song>()
Initial implementation inspired by the reader snippet in the midilib README.
For MIDI files, check out [freemidi.org](There are several sites with MIDI files) and BitMidi or your favorite search engine.
Gems:
-
midilib to parse MIDI files.
-
music to convert a note to Hz
-
MIDI file format. Especially useful to see note mappings.
-
Musical Notes and their Frequencies. Not necessary if you use the
music
gem, above. But handy. -
Super Mario theme songs in Arduino
-
Midi to Arduino. This exists, but I've not looked at the source (if it's even available).
There are many online instructions for attaching speakers to Arduino, just search around 'til you find one that more or less aligns with your kit.
(Stream-of-consciousness notes about MIDI, individual files/songs, etc)
-
The file format seems standard (framing, etc), but actually extracting notes isn't. I've downloaded 3 songs so far and am trying to grab the "closest-to-melody"
Happy
is on track 4 channel 0. All tracks have a single channel.Roar
is on track 1 channel 3. There's one track with multiple channels.JamesBond
is on track 5 channel 3.
-
To find the channel and track:
- Play the tune in GarageBand. Mute all the tracks you don't want to hear to confirm that's the track.
- Look at the starting note sequence (e.g. E1 F#1 F#1 F#1 F#1).
- In
reader.rb
, change 'debug' totrue
. Run the script, send the output to a file or pipe it intoless
. - Search the file for E1, see if you can find an F#1 etc after it.
- Potentially set a breakpoint and inspect
e
to see the track and channel - Once you've isolated the track and channel, set
debug
back tofalse
, runreader.rb
and send the output to the Arduino project directory.
- Put the Arduino code in this repo as well (perhaps a library?)
- Streamline the "find the track/channel" process
- How to play the tunes (arbitrary Hz + duration) on macOS?
- Extract the tempo instead of the bogus
denominator
- Ability to adjust octaves
- Song config file so it's not inline in code