【问题标题】:How do I read midi / musicxml files in music21 for solo piano where there can be multiple notes in a voice simultaneously?如何在独奏钢琴的 music21 中读取 midi / musicxml 文件,其中一个声音可以同时有多个音符?
【发布时间】:2021-10-23 03:16:12
【问题描述】:

我已经编写了一个 python 脚本来处理带有 music21 的 midi 文件并再次编写一个 midi 文件。如果独奏钢琴在某种意义上是“简单的”,即没有多个音高/音符在一个声音中同时演奏,则此方法有效。

https://github.com/githubuser1983/algorithmic_python_music/blob/main/12RootOf2.py

上面的相关部分是:

def parseMidi(fp,part=0):
    import os
    from music21 import converter
    print(fp)
    score = converter.parse(fp,quantizePost=True)
    print(list(score.elements[0].notesAndRests))
    #print([e.partAbbreviation for e in score.elements][0])
    from music21 import chord
    durs = []
    ll0 = []
    vols = []
    isPauses = []
    for p in score.elements[part].notesAndRests:
        #print(p)
        if type(p)==chord.Chord:
            pitches = median([e.pitch.midi-21 for e in p]) # todo: think about chords
            vol = median([e.volume.velocity for e in p])
            dur = float(p.duration.quarterLength)
            #print(pitches)
            ll0.append(pitches)
            isPause = False
        elif (p.name=="rest"):
            pitches = 89
            vol = 1
            dur = float(p.duration.quarterLength)
            ll0.append(pitches)
            isPause = True
        else:
            pitches = p.pitch.midi-21
            vol = p.volume.velocity
            dur = float(p.duration.quarterLength)
            ll0.append(pitches)
            isPause =  False
        durs.append(dur/(12*4.0))
        vols.append(vol*1.0/127.0)
        isPauses.append(isPause)
            #print(p.name,p.octave,p.duration.quarterLength)
    #print(dir(score)) 
    #print(ll0)
    #print(durs)
    return ll0,durs,vols,isPauses

另一种选择是读取musicxml 而不是midi。我需要让算法工作的是每个声音的音符列表 =(音高、持续时间、音量、isPause)。

感谢您的帮助。

【问题讨论】:

  • Music21 与 MIDI 一起工作,但在 musicxml 方面表现出色——除了下面的答案和 cmets,请考虑尽快将文件更改为 musicxml。 Musescore 在将 MIDI 批量转换为 musicxml 方面做得很好。
  • @michaelscottcuthbert 我将如何在 musicxml 中做到这一点?

标签: parsing midi music21 musicxml


【解决方案1】:

目前,在music21 中,stream.Voice 对象更多是一个展示概念,而不是一个逻辑概念。声音和和弦都是同时的,这就是 MIDI 文件所捕获的全部内容。 (事实上​​,在本周发布的第 7 版中有pending changes,除了制作小节外,它还可以从 MIDI 文件中制作更少的声音和更多的和弦。如果混响或录制的演奏中存在小的重叠,您可以获得雕刻师永远不会在乐谱中打印的“声音”。)

在你的情况下,我可能只需要 .flatPart 对象来摆脱 Voices(最终在 v.7 中的测量),然后运行 ​​chordify() 如果你想确保有没有重叠。否则,如果您根本不需要和弦,您仍然可以获取 chordify() 的输出并找到每个和弦的根。几种可能性都取决于您的来源。

【讨论】:

  • Jacob 所说的 - (a) 在您的每个语音脚本之前运行 chordify()。或将score.elements[part].notesAndRests 替换为score.elements[part].recurse().notesAndRests -- 感谢您使用music21!
  • @MichaelScottCuthbert:谢谢,成功了!
猜你喜欢
  • 1970-01-01
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多