繁体   English   中英

在music21中将钢琴卷帘转换为MIDI?

[英]Converting piano roll to MIDI in music21?

我正在使用 music21 来处理 MIDI 和 mXML 文件,并将它们转换为我在项目中使用的钢琴卷帘。

我的钢琴卷由 88 维向量序列组成,其中向量中的每个元素代表一个音高。 一个向量是一个时间步长,可以是第 16 次、第 8 次、第 4 次等。 元素可以获得三个值 {0, 1, 2}。 0 表示音符关闭。 1 表示注释已打开。 2 也表示该音符已打开,但它始终跟随 1 - 这就是我区分同一音符的多个按键的方式。 例如,让时间步长为 8th,这两个音高为 C 和 E:

[0 0 0 ... 1 0 0 0 1 ... 0]
[0 0 0 ... 1 0 0 0 1 ... 0]
[0 0 0 ... 2 0 0 0 2 ... 0]
[0 0 0 ... 2 0 0 0 2 ... 0]
[0 0 0 ... 1 0 0 0 0 ... 0]
[0 0 0 ... 1 0 0 0 0 ... 0]

我们看到 C 和 E 同时演奏四分音符,然后再次演奏四分音符,最后以持续四分音符的 C 结束。

现在,我正在为每个音符创建Stream()并在音符出现时填充它。 这给了我 88 个流,当我将其转换为 MIDI 并使用 MuseScore 打开该 MIDI 时,这给我留下了无法读取的混乱局面。

我的问题是,有没有更好的方法可以将这种钢琴卷帘转换为 MIDI? 一些我可以使用的算法或想法将不胜感激。

在我看来,music21 是一个非常好的库,但对于这项工作来说太高级了。 MIDI 中没有流、四分音符或和弦之类的东西——只有消息。 请尝试使用Mido库。 这是示例代码:

from mido import Message, MidiFile, MidiTrack

def stop_note(note, time):
    return Message('note_off', note = note,
                   velocity = 0, time = time)

def start_note(note, time):
    return Message('note_on', note = note,
                   velocity = 127, time = time)

def roll_to_track(roll):
    delta = 0
    # State of the notes in the roll.
    notes = [False] * len(roll[0])
    # MIDI note for first column.
    midi_base = 60
    for row in roll:
        for i, col in enumerate(row):
            note = midi_base + i
            if col == 1:
                if notes[i]:
                    # First stop the ringing note
                    yield stop_note(note, delta)
                    delta = 0
                yield start_note(note, delta)
                delta = 0
                notes[i] = True
            elif col == 0:
                if notes[i]:
                    # Stop the ringing note
                    yield stop_note(note, delta)
                    delta = 0
                notes[i] = False
        # ms per row
        delta += 500

roll = [[0, 0, 0, 1, 0, 0, 0, 1, 0],
        [0, 0, 0, 1, 0, 0, 0, 1, 0],
        [0, 0, 0, 2, 0, 0, 0, 2, 0],
        [0, 1, 0, 2, 0, 0, 0, 2, 0],
        [0, 0, 0, 1, 0, 0, 0, 0, 0],
        [0, 0, 0, 1, 0, 0, 0, 0, 0]]

midi = MidiFile(type = 1)
midi.tracks.append(MidiTrack(roll_to_track(roll)))
midi.save('test.mid')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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