【发布时间】:2019-12-27 14:33:20
【问题描述】:
我目前正在为 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()
【问题讨论】:
标签: python midi markov-chains