简体   繁体   中英

music21 : given midi input, output correctly-spelled pitches with octave numbers

See Edit below for a work-in-progress MRE

I'm trying to transform the text output of music21 to include octave numbers and correct enharmonic spelling.

As background, I'm a javascript programmer, new to music21 and python.

The following

myMusic = converter.parse("midi")
myMusic.show("text")

yields

Time      Actual output      Desired Output 
{0.0} <music21.note.Note C>      C4
{0.1} <music21.note.Note D#>     E-4
{0.2} <music21.note.Note G>      G4
{0.3} <music21.note.Note G>      G4

Where there are two issues:

  1. How do I include the octave in the text output? (Interestingly, when there are chords, the octave of each note does appear.

  2. The D# should be an Eb , ie, should be interpreted in a tonal context. I'd like to run EnharmonicSimplifier.bestPitches() on the whole parsed midi file to correct this, but from the docs , it appears that it can only be run on a note list .

Am I going about this wrong? Should I be outputting to a different format to get this info? I need timepoints (offset is ok), octave numbers, and correctly-spelled pitches. Maybe I'm missing intermediate processing?

Any guidance appreciated.

EDIT: Work in progress MRE, solves issue 1. (badly?), but not 2.

from music21 import *
environment.set('autoDownload', 'allow')

stream1 = converter.parse("https://upload.wikimedia.org/wikipedia/commons/5/55/MIDI_sample.mid")

for n in stream1.recurse().notes:
  try: 
    print(n.offset, n.nameWithOctave)
  except Exception as e: 
    print(n.offset, *n.pitches)

Yields (excerpted)

237.5 C2
238.0 F#2
238.2 F#2
238.5 C2 F#2
238.7 B-2

1

.show() is nice at a glance when debugging but not ideal for structured output. Have a look at recurse() . music21 has a container ontology: objects are "in" voices, "in" measures, "in" parts, "in" scores. So if you start top-down from a score and want to walk every nested container, just use recurse():

for n in myStream.recurse().notes:
   print(n.offset, ' '.join(p.nameWithOctave for p in n.pitches))

Note properties: http://web.mit.edu/music21/doc/moduleReference/moduleNote.html

2

simplifyMultipleEnharmonics() takes an iterable of pitches (or things that can be converted to pitches, but faster to give it the pitches if you've got 'em). Every Note or Chord object has a pitches attribute, so you can safely call .pitches on Notes or Chords while looping through your parsed file and send that tuple of pitches to simplifyMultipleEnharmonics , along with your Key object.

for n in myStream.recurse().notes:
  closest_key = n.getContextByClass(key.Key)
  n.pitches = pitch.simplifyMultipleEnharmonics(n.pitches, keyContext=closest_key)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM