Extract tracks from midi files and play on Arduino

http://subsynth.sourceforge.net/midinote2freq.html + http://www.fourmilab.ch/webtools/midicsv/ + Arduino tone() has some interesting applications for really tinny music.

Posted in Arduino | 7 Comments

7 Responses to Extract tracks from midi files and play on Arduino

  1. Guillermo says:

    Hi, actually i am using the serial port to read midi info, but now i want to read midi from a midi file. The only parameters i need are: midi channel, note on/off, and velocity… i think this should be pretty simple, but i do not know the steps i have to do… Could you help to me??
    I need a simple interface to use in Arduino, read sequentially the data from the midi file and extract that parameters…
    Thx!!!

    • dustinandrews says:

      Well you have a couple of choices. There is a lot of info around the web about reading midi right off the wire in Arduino. So you can always output the midi file from a PC and decode it. Assuming that’s no good for some reason I have another approach. You’ll need perl, the programs from this page http://www.fourmilab.ch/webtools/midicsv/ and the code from this page http://subsynth.sourceforge.net/midinote2freq.html if you don’t already know how to convert midi notes to frequencies.

      Using midcsv extract your midi file to a CSV file. Use the perl scripts provided by the author of midcsv to extract the channel(s) you are interested in. Then convert the notes to frequencies and durations for the tone() function. It’s labor intensive, but being able to dump the .midi files to .csv makes it doable.

      • Guillermo says:

        Hi @dustinandrews, thanks for your support!! I’ve just executed midicsv with one of my midi files and i got more or less the whole info i need, but i’m not sure about the time parameter, i mean, for instance some simple coded obtained in the csv file:

        0, 0, Header, 0, 1, 96
        1, 0, Start_track
        1, 0, Title_t, “mat 303 line00″
        1, 0, Time_signature, 4, 2, 36, 8
        1, 0, Time_signature, 4, 2, 36, 8
        1, 0, Note_on_c, 0, 70, 93
        1, 3, Note_off_c, 0, 70, 64
        1, 96, Note_on_c, 0, 69, 46
        1, 156, Note_on_c, 0, 94, 16
        1, 176, Control_c, 0, 3, 0
        1, 176, Note_off_c, 0, 94, 0
        1, 192, Note_off_c, 0, 69, 0
        1, 192, End_track
        0, 0, End_of_file

        Looking the end track number, 192… How many seconds really are?? The rest of the parameters i understand them:

        1, 176, Note_off_c, 0, 94, 0

        1 –> Track number
        176 –> time instant but… How many seconds and milliseconds??
        Note_off –> that note was released in that time
        94 –> note played
        0 –> velocity (being note off, must be zero value)

        For my program, these are the only parameters i need…
        Thanks again!!!

        • dustinandrews says:

          Times are in milliseconds(?) from the start of the track. So for example if note 94 goes on at 156 and then off at 176 it plays for 20ms. Hunt around the midicsv site. He explains the format pretty clearly.

          I wrote a (very naive) perl script to write out the tone() statements for my song.

          Since tone can only play one note at a time and most MIDI files are polyphonic, I had problems finding one with a clean melody to play.

          Do you have a way to deal with overlapping notes? I could add more of the terrible speakers I am using with attiny13′s to power them, but that seems completely silly to me. (So I might)

  2. Guillermo says:

    Hi again!! i’ve been testing midicsv and about the time parameter and really has no sense what we said the last day. In my test i exported midi of 1sec. The result was that end is 176 units of ??? I mean, 176units=1second (1unit=5,681ms). I’ve read documentation in midicsv site and do not explain this so clearly… What’s your opinion??

    About overlapping i think that you could store in a var when a tone played is Note ON (store as many notes get Note ON) and sequentially controlling when every one gets Note OFF, so, in this way you might control independently each note played… sorry about my poor english explaining…

  3. dustinandrews says:

    Guillermo, I understand you perfectly. I had the same problems and you are right the duration is not clear. It’s probably explained someplace in the MIDI protocol.

    In my program I just double the duration in Milliseconds and called it good enough. I think your idea to store the notes and play them sequentially is good. I had the same idea, but didn’t try it yet.

  4. Tim A says:

    I know this is an old thread, but you may find this free Windows app will give more (and in some ways better) data.
    Drag and Drop a Midifile into the main window to produce a CSV file. The application has many options for selecting which data to output.

    http://www.tima.uk.com/midianal.htm

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>