music21 :给定 midi 输入,输出正确拼写的音高和八度数
Posted
技术标签:
【中文标题】music21 :给定 midi 输入,输出正确拼写的音高和八度数【英文标题】:music21 : given midi input, output correctly-spelled pitches with octave numbers 【发布时间】:2021-09-29 22:04:38 【问题描述】:请参阅下面的编辑了解正在进行的 MRE
我正在尝试将music21 的text
输出转换为包含八度音阶数字和正确的等音拼写。
作为背景,我是一名 javascript 程序员,对 music21 和 python 不熟悉。
以下
myMusic = converter.parse("midi")
myMusic.show("text")
产量
Time Actual output Desired Output
0.0 <music21.note.Note C> C4
0.1 <music21.note.Note D#> E-4
0.2 <music21.note.Note G> G4
0.3 <music21.note.Note G> G4
这里有两个问题:
如何在文本输出中包含八度音阶? (有趣的是,当有和弦时,每个音符的八度都会出现。
D#
应该是 Eb
,即应该在音调上下文中解释。我想在整个解析的midi文件上运行EnharmonicSimplifier.bestPitches()
来纠正这个问题,但是from the docs,它似乎只能在note list
上运行。
我做错了吗?我应该输出到不同的格式来获取这些信息吗?我需要时间点(偏移量可以)、八度数和正确拼写的音高。也许我缺少中间处理?
任何指导表示赞赏。
编辑:正在进行的 MRE,解决了问题 1.(严重吗?),但不是 2.
from music21 import *
environment.set('autoDownload', 'allow')
stream1 = converter.parse("https://upload.wikimedia.org/wikipedia/commons/5/55/MIDI_sample.mid")
for n in stream1.recurse().notes:
try:
print(n.offset, n.nameWithOctave)
except Exception as e:
print(n.offset, *n.pitches)
产量(摘录)
237.5 C2
238.0 F#2
238.2 F#2
238.5 C2 F#2
238.7 B-2
【问题讨论】:
【参考方案1】:1
.show()
在调试时一目了然,但不适合结构化输出。看看recurse()
。 music21 有一个容器本体:对象是“in”声音、“in”小节、“in”声部、“in”乐谱。因此,如果您从分数开始自上而下并想要遍历每个嵌套容器,只需使用 recurse():
for n in myStream.recurse().notes:
print(n.offset, ' '.join(p.nameWithOctave for p in n.pitches))
备注属性:http://web.mit.edu/music21/doc/moduleReference/moduleNote.html
2
simplifyMultipleEnharmonics()
接受一个可迭代的音高(或可以转换为音高的东西,但如果你有它们,可以更快地给它音高)。每个 Note 或 Chord 对象都有一个 pitches
属性,因此您可以安全地在 Notes 或 Chords 上调用 .pitches
,同时遍历您的解析文件,并将该音高元组连同您的 Key 对象一起发送到 simplifyMultipleEnharmonics
。
for n in myStream.recurse().notes:
closest_key = n.getContextByClass(key.Key)
n.pitches = pitch.simplifyMultipleEnharmonics(n.pitches, keyContext=closest_key)
【讨论】:
文字解释给了我一个高层次的理解——谢谢! - 但我遇到了实施问题。 (粗体是为了清楚起见,而不是大喊大叫)Re: 1.,nameWithOctave
和弦失败。我添加了except Try ... Exception as e: print(n.offset, *n.pitches)
,它解决了这个问题,但可能不是最好的方法。 Re: 2. 尝试过,但考虑到我第一次接触 Python,太抽象了。您的答案能否包含一个实际为 .mid 文件生成所需输出的代码示例?这是来自***的示例:upload.wikimedia.org/wikipedia/commons/5/55/MIDI_sample.mid
是的,很好的调用,nameWithOctave 只对单个对象有意义,所以我的示例现在打印一个名称列表。以及#2 的代码示例。
我收到 1 的语法错误。将检查 2。当我有机会时,但有道理!
已编辑,抱歉!!
现在说得通了!如果您是 music21 的开发人员,可能值得考虑在文档中包含这样的示例,因为我认为带有时间点的音高是一个非常常见的用例。无论如何,我感谢您的帮助!以上是关于music21 :给定 midi 输入,输出正确拼写的音高和八度数的主要内容,如果未能解决你的问题,请参考以下文章
music21:从平面乐谱中获取 midi 声音的声音/程序/乐器?
使用 music21 显示 Mid 文件中的 midi 音高数字