SLuck
SLuck

Reputation: 601

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

Given a midi file, how can one convert the bar count to time? Generally, how can one easily map the bar count, in entire numbers, to the time in seconds in the song

Upvotes: 0

Views: 445

Answers (1)

SLuck
SLuck

Reputation: 601

Using pretty midi, my solution

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)

If anyone knows a function in pretty midi or music21 that solves the same issue please let me know, couldn't find one. EDIT: There was also an issue with 6/8 beats, I think this covers all edge cases(not 100% sure)

Upvotes: 1

Related Questions