迭代 Music21 中的所有音符

Iterating over all notes in Music21

我正在尝试为每个笔记获取 table 如下信息:

Pitch - Octave - AbsoluteStart - Duration - Tied - MeterOfMeasure - Quarterlength

对于流中的每个音符(可以包含语音等)。 有没有一种简单的方法可以遍历所有笔记,这样我就可以一个一个地调用属性?

from music21 import *
song = converter.parse('test.xml')

我一直在努力:

 song.show('t')

问题在于缺少关键信息(持续时间等)。

ps:理想情况下,我可以对流进行预处理,以便将 Ties 视为完整的音符持续时间。我相信 Stream.stripTies.

可以做到这一点

我正在测试的 musicXML 文件是:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise>
  <identification>
    <creator type="composer">Brennan Becker</creator>
    <encoding>
      <software>MuseScore 2.0.3.1</software>
      <encoding-date>2017-07-13</encoding-date>
      <supports element="accidental" type="yes"/>
      <supports element="beam" type="yes"/>
      <supports element="print" attribute="new-page" type="yes" value="yes"/>
      <supports element="print" attribute="new-system" type="yes" value="yes"/>
      <supports element="stem" type="yes"/>
      </encoding>
    <source>http://musescore.com/score/2383771</source>
    </identification>
  <defaults>
    <scaling>
      <millimeters>7.05556</millimeters>
      <tenths>40</tenths>
      </scaling>
    <page-layout>
      <page-height>1584</page-height>
      <page-width>1224</page-width>
      <page-margins type="even">
        <left-margin>56.6929</left-margin>
        <right-margin>56.6929</right-margin>
        <top-margin>56.6929</top-margin>
        <bottom-margin>113.386</bottom-margin>
        </page-margins>
      <page-margins type="odd">
        <left-margin>56.6929</left-margin>
        <right-margin>56.6929</right-margin>
        <top-margin>56.6929</top-margin>
        <bottom-margin>113.386</bottom-margin>
        </page-margins>
      </page-layout>
    <word-font font-family="FreeSerif" font-size="10"/>
    <lyric-font font-family="FreeSerif" font-size="11"/>
    </defaults>
  <credit page="1">
    <credit-words default-x="1167.31" default-y="1402.31" justify="right" valign="bottom" font-size="12">Brennan Becker</credit-words>
    </credit>
  <credit page="1">
    <credit-words default-x="612" default-y="1527.31" justify="center" valign="top" font-size="48">Test</credit-words>
    </credit>
  <part-list>
    <score-part id="P1">
      <part-name>Piano</part-name>
      <part-abbreviation>Pno.</part-abbreviation>
      <score-instrument id="P1-I1">
        <instrument-name>Piano</instrument-name>
        </score-instrument>
      <midi-device id="P1-I1" port="1"></midi-device>
      <midi-instrument id="P1-I1">
        <midi-channel>1</midi-channel>
        <midi-program>1</midi-program>
        <volume>78.7402</volume>
        <pan>0</pan>
        </midi-instrument>
      </score-part>
    </part-list>
  <part id="P1">
    <measure number="1" width="641.30">
      <print>
        <system-layout>
          <system-margins>
            <left-margin>21.00</left-margin>
            <right-margin>0.00</right-margin>
            </system-margins>
          <top-system-distance>195.00</top-system-distance>
          </system-layout>
        <staff-layout number="2">
          <staff-distance>65.00</staff-distance>
          </staff-layout>
        </print>
      <attributes>
        <divisions>4</divisions>
        <key>
          <fifths>1</fifths>
          </key>
        <time>
          <beats>2</beats>
          <beat-type>4</beat-type>
          </time>
        <staves>2</staves>
        <clef number="1">
          <sign>G</sign>
          <line>2</line>
          </clef>
        <clef number="2">
          <sign>F</sign>
          <line>4</line>
          </clef>
        </attributes>
      <direction placement="above">
        <direction-type>
          <metronome parentheses="no">
            <beat-unit>quarter</beat-unit>
            <per-minute>100</per-minute>
            </metronome>
          </direction-type>
        <staff>1</staff>
        <sound tempo="100"/>
        </direction>
      <note>
        <rest/>
        <duration>8</duration>
        <voice>1</voice>
        <staff>1</staff>
        </note>
      <backup>
        <duration>8</duration>
        </backup>
      <direction placement="below">
        <direction-type>
          <pedal type="start" line="yes"/>
          </direction-type>
        <staff>2</staff>
        </direction>
      <note default-x="88.37" default-y="-130.00">
        <pitch>
          <step>C</step>
          <octave>3</octave>
          </pitch>
        <duration>1</duration>
        <voice>5</voice>
        <type>16th</type>
        <stem>down</stem>
        <staff>2</staff>
        <beam number="1">begin</beam>
        <beam number="2">begin</beam>
        </note>
      <note default-x="174.47" default-y="-125.00">
        <pitch>
          <step>D</step>
          <octave>3</octave>
          </pitch>
        <duration>1</duration>
        <voice>5</voice>
        <type>16th</type>
        <stem>down</stem>
        <staff>2</staff>
        <beam number="1">continue</beam>
        <beam number="2">continue</beam>
        </note>
      <note default-x="260.56" default-y="-120.00">
        <pitch>
          <step>E</step>
          <octave>3</octave>
          </pitch>
        <duration>1</duration>
        <voice>5</voice>
        <type>16th</type>
        <stem>down</stem>
        <staff>2</staff>
        <beam number="1">continue</beam>
        <beam number="2">continue</beam>
        </note>
      <note default-x="346.66" default-y="-115.00">
        <pitch>
          <step>F</step>
          <alter>1</alter>
          <octave>3</octave>
          </pitch>
        <duration>1</duration>
        <voice>5</voice>
        <type>16th</type>
        <stem>down</stem>
        <staff>2</staff>
        <beam number="1">end</beam>
        <beam number="2">end</beam>
        </note>
      <note default-x="432.76" default-y="-110.00">
        <pitch>
          <step>G</step>
          <octave>3</octave>
          </pitch>
        <duration>4</duration>
        <voice>5</voice>
        <type>quarter</type>
        <stem>down</stem>
        <staff>2</staff>
        </note>
      <direction placement="below">
        <direction-type>
          <pedal type="stop" line="yes"/>
          </direction-type>
        <staff>2</staff>
        </direction>
      </measure>
    <measure number="2" width="448.31">
      <barline location="left">
        <bar-style>heavy-light</bar-style>
        <repeat direction="forward"/>
        </barline>
      <attributes>
        <time>
          <beats>3</beats>
          <beat-type>8</beat-type>
          </time>
        </attributes>
      <direction placement="above">
        <direction-type>
          <metronome parentheses="no">
            <beat-unit>quarter</beat-unit>
            <per-minute>80</per-minute>
            </metronome>
          </direction-type>
        <staff>1</staff>
        <sound tempo="79.9998"/>
        </direction>
      <note default-x="37.50" default-y="-25.00">
        <pitch>
          <step>A</step>
          <octave>4</octave>
          </pitch>
        <duration>2</duration>
        <tie type="start"/>
        <voice>1</voice>
        <type>eighth</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">begin</beam>
        <notations>
          <tied type="start"/>
          </notations>
        </note>
      <note default-x="37.50" default-y="-5.00">
        <chord/>
        <pitch>
          <step>E</step>
          <octave>5</octave>
          </pitch>
        <duration>2</duration>
        <voice>1</voice>
        <type>eighth</type>
        <stem>down</stem>
        <staff>1</staff>
        </note>
      <note default-x="168.06" default-y="-5.00">
        <pitch>
          <step>E</step>
          <octave>5</octave>
          </pitch>
        <duration>2</duration>
        <voice>1</voice>
        <type>eighth</type>
        <stem>down</stem>
        <staff>1</staff>
        <beam number="1">end</beam>
        </note>
      <note default-x="298.62" default-y="-25.00">
        <pitch>
          <step>A</step>
          <octave>4</octave>
          </pitch>
        <duration>2</duration>
        <tie type="stop"/>
        <voice>1</voice>
        <type>eighth</type>
        <stem>down</stem>
        <staff>1</staff>
        <notations>
          <tied type="stop"/>
          </notations>
        </note>
      <note default-x="298.62" default-y="-10.00">
        <chord/>
        <pitch>
          <step>D</step>
          <octave>5</octave>
          </pitch>
        <duration>2</duration>
        <voice>1</voice>
        <type>eighth</type>
        <stem>down</stem>
        <staff>1</staff>
        </note>
      <backup>
        <duration>6</duration>
        </backup>
      <direction placement="below">
        <direction-type>
          <pedal type="start" line="yes"/>
          </direction-type>
        <staff>2</staff>
        </direction>
      <note default-x="37.50" default-y="-110.00">
        <pitch>
          <step>G</step>
          <octave>3</octave>
          </pitch>
        <duration>6</duration>
        <voice>5</voice>
        <type>quarter</type>
        <dot/>
        <stem>down</stem>
        <staff>2</staff>
        </note>
      <direction placement="below">
        <direction-type>
          <pedal type="stop" line="yes"/>
          </direction-type>
        <staff>2</staff>
        </direction>
      <barline location="right">
        <bar-style>light-heavy</bar-style>
        <repeat direction="backward"/>
        </barline>
      </measure>
    </part>
  </score-partwise>

我迭代所有音符并取回音乐属性的解决方案:

import music21 as m

song = m.converter.parse('test.xml')
# process the ties
song = song.stripTies()

# unfold repetitions
i = 0;
for a in song:
    if a.isStream:
        e = m.repeat.Expander(a)
        s2 = e.process()
        timing = s2.secondsMap
        song[i] = s2
    i += 1;

# todo: add note onsets

def getMusicProperties(x):
    s = '';
    t='';
    s = str(x.pitch) + ", " + str(x.duration.type) + ", " + str(x.duration.quarterLength);
    s += ", "
    if x.tie != None:
        t = x.tie.type;
    s += t + ", " + str(x.pitch.ps) + ", " + str(x.octave); # + str(x.seconds)  # x.seconds not always there  
    return s


print('pitch, duration_string, duration, tie, midi pitch, octave')
for a in song.recurse().notes:

    if (a.isNote):
        x = a;
        s = getMusicProperties(x);
        print(s);

    if (a.isChord):
        for x in a._notes:
            s = getMusicProperties(x);
            print(s);

print("Done.")

要获得绝对音符起音,我们可以使用:

for el in song.recurse():
     totalOffset = el.getOffsetInHierarchy(song)