将 MIDI 时间转换为小节和节拍

Convert midi time to bars and beats

我正在尝试弄清楚如何将 MIDI 时间转换为小节和节拍。 Here is a sample midi file。如果您下载该文件并在 GarageBand 等程序中打开该文件,您会看到第三首曲目在第一小节中包含四个音符:

现在,如果您在 Python 中加载带有 mido 的文件,您可以在同一轨道中看到前四个音符:

import mido

midi = mido.MidiFile('1079-02.mid')
list(midi.tracks[2])

如果您查看音轨中的事件列表,您会看到音轨中的前四个音符 on/off 事件:

 <message note_on channel=1 note=60 velocity=100 time=0>,
 <message note_on channel=1 note=60 velocity=0 time=480>,
 <message note_on channel=1 note=63 velocity=100 time=0>,
 <message note_on channel=1 note=63 velocity=0 time=480>,
 <message note_on channel=1 note=67 velocity=100 time=0>,
 <message note_on channel=1 note=67 velocity=0 time=480>,
 <message note_on channel=1 note=68 velocity=100 time=0>,
 <message note_on channel=1 note=68 velocity=0 time=480>,

在这里我们可以看到,在此特定文件中,时间值 480 等于四分之一柱。但是,madmomuses 480 as the default ticks per beat value 在它们的一些辅助函数中,所以也许这是一个常见的幻数?但是,在其他文件中,该值不同。

我的问题是:如何将 midi 文件中的时间值转换为小节长度的时间值?例如,对于此文件,我想将第三首曲目的前四个音符中的时间属性表示为 0.25,因为每个音符持续四分之一小节。有谁知道我怎样才能运行这个转换?

作为参考,此文件中的第一首曲目包含以下时间属性:

<meta message smpte_offset frame_rate=24 hours=32 minutes=0 seconds=3 frames=15 sub_frames=0 time=0>,
<meta message time_signature numerator=4 denominator=4 clocks_per_click=24 notated_32nd_notes_per_beat=8 time=0>,
<meta message set_tempo tempo=857143 time=0>,

赞美所有美好和神圣的事物,mido.MidiFile 读取每拍元数据的刻度并将其存储在 mido.MidiFile.ticks_per_beat 中:

import mido

midi = mido.MidiFile('1079-02.mid')
print(midi.ticks_per_beat)

然后您只需将每个音符的持续时间除以每个节拍的滴答声值,就可以根据节拍的持续时间来表示音符!