【日常】Python读取解析xml文件,顺便转换为大疆机甲大师可以演奏的乐谱
最后生成的就是下面视频中的一坨数据,《彩云追月》的简谱,包括89个音符和间隔。
注:上面S1的代码中仅为演示之用使用了time.sleep,如需配合云台/底盘运动等等,需要另外机制。参考此文:#S1歌舞大赛#勃拉姆斯的摇篮曲-乐谱简易录入方法-产品-大疆社区。
后补:已更新代码,配合整体运动的演奏完成。演示如下:
解析XML相关代码如下,用Python标准库的minidom,与HTML的DOM解析类似,也有getElementsByTagName方法。完整源码在此。
声明:(多谢评论指出)下面是在电脑上运行的Python代码,而非机甲上运行的。
...
def 取子元素(节点, tag名):
return 节点.getElementsByTagName(tag名)[0].childNodes[0].nodeValue
# MusicXML文件是网上资源, 需另行下载
xmldoc = minidom.parse('彩云追月.xml')
原音符列表 = xmldoc.getElementsByTagName('note')
...
for 音符 in 原音符列表:
音高 = 音符.getElementsByTagName('pitch')[0]
...
XML中的第一个note节点内容如下:
<note default-x="79.59" default-y="-65.00">
<pitch>
<step>G</step>
<octave>2</octave>
</pitch>
<duration>3</duration>
<voice>1</voice>
<type>quarter</type>
<dot/>
<stem>up</stem>
<lyric number="2" default-x="6.58" default-y="-106.00" relative-y="-1.61">
<syllabic>single</syllabic>
<text>明</text>
</lyric>
<lyric number="3" default-x="6.58" default-y="-132.00">
<syllabic>single</syllabic>
<text>明</text>
</lyric>
</note>
对了,对MusicXML格式熟悉的请教一下:
- 节拍的时间长度。现在是靠duration 总和和曲子长度推出每单位duration的时间长度。比如,上面的《彩云追月》的xml中,duration总和为160,mp3的长度为107秒,演奏了两遍,因此每个duration约为107/2/160(上面的演示中稍慢)。不知XML中有没有相关数据可以算出这个长度?
- 分节。现在输出的是一坨连着的数据,没有任何分节。不知道XML中有没有各节标志可以提取?这样可以让输出的数据更便于组织和调试。
停止无偿服务,详见后文及最后声明【巧妇难为无米之炊】为机甲大师从MusicXML提取乐谱之卡农【如果有其他需要转换的乐曲,可以留言。我找得到相应MusicXML的话,乐于代劳转换。】