Skip to content
Advertisement

Why are there multiple set_tempo meta midi messages? (and how to deal)

I am currently writing a parser for midi files so I can generate my own music using a Markov chain.

I’m a bit confused as to why there are so many set_tempo midi meta messages (in the track 0 meta message section) of each file. I would understand if they were set to different delta time, but some are not. Also some seem to set the same tempo for the same delta time which seems weirdly superfluous.

Here’s an example…

<meta message set_tempo tempo=857139 time=0>
<meta message set_tempo tempo=857139 time=0>
<meta message set_tempo tempo=857632 time=0>
<meta message set_tempo tempo=857632 time=180224>
<meta message set_tempo tempo=895896 time=438>
<meta message set_tempo tempo=930917 time=438>
<meta message set_tempo tempo=967865 time=438>
<meta message set_tempo tempo=1008868 time=438>
<meta message set_tempo tempo=1053514 time=438>
<meta message set_tempo tempo=1101084 time=438>
<meta message set_tempo tempo=2403785 time=438>
<meta message set_tempo tempo=857632 time=1030>
<meta message set_tempo tempo=895896 time=292>
<meta message set_tempo tempo=930917 time=292>
<meta message set_tempo tempo=967865 time=292>
<meta message set_tempo tempo=1008868 time=292>
<meta message set_tempo tempo=1053514 time=292>
<meta message set_tempo tempo=1101084 time=292>
<meta message set_tempo tempo=2403785 time=292>
<meta message set_tempo tempo=2403785 time=1028>
<meta message end_of_track time=5119>

so,

(1) why are there duplicates?
(2) are the changes in tempo at different delta times important ? (ie. is this because the music speeds up/slows down in various parts
(3) Is it worth implementing a hidden markov chain that deals with tempo changes for my generator

Any help at all would be appreciated. N.B. I know very little about music theory

Cheers

Here is my solution, have I done something wrong (reply to comment in answer below).

import mido

all_mid = [' (Yiruma).mid']

# add time from start to message data (for sorting and adjusted delta time purposes)
def add_cumulative_time(msg, current_time):
    add_on = msg.time
    current_time += add_on
    return current_time, add_on

def clean(mid, all_messages):  # for each track (then message) do the following
    msgwithtempos = []
    for i, track in enumerate(mid.tracks):
        current_time = 0
        for msg in track:
            current_time = add_cumulative_time(msg, current_time)[0]
            allowed_types = ["note_on", "note_off", "program_change", "set_tempo"] 
            if msg.type in allowed_types:
                all_messages.append([msg, current_time])
            else:
                pass
    return all_messages, msgwithtempos


def main():  # for each midi file do the following
    all_lists = []
    for i in range(0, len(all_mid)):
        all_messages = []
        mid = mido.MidiFile(all_mid[i])
        ticksperbeat = mid.ticks_per_beat
        all_messages, msgwithtempos = clean(mid, all_messages)
        final_messages = all_messages + msgwithtempos
        final_messages = sorted(final_messages, key=lambda x: x[1])
        all_lists += final_messages
    for i, item in enumerate(all_lists):
        if all_lists[i][0].type == "set_tempo":
            while all_lists[i+1][0].type == "set_tempo": # talk about this as an error with i-1 being logical but not working
                all_lists.pop(i+1)
    return all_lists, ticksperbeat


if __name__ == '__main__':
    main()

Advertisement

Answer

  1. I suppose these duplicates are just artifacts of recording from real instrument or something like this. It’s not important.
  2. Yes, changes of tempo cause music is playing slower or faster.
  3. You absolutely must respect all tempo changes. That follows from previous sentence.
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement