Music21:获取音符的曲目索引

Posted

技术标签:

【中文标题】Music21:获取音符的曲目索引【英文标题】:Music21: get track index of a note 【发布时间】:2020-06-11 20:26:06 【问题描述】:

我有一个multi-track midi file,我正在用 music21 阅读:

import music21

f = music21.midi.MidiFile()
f.open('1079-02.mid')
f.read()
stream = music21.midi.translate.midiFileToStream(f).flat
note_filter = music21.stream.filters.ClassFilter('Note')
for n in stream.recurse().addFilter(note_filter):
  offset = n.offset # offset from song start in beats
  note = n.pitch # letter of the note, e.g. C4, F5
  midi_note = n.pitch.midi # midi number of the pitch, e.g. 60, 72
  duration = n.duration # duration of the note in beats
  instrument = n.activeSite.getInstrument() # instrument voice

我想弄清楚这个流中的每个音符属于哪个音轨。例如。当我在 GarageBand 中打开文件时,音符被组织成轨道:

mido 中,每个MidiFile 都有一个tracks 属性,其中包含每个轨道的一个音符列表。

有没有办法让music21 达到同样的效果?任何帮助将不胜感激!

【问题讨论】:

你看到***.com/a/41019546/152016了吗? 我没见过!我想保留流方法,因为我想将所有轨道合并到一个流中,所以时间属性是绝对的而不是相对的。 f.tracks 存在并包含每个轨道的一个条目。但是时间是基于给定轨道内的相对偏移量... web.mit.edu/music21/doc/moduleReference/… 难道你不能只改变曲目的数据并在父midi对象中调用这个方法吗? 嗯,你是什么意思? 【参考方案1】:

音乐曲目被解析为单独的 stream.Part 对象,因此如果您避免将其展平,您可以直接浏览您生成的 stream.Score 的部分(这里,我刚刚使用 converter.parse() 生成了一个流:

s = converter.parse('1079-02.mid')
for part in s.parts:
    for note in part.notes:
       print("I WAS IN PART ", part)

或查找包含部分:

s = converter.parse('1079-02.mid')
for note in s.recurse().notes:
    part = note.sites.getObjByClass('Part')
    print("I WAS IN PART ", part)

我怀疑你真的需要压平任何东西。祝你好运!

【讨论】:

以上是关于Music21:获取音符的曲目索引的主要内容,如果未能解决你的问题,请参考以下文章

四分之一时长小于 0.25 的 Music21 音符?

music21:写入midi文件后和弦转音符?

保存到 MIDI 文件时,Music21 一次播放所有音符

如何使用 Python 中的长笛乐器从音符制作 MIDI 文件(music21 库)

music21:从平面乐谱中获取 midi 声音的声音/程序/乐器?

Music21 Python 库将只输出钢琴声音