先说结论
MIDI 文件记录的是一次演奏:按了哪个键、什么时候按、按多重、按多久。它的音符没有升降号、声部、书面休止符或符杠,文件里也常常没有调号,所以 MuseScore 只能去猜,而音符偏离节拍网格时,它猜得最离谱。在 12 段吉他转谱上,我们最早的转换器一个调号也没写,还藏起了所有休止符;同样的音符先对齐到十六分音符网格、使用固定速度、在每条音轨写入调号,再交给 MuseScore Studio 4.7.5 的导入器,12 份里有 10 份调号正确,所有休止符也都显示了出来。MuseScore Studio 4 没有 MIDI 导入面板,所以这些修正要么写进 MIDI 文件,要么写进命令行用的选项文件。
MIDI 文件不存哪些信息?
读谱所需的大部分信息,它都不存。一个 MIDI 音符就是 0 到 127 之间的一个键号加一个力度值,在音符开始时发送一次,结束时再发送一次(MIDI 协会)。63 号音既是 D♯ 也是 E♭,该写哪个取决于调性,而音符本身并不说明。标准 MIDI 文件可以用元事件加入速度、拍号和调号,但声部、休止符、符杠和连音都没有标准的存放位置。休止符只是一段空隙,音长也只是 tick 数,而不是书面时值。
音频转 MIDI 工具还会带来第二个问题:它们的时间来自录音,音符很少正好落在拍点上。ScoreStarling 使用的 Spotify Basic Pitch 会按你给定的速度,把所有音符写进同一个 Electric Piano 1(电钢琴 1)声部,而且不写调号(note_creation.py)。要把它变成乐谱,就得为每个音符选定音名写法、书面时值、声部和谱表。每个转换器都得做这些选择,区别只在于做得好不好。
简单的转换器把 12 段吉他转谱弄成了什么样
我们最早的记谱环节,是一个基于 music21 库自己写的转换器。我们把公开数据集 GuitarSet 中 12 段录音经 Basic Pitch 转出的 MIDI 交给它,同时提供每段录音的速度,再由 Verovio 原样排版它写出的内容。逐一检查这 12 份乐谱,我们发现:
- 所有乐谱都看不到休止符:music21 的 MusicXML 导出器默认用隐藏的休止符填补空隙(m21ToXml.py)。
- 所有乐谱都没有调号。E 大调的曲子一个升号都没有;一段 C 大调伴奏的 431 个书面音符里,有 153 个带着多余的还原号(对应 421 个 MIDI 音符,有些被拆开后用延音线相连)。
- 音名写法只看音符编号。MIDI 63 号音一律写成 E♭,即使在本该写 D♯ 的 E 大调里也是如此;在一首 G♭ 大调的曲子里,49 个调内音中有 30 个写错了。
- 一行谱表上最多五个声部。音符的起点和终点各自对齐到最近的十六分音符,于是下一个音弹出时仍在振动的那根弦,就逼出了另一个声部,还配上了相应的附点和延音线。
- 吉他被写成了钢琴:12 份乐谱中有 10 份用钢琴大谱表,另外 2 份用低音谱号,没有一份用吉他谱号,因为 Basic Pitch 把所有音符都标成了 Electric Piano(电钢琴)。
2026年10月7日,我们用同一批保存下来的 MIDI 文件重新运行了这个转换器,得到的数字完全一样。
问题不在音乐字体。Verovio 和它的 Leipzig 字体只是照着 MusicXML 画;错的是 MusicXML 本身。
前后对比:换用 MuseScore Studio 的导入器
我们先看了开源的替代方案:partitura 能处理调性、音名写法和声部,但没有量化器,也不写休止符;我们找到的其他研究工具,要么只支持钢琴,要么没有声明许可证、仅限非商业用途,或者尚未发布。于是我们把这项工作交给了 MuseScore Studio 4.7.5 的 MIDI 导入器,以独立程序的方式运行。同样的 12 段录音、同样的 Basic Pitch 音符、同样的给定速度,按下文的方法预处理,2026年10月2日在一台 Mac 上测得:
| 指标 | music21 转换器 | MuseScore 导入器 |
|---|---|---|
| 调号与标注一致 | 0/12 | 10/12 |
| 调内音写法与调性相悖 | 2,703 个中 322 个 | 3,213 个中 0 个 |
| 每个书面音符的变音记号数 | 0.53 | 0.06 |
| 可见的休止符 | 1,626 个中 0 个 | 全部 988 个 |
| 单行谱表最多声部数 | 5 | 2 |
| 所有 MIDI 音符均写出 | 12/12 | 12/12 |
| 4/4 拍、使用给定速度 | 12/12 | 12/12 |
两边的书面音符总数不同,是因为 MuseScore 用延音线跨拍、跨小节线连接音符的方式不一样。两个错的调都和标注差一个五度:G♭ 大调的曲子写成了 D♭ 大调,E 大调的写成了 B 大调。文件里没有我们估出的调时,MuseScore 自己猜的调只对了 5 份(2026年10月7日重测);正是把估计结果写进文件,才把它提高到 10 份。导入器处理每段录音用时 1.2–4.3 秒,平均 2.3 秒。
MuseScore 为什么会重新猜速度、拍号和调?
因为在它看来,没量化的 MIDI 像是一段现场演奏。导入器会检查落在拍点附近的音符,如果其中正好从拍点开始的不到 60%,它就把文件当作真人演奏(importmidi_quant.cpp)。接着它会运行自己的节拍追踪,选定拍号,并拉伸音符的时间去贴合它找到的拍子。MuseScore 的旧版手册说,这种模式是拿准确性换可读性,对没有对齐的文件默认开启。
调性另有一条规则。只要有任何一条非鼓音轨缺少调号,或者文件被判定为演奏,导入器就会根据音符估计调性(importmidi_key.cpp)。所以只在速度音轨里写调号是不够的,每条有音符的音轨都要有。直接导入 Basic Pitch 的原始 MIDI 时,我们看到拍号、速度和调全都被重新猜了一遍,哪怕已经把“真人演奏”选项设为 false。
导入前该怎么处理 MIDI?
能在 MIDI 文件里定下的记谱决定,就在 MuseScore 看到它之前定好。我们对每份转谱都会这样做:
- 使用一个固定的速度。ScoreStarling 会用你设定的 BPM,或从录音中检测出的速度;在 DAW(编曲软件)里,可以跟着节拍器录音,或者把工程速度调到与这条录音一致。
- 把每个音符的起点和终点都移到网格上,网格精度就是你想读到的最短时值。本文 10月2日的测试用的是 4/4 拍下的十六分音符。所有音符都在网格上时,MuseScore 会把文件当作写好的乐谱来读,而不是当作演奏。
- 把速度和拍号放在第一条音轨里,每条有音符的音轨都写上调号。我们用 music21 的 Krumhansl–Schmuckler 调性识别算法根据音符估计调性;如果你知道真正的调,就直接用它。
- 给每条音轨设上真实的乐器。MuseScore 会根据 General MIDI 音色来选择谱表和谱号:仍标为 Electric Piano 的吉他会被放到钢琴大谱表上,而设为尼龙弦吉他音色时,会用下方带 8 的高音谱号。
- 注意同音反复。如果同一个音在一个网格单位内弹了两下,对齐后两次起音会合并成一次;我们会把第二次往后挪一个三十二分音符。
MuseScore 导入该用哪些设置?
MuseScore Studio 4 没有可以设置这些选项的导入面板。它的手册说 MIDI 导入面板“目前尚未实现”,要求恢复它的 GitHub issue(#11918,2022年6月提出)在我们 2026年10月3日查看时仍未关闭。在软件里,唯一与量化有关的设置是导入 MIDI 文件时的最短音符时值,位于“首选项 → 导入”(Preferences → Import)。
导入器仍会从命令行里用 -M 传入的文件读取主要选项,手册的命令行页面附有一个示例。下面是 10月2日测试用的文件;现在 ScoreStarling 会把旋律写在一个声部里(VoiceCount 设为 0),并在第一小节是弱起小节时打开 RecognizePickupBar:
<?xml version="1.0" encoding="UTF-8"?>
<MidiOptions>
<QuantValue>2</QuantValue>
<VoiceCount>1</VoiceCount>
<Duplets>false</Duplets>
<Triplets>false</Triplets>
<Quadruplets>false</Quadruplets>
<Quintuplets>false</Quintuplets>
<Septuplets>false</Septuplets>
<Nonuplets>false</Nonuplets>
<HumanPerformance>false</HumanPerformance>
<MeasureCount2xLess>false</MeasureCount2xLess>
<SplitStaff>false</SplitStaff>
<ClefChanges>false</ClefChanges>
<SimplifyDurations>true</SimplifyDurations>
<ShowStaccato>false</ShowStaccato>
<DottedNotes>true</DottedNotes>
<RecognizePickupBar>false</RecognizePickupBar>
<Swing>0</Swing>
</MidiOptions>
然后进行转换,输出文件用 MusicXML 扩展名:
mscore -M midi-import.xml -o score.musicxml performance.mid
程序的名称和位置因系统而异,Windows 上手册用的是 MuseScore4.exe。主要选项的作用如下:
| 选项 | 取值 | 作用 |
|---|---|---|
| QuantValue | 2 | 最短书面时值:十六分音符(1 为八分音符,3 为三十二分音符) |
| VoiceCount | 1 | 每行谱表最多两个声部;声部数等于取值加一 |
| Triplets 及其他连音选项 | false | 不识别连音,因为我们的网格里没有连音 |
| HumanPerformance | false | 不把文件当作现场演奏;只有音符都在网格上时,这样设置才成立 |
| SplitStaff | false,钢琴为 true | 把钢琴声部按左右手分到两行谱表;对其他乐器,MuseScore 则会拆成单独的声部 |
| SimplifyDurations | true | 更少的休止符,更简单的时值 |
| ClefChanges | false | 谱表中途不插入小号的变换谱号 |
| RecognizePickupBar | false | 第一小节按完整小节处理 |
| Swing | 0 | 不检测摇摆节奏 |
如果你的音乐里有三连音,就不要对齐到直拍网格,并保持 Triplets 开启;MuseScore 识别三连音的效果如何,我们还没测过。在 MuseScore 3 里,这些设置都放在一个导入面板中,列名有 Max. voices、Search tuplets 和 Is human performance 等。
谱面更整洁,代价是什么?
会损失一些准确性,主要在音符时值上。以下是我们测得或已知的取舍:
- MuseScore 把 26% 的音符写得比量化后的演奏更长,最多长出三个十六分音符,从来没有写短过;同时发声但长短不同的音符,也可能被写成同一个时值。在 ScoreStarling 里,播放和 MIDI 导出保留演奏的实际时间,不过旋律线会先清理一遍:同时弹下的几个音只留最强的那个,微弱的回声会去掉,持续的音在下一个音开始时结束。
- 调性是根据音符估计的,12 份里错了 2 份,每次都差一个五度。带七个升号或降号的调,会写成对应的、只有五个升降号的等音调。
- 10月2日这次吉他测试用的是直拍的十六分音符网格,表示不了三连音和摇摆节奏。ScoreStarling 转谱单件乐器或人声时依然如此,拍号从 4/4 开始;钢琴独奏则会跟随演奏的小节划分,可以选用 4/4、3/4、6/8 或 12/8。如果你自己准备文件,请写入真实的拍号。
- MuseScore 会按自己的规则把钢琴和弦分给左右手,即使是两个音挨得很近的和弦,也可能被分到不同的谱表上。
其中一部分可以在导入后整理。工具 → 重组节奏(Tools → Regroup rhythms)会改写选中的段落,让音符按拍子分组,节奏本身不变。工具 → 用升号/降号重新拼写音高(Tools → Respell pitches with sharps / with flats)可以修改音名写法,不过手册说它是针对同一音高的音符设计的。调号错了,在导入前改 MIDI 文件,比导入后逐个改音符快得多。
MuseScore 能把 MP3 转成乐谱吗?
MuseScore Studio 不行:它能打开 MusicXML、MIDI 这类乐谱格式,但打不开音频。Muse Group 于 2026年8月17日在 MuseScore 网页平台上推出了 Audio-to-Score 测试版:支持钢琴独奏和原声吉他,MP3 文件最大 30 MB(约三分钟),免费,结果以 MSCZ 文件返回,供 MuseScore Studio 打开。我们还没有测试过。
另一条路就是本文讲的做法:先用音频转 MIDI 模型,再整理它的时间,最后交给 MuseScore 的导入器。ScoreStarling 转单件乐器或人声时就是这样,用的是 Basic Pitch;钢琴独奏则用一个钢琴模型,它转出的音符同时给出节拍和小节线;页面由 Verovio 绘制。现在,单音旋律会写在一行谱表的一个声部里,弹和弦的声部会把和弦保留在同一行谱表上,“乐谱设置 → 布局”还可以改变单声部录音的记谱方式。上面的测量数据来自 10月2日。10月4日,在旋律改为一次一个音、写在一行谱表上之后,我们重测了一遍:调号同样 12 份对了 10 份,3,158 个调内音里写法与调性相悖的为 0,357 个休止符全部显示。
你也可以在 ScoreStarling 里选择或拖入 MIDI 文件,直接得到可编辑的乐谱;鼓轨会被略去,整份乐谱只用一个拍号。录音只转写前五分钟,上传文件最大 100 MiB。PDF 免费,MusicXML 需要先解锁乐谱(一次性 15 积分);其余细节见技术规格(2026年10月7日核对)。工作台可以免费开始使用;注明日期的吉他和乐队测量结果,收录在《AI 扒谱到底有多准?我们实测了一下》一文中。
参考资料
- Summary of MIDI 1.0 Messages——MIDI Association
- Meta Message Types——mido 文档
- basic_pitch/note_creation.py——Spotify Basic Pitch,GitHub
- music21/musicxml/m21ToXml.py——music21,GitHub
- GuitarSet 1.1.0——Xi 等,Zenodo(CC BY 4.0)
- MIDI import——MuseScore 4 手册
- Restore MIDI import panel, issue #11918——MuseScore,GitHub
- importmidi_quant.cpp 和 importmidi_key.cpp——MuseScore 源代码,GitHub
- MIDI import——早期 MuseScore 手册(导入面板)
- Command line usage 及其中的MIDI 导入选项示例文件——MuseScore Studio 手册
- Preferences、File export、Regroup rhythms 和 Respell pitches——MuseScore Studio 手册
- Hear It, Play It: MuseScore Introduces New Smart Audio Recognition Features——Muse Group,2026年8月17日
常见问题
怎么把 MIDI 转成 MusicXML?
在 MuseScore Studio 里打开 MIDI 文件,选择“文件 → 导出”(File → Export),格式选 MusicXML,默认导出压缩的 .mxl。也可以在终端里运行 mscore -o score.musicxml file.mid,效果相同;加上 -M 还能传入一个选项文件,设置量化和声部。记得先把 MIDI 处理好,否则 MusicXML 里也会是同样的一团乱。
为什么 MIDI 导入后满是延音线和附点音符?
因为真人演奏的音符很少刚好在拍点上结束。对齐到很细的网格后,它们会跨过拍子和小节线,只能用延音线连起来;互相重叠的音符还会溢出到额外的声部里。把量化精度设为你想读到的最短时值,把导入器限制为最多两个声部,并让它简化时值;这样 MuseScore 会把部分音符写得稍长一点,让谱面更整洁。
为什么我以为是 E♭,MuseScore 却写成了 D♯?
MIDI 只记录 63 号音,不记录它该写成哪个音名,所以 MuseScore 会按调号来决定写法;某条音轨没有调号时,它就自己估计调性。导入前,在每条音轨里写好正确的调号。导入后,可以用“工具 → 用升号/降号重新拼写音高”(Tools → Respell pitches with sharps / with flats)修改选中的同音高音符。
MuseScore Studio 4 里还能用 MuseScore 3 的 MIDI 导入面板吗?
截至 2026年10月3日还不行:这个面板没有移植过来,要求恢复它的 GitHub issue #11918 也仍未关闭。MuseScore Studio 4 保留了一项针对导入 MIDI 的“最短音符”首选项,它的命令行也接受用 -M 传入选项文件,能覆盖原面板的主要设置。
ScoreStarling 的转谱结果能在 MuseScore 里打开吗?
可以。导出 MusicXML(.musicxml 或 .mxl),调号、音名写法、休止符和声部都会保留;如果只需要音符,导出 MIDI 也行。两者都需要先解锁乐谱,一次性花费 15 积分。ScoreStarling 可以免费开始使用;每份转谱结果都只是初稿,需要你用耳朵核对。