如何在 midi 中将小节数转换为时间? (音乐)

How to convert bar count to time, in midi? (music)

给定一个 midi 文件,如何将小节计数转换为时间? 通常,如何轻松地将小节数(整数)映射到歌曲中的时间(以秒为单位)

使用 pretty midi,我的解决方案

import pretty_midi as pm

def get_bar_to_time_dict(self,song,id):
    def get_numerator_for_sig_change(signature_change,id):
        # since sometime pretty midi count are wierd
        if int(signature_change.numerator)==6 and int(signature_change.denominator)==8:
            # 6/8 goes to 2 for sure
            return 2
        return signature_change.numerator
    # we have to take into account time-signature-changes
    changes = song.time_signature_changes
    beats = song.get_beats()
    bar_to_time_dict = dict()
    # first bar is on first position
    current_beat_index = 0
    current_bar = 1
    bar_to_time_dict[current_bar] = beats[current_beat_index]
    for index_time_sig, _ in enumerate(changes):
        numerator = get_numerator_for_sig_change(changes[index_time_sig],id)
        # keep adding to dictionary until the time signature changes, or we are in the last change, in that case iterate till end of beats
        while index_time_sig == len(changes) - 1 or beats[current_beat_index] < changes[index_time_sig + 1].time:
            # we have to increase in numerator steps, minus 1 for counting logic of natural counting
            current_beat_index += numerator
            if current_beat_index > len(beats) - 1:
                # we labeled all beats so end function
                return bar_to_time_dict
            current_bar += 1
            bar_to_time_dict[current_bar] = beats[current_beat_index]
    return bar_to_time_dict

song = pm.PrettyMIDI('some_midi_file.midi')
get_bar_to_time_dict(song)

如果有人知道 pretty midi 或 music21 中解决相同问题的功能,请告诉我,找不到。 编辑:6/8 节拍也有问题,我认为这涵盖了所有边缘情况(不是 100% 确定)