如何访问 MIDI 文件中的最后一个事件?

Posted

技术标签:

【中文标题】如何访问 MIDI 文件中的最后一个事件?【英文标题】:How can I access the last event in a MIDI file? 【发布时间】:2017-06-28 10:42:12 【问题描述】:

这是我的代码:

import midi
pattern = midi.read_midifile('midifile.mid')

for p in pattern:
    for event, lastEvent in zip(p[1:], p):
        if event.name == 'Note On' and lastEvent.name == 'Note On':
            if event.channel == 1:
                print(event.pitch, lastEvent.pitch)

例如,前 5 个音高是57, 45, 65, 53, 52 意思是我想要

45, 57
65, 45
53, 65
52, 53

但是代码的输出是

45, 57
53, 65
64, 52
50, 62

提前致谢

【问题讨论】:

理论上,zip 是正确的。 print([e.pitch for e in p if e.channel == 1 and e.name == 'Note On']) 的输出是什么? 那将是错误:“TrackNameEvent”对象没有“通道”属性。这是因为只有名为“Note On”或“Note Off”的事件才有频道。 【参考方案1】:

我认为问题在于.name 属性是否不都是'Note on'

这意味着您将事件与前一个事件进行比较,而不是 event.name == 'Note on' 的前一个事件

也许可以试试:

import midi
pattern = midi.read_midifile('midifile.mid')

for p in pattern:
    previous_event = p[0]
    for event in p[1:]:
        if event.name == 'Note on':
            if event.channel == 1:
                print(event.pitch, previous_event.pitch)
                previous_event = event

我想要做的是过滤 p 中的事件,只针对那些带有 event.name == 'Note on' 的事件(尽管我确信有更简单的方法可以通过使用类似 @ 的东西重新定义 p 987654325@

合并这意味着:

import midi
pattern = midi.read_midifile('midifile.mid')

for p in pattern:
    p2 = [event for event in p if event.name == 'Note on'] # maybe should include and event.channel ==1 ?
    for event, lastEvent in zip(p2[1:], p2):
        if event.name == 'Note On' and lastEvent.name == 'Note On':
            if event.channel == 1:
                print(event.pitch, lastEvent.pitch)

【讨论】:

谢谢,第一个解决方案没有返回任何内容,但第二个解决方案返回了所需的内容! 哦,是的,我刚刚意识到第一个 if 条件永远不会满足:P @roncook - 第二种解决方案有点多余,(它检查'note on'两次)并且过滤步骤不包括检查该通道 == 1,所以请注意这一点。

以上是关于如何访问 MIDI 文件中的最后一个事件?的主要内容,如果未能解决你的问题,请参考以下文章

读取 MIDI 文件

如何访问和更改 Pygame.midi?

如何合并轨道中的所有 Midi 事件?

如何在它到达我的 Java 接收器后访问 midi 信息

您如何确定 NAudio 1.7 中的 midi 文件持续时间(以条为单位)?

如何在音轨中的特定点触发事件或回调?