我目前正在为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)不同三角洲时期的节奏变化是否重要?(即)这是因为音乐在不同的地方加速/减速吗?
(3)是否值得为我的生成器实现一个处理速度变化的隐马尔可夫链?
任何帮助都将不胜感激。我对音乐理论知之甚少。
干杯
这是我的解决方案,我是否做错了什么(在下面回复评论)。
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()发布于 2019-12-27 15:14:14
,
发布于 2020-08-30 14:19:51
如果您使用的是0格式文件,MIDI 1.0的规范说明如下:
对于格式为0的文件,
的速度将分散在轨道上,而速度地图阅读器应该忽略中间的事件。
我认为这意味着第一个节奏是要使用的。我已经将具有多个节拍事件的midi文件拖到多个程序中,它们倾向于选择第一个节拍,尽管Ableton对于它有时选择哪个节拍似乎有点随机。
发布于 2022-01-22 20:16:34
我的midi文件也有一个长串的“设定节奏”消息。它们似乎是虚拟消息,只用于它们的“时间”字段值。
时间字段用于在第一轨道的特定时间放置“标记”和"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_trackhttps://stackoverflow.com/questions/59502210
复制相似问题