【发布时间】:2020-11-26 18:28:13
【问题描述】:
我正在研究 Midi 文件规范,现在我正在测试它,如果由 Timidity 播放,它可以正常工作,但对于 Garage Band、OS X(输出不播放)和 Synthesia 都已损坏。
head = '4d 54 68 64'
chunklen = '00 00 00 06'
mformat = '00 01'
ntracks = '00 02'
tickdiv = '00 60'
trackid = '4d 54 72 6b'
eot = '00 ff 2f 00'
makeheader = lambda : " ".join([head,chunklen,mformat,ntracks,tickdiv])
def chunklencalc(notes):
chlen = format(len(notes)*4, 'x')
return " ".join([x for x in re.compile('(.{2})').split("00000000"[len(chlen):] + chlen) if x != ''])
maketrack = lambda notes : " ".join([trackid, chunklencalc(notes)] + notes + [eot])
makestandardquarter = lambda root : f"00 90 {root} 64 60 80 {root} 64"
def createMidi(filename,bytelist):
with open(filename, 'wb') as f:
for e in bytelist.split(" "):
f.write(bytes.fromhex(e))
filename = 'firsttest.mid'
head = makeheader()
notes1 =[
makestandardquarter('3c'),
makestandardquarter('3c'),
makestandardquarter('3c'),
makestandardquarter('3c'),
makestandardquarter('3c'),
makestandardquarter('3c'),
makestandardquarter('3c'),
makestandardquarter('3c'),
]
notes2 =[
makestandardquarter('40'),
makestandardquarter('40'),
makestandardquarter('40'),
makestandardquarter('40'),
makestandardquarter('40'),
makestandardquarter('40'),
makestandardquarter('40'),
makestandardquarter('40'),
]
track1 = maketrack(notes1)
track2 = maketrack(notes2)
createMidi(filename, " ".join([head, track1,track2]))
我希望在两个曲目中出现一系列季度,但只有前四个曲目出现在一个曲目中。
【问题讨论】:
-
你检查过文件是否有正确的字节序吗?查看规范应该是小端。
-
我担心 chunklen 的计算和创建便笺的函数,因为在之前的测试中,我手动计算并硬编码了便笺,它适用于每个系统。此外,只处理了一半的笔记似乎很奇怪。最后我不熟悉这种低级的东西,感谢任何帮助。
-
同样在 chunklen 函数中,我认为 eot 段(4 字节)应该是 +4,但胆怯不会抱怨。
-
为了处理字节,我发现使用 struct python 模块很有用:docs.python.org/3/library/struct.html 请记住,您可以像这样定义二进制字符串:
b"\x00"