为什么有多个 set_tempo 元 MIDI 消息? (以及如何处理)
Why are there multiple set_tempo meta midi messages? (and how to deal)
我目前正在为 midi 文件编写一个解析器,这样我就可以使用马尔可夫链生成我自己的音乐。
我有点困惑为什么每个文件有这么多 set_tempo midi 元信息(在音轨 0 元信息部分)。如果将它们设置为不同的增量时间,我会理解,但有些不是。还有一些似乎为相同的增量时间设置了相同的速度,这似乎奇怪地多余。
这是一个例子...
<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>
所以,
(1) 为什么会有重复?
(2) 不同增量时间的速度变化是否重要? (也就是说,这是因为音乐在各个部分速度 up/slows 变慢
(3) 是否值得为我的生成器实现一个处理速度变化的隐藏马尔可夫链
如有任何帮助,我们将不胜感激。 N.B。我对乐理知之甚少
干杯
这是我的解决方案,我是不是做错了什么(在下面的回答中回复评论)。
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()
- 我想这些复制品只是真实乐器或类似乐器录音的产物。不重要。
- 是的,节奏的变化导致音乐播放速度变慢或变快。
- 您绝对必须尊重所有 速度变化。这是上一句的结果。
如果您使用的是格式 0 文件,MIDI 1.0 规范说明如下:
For a format 0 file, the tempo will be scattered through the track and
the tempo map reader should ignore the intervening events
我认为这意味着要使用第一个速度。我已经将具有多个速度事件的 MIDI 文件拖到多个程序中,它们倾向于选择第一个速度,尽管 Ableton 有时似乎对选择哪个速度有点随机。
我的 midi 文件也有一长串“设定速度”信息。它们似乎是虚拟消息,仅用于其 'time' 字段值。
时间字段用于在第一轨道的特定时间放置“标记”和“key_signature”消息。第一首曲目中没有音符。见下文。第二个和第三个音轨在这个midi文件中有音符(下面没有显示这两个音轨)。
MIDI-MESSAGE KEY:VALUE pairs ...
track_name name:Clair de Lune, time:0
...
time_signature numerator:9, denominator:8, clocks_per_click:12, notated_32nd_notes_per_beat:8, time:0
key_signature key:Db, time:0
set_tempo tempo:600000, time:0
marker text:Andante tres expressif, time:0
set_tempo tempo:1875000, time:240
set_tempo tempo:888889, time:240
set_tempo tempo:821918, time:1680
...
set_tempo tempo:789474, time:240
set_tempo tempo:863309, time:240
set_tempo tempo:909091, time:460
...
set_tempo tempo:1846154, time:740
set_tempo tempo:863309, time:240
marker text:Tempo rubato, time:0
set_tempo tempo:857756, time:40
...
set_tempo tempo:571429, time:40
set_tempo tempo:585366, time:600
set_tempo tempo:535714, time:120
set_tempo tempo:515818, time:480
key_signature key:E, time:240
set_tempo tempo:524017, time:0
marker text:En animant, time:0
set_tempo tempo:481618, time:480
set_tempo tempo:498132, time:240
...
end_of_track
我目前正在为 midi 文件编写一个解析器,这样我就可以使用马尔可夫链生成我自己的音乐。
我有点困惑为什么每个文件有这么多 set_tempo midi 元信息(在音轨 0 元信息部分)。如果将它们设置为不同的增量时间,我会理解,但有些不是。还有一些似乎为相同的增量时间设置了相同的速度,这似乎奇怪地多余。
这是一个例子...
<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>
所以,
(1) 为什么会有重复?
(2) 不同增量时间的速度变化是否重要? (也就是说,这是因为音乐在各个部分速度 up/slows 变慢
(3) 是否值得为我的生成器实现一个处理速度变化的隐藏马尔可夫链
如有任何帮助,我们将不胜感激。 N.B。我对乐理知之甚少
干杯
这是我的解决方案,我是不是做错了什么(在下面的回答中回复评论)。
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()
- 我想这些复制品只是真实乐器或类似乐器录音的产物。不重要。
- 是的,节奏的变化导致音乐播放速度变慢或变快。
- 您绝对必须尊重所有 速度变化。这是上一句的结果。
如果您使用的是格式 0 文件,MIDI 1.0 规范说明如下:
For a format 0 file, the tempo will be scattered through the track and the tempo map reader should ignore the intervening events
我认为这意味着要使用第一个速度。我已经将具有多个速度事件的 MIDI 文件拖到多个程序中,它们倾向于选择第一个速度,尽管 Ableton 有时似乎对选择哪个速度有点随机。
我的 midi 文件也有一长串“设定速度”信息。它们似乎是虚拟消息,仅用于其 'time' 字段值。
时间字段用于在第一轨道的特定时间放置“标记”和“key_signature”消息。第一首曲目中没有音符。见下文。第二个和第三个音轨在这个midi文件中有音符(下面没有显示这两个音轨)。
MIDI-MESSAGE KEY:VALUE pairs ...
track_name name:Clair de Lune, time:0
...
time_signature numerator:9, denominator:8, clocks_per_click:12, notated_32nd_notes_per_beat:8, time:0
key_signature key:Db, time:0
set_tempo tempo:600000, time:0
marker text:Andante tres expressif, time:0
set_tempo tempo:1875000, time:240
set_tempo tempo:888889, time:240
set_tempo tempo:821918, time:1680
...
set_tempo tempo:789474, time:240
set_tempo tempo:863309, time:240
set_tempo tempo:909091, time:460
...
set_tempo tempo:1846154, time:740
set_tempo tempo:863309, time:240
marker text:Tempo rubato, time:0
set_tempo tempo:857756, time:40
...
set_tempo tempo:571429, time:40
set_tempo tempo:585366, time:600
set_tempo tempo:535714, time:120
set_tempo tempo:515818, time:480
key_signature key:E, time:240
set_tempo tempo:524017, time:0
marker text:En animant, time:0
set_tempo tempo:481618, time:480
set_tempo tempo:498132, time:240
...
end_of_track