3

I'm trying to use music21 to convert multi-track midi files into array of notes and durations per each track.

For example, given a midi file test.mid with 16 tracks in it,

I would like to get 16 arrays of tuples, consisting of (pitch, duration (plus maybe position of the note)).

Documentation for music21 is rather difficult to follow, and I would really appreciate any help on this..

ytrewq
  • 3,670
  • 9
  • 42
  • 71

1 Answers1

3

There is more than one way to do this in music21, so this is just one simple way. Note that the durational value is expressed as a float, such that a quarter note equals 1.0, a half note equals 2.0, etc.:

import music21
from music21 import *

piece = converter.parse("full_path_to_piece.midi")
all_parts = []
for part in piece.parts:
  part_tuples = []
  for event in part:
    for y, in event.contextSites():
      if y[0] is part:
        offset = y[1]
    if getattr(event, 'isNote', None) and event.isNote:
      part_tuples.append((event.nameWithOctave, event.quarterLength, offset))
    if getattr(event, 'isRest', None) and event.isRest:
      part_tuples.append(('Rest', event.quarterLength, offset))
  all_parts.append(part_tuples)

An alternative solution would be to use the vis-framework, which accesses music files in symbolic notation via music21 and stores the information in pandas dataframes. You can do this:

pip install vis-framework

Another solution would be to use Humdrum instead of music21.

Alex
  • 2,154
  • 3
  • 26
  • 49
  • thank you so much! By "position of note", I meant the timestamp of the note, so that I can reconstruct the midi file after manipulating the arrays. Is that also a part of event field? Also, what did you mean by "include detection of rests"? – ytrewq Dec 08 '16 at 09:41
  • By timestamp do you mean the temporal position from the beginning of the piece? In music21 parlance (and VIS parlance) this is often referred to as an event's "offset". If that's what you mean let me know and I'll edit my answer because there is an "offset" attribute, but it's not as simple to use as you might expect. What I meant about including rests is that, the code in my answer currently skips over rests. Did you want to know when you come across a rest as well? – Alex Dec 08 '16 at 15:31
  • Also note that music21 has a Google group which is a very good source of information about the software, and I believe is also the preferred location for music21 questions. https://groups.google.com/forum/?hl=en#!forum/music21list – Alex Dec 08 '16 at 15:33
  • Thanx! Yes, I did mean the temporal position of the notes from the beginning of the piece. I'm still not sure what you mean by rests, but will be grateful if you could extend the answer to include it! – ytrewq Dec 09 '16 at 03:41
  • The edits should detect rests too, and add a third variable to the tuple which is its temporal position from the beginning of the piece. – Alex Dec 11 '16 at 12:08