用musicpy制作音符画
musicpy是国人写的一个不错的库,操作音符挺方便的,运算符重载很到位,只是IDE太寒碜了(×)(建议开发VSCode插件(
今天呢就用它解决了困扰了我一段时间的问题——按几何图形绘制音符画。之前尝试拿鼠标手动画每个音符,到最后就发现画得一点也不像。现在就可以用musicpy自动画出来。
为了让音符顺滑,我改了musicpy.py
源代码,在write()
的定义里把输出MIDI的分辨率设为了1920:
- MyMIDI = MIDIFile(track_number, deinterleave=deinterleave)
+ MyMIDI = MIDIFile(track_number, deinterleave=deinterleave, ticks_per_quarternote=1920)
我使用的代码:
import musicpy
import math
def achord(*notes):
return musicpy.chord(notes)
mychord = None
i = 21
while i <= 108:
j = (math.asin((i - 20) / 44 - 1) - math.asin((i - 21) / 44 - 1)) / (math.pi * 2)
print((i, j))
nc = achord(musicpy.degree_to_note(i)) % (j, j)
if mychord:
mychord += nc
else:
mychord = nc
i += 1
musicpy.write("up.mid", mychord)
以上代码会输出每个音符的音高和时长,并写入上行的半个周期到up.mid。偷了点懒,我把musicpy.degree_to_note(i)
中的i
改成129 - i
,"up.mid"
改成"down.mid"
,得到了下行的半个周期。
用类似的思路可以得到其他图形。注意用&
运算符可以让两个musicpy.chord
同时播放。
2022-09-07 更新
虽然由于不太习惯使用 Python 的缘故,音符画的问题我已经改用其他方法解决了,但刚刚我发现 musicpy 更新了一些内容,添加了更多好的功能。特别是音轨和乐曲类型的加入简直是史诗级加强。
现在输出 MIDI 文件的默认分辨率是 960,基本上足够用来做音符画了,并且如果需要的话也可以在调用 write
或 play
时直接指定需要的输出分辨率:
write("out.mid", mychord, ticks_per_quarternote=384)