Skip to main content
Glama
David7ce
by David7ce

audio2score-mcp

将录制的音频文件转换为可编辑的乐谱:音频 → MIDI → MusicXML

选择 MusicXML 作为目标格式,因为它是"乐谱界的 SVG"——一种开放的、基于文本的格式,任何记谱应用(MuseScore、Sibelius、Guitar Pro、Finale、Dorico)都可以打开、编辑和重新导出,而无需拥有生成它的流水线。本项目只生成 .mid.musicxml 文件;打开、编辑以及导出为任何其他格式(PDF、音频、六线谱)都在你选择的记谱应用中手动完成——关于本项目为何刻意不封装这部分,请参阅下文"此项目连接到的格式"。

两种运行方式:作为普通 CLI 脚本运行,或作为 MCP 服务器运行,将相同的步骤暴露为 Claude 可以调用的工具。

目录内容

  • transcribe.py — 音频文件 → MIDI,通过 Spotify 的 basic-pitch

  • to_score.py — MIDI 文件 → MusicXML,通过 music21

  • score_to_notes.py — 乐谱文件(MIDI、MusicXML,或任何 music21 能读取的格式)→ 以 daw-mcp 的 batch_set_notes 格式输出的 JSON 音符数组

  • mcp_server.py — MCP 服务器,将以上三个脚本封装为工具(transcribe_audiomidi_to_scorescore_to_notes

每一步都是磁盘上独立、真实存在的产物——不是隐藏的中间结果。MIDI 与记谱之间的停顿是刻意设计的:自动转写是有损的,因此在它变成乐谱之前,原始 MIDI 值得检查(或手动修正)一下。

score_to_notes.py 刻意设计为格式无关的,而非 MIDI 专用——music21.converter.parse() 对 MIDI 和 MusicXML 的处理完全相同,因此将 transcribe.py 生成的 .mid 或外部 OMR 工具(参见"此项目连接到的格式")生成的 .mxl 喂给它,走的是同一条代码路径。本项目没有单独的 MusicXML→MIDI 或 MusicXML→PDF 工具——一旦生成了 .musicxml,任何记谱应用都能直接打开并导出它,所以在这里构建这些功能只是重复安装已有的东西。

Related MCP server: whisper-mcp

文件存放位置

建议:将输入文件放入 workspace/(仓库本地目录,已被 gitignore——参见 .gitignore——放在这里的任何内容都不会被提交,包括输入文件)。不过这不是硬性要求——任何路径都可以。每个输出文件都生成在其输入文件旁边,同名不同扩展名:

workspace/song.mp3          <- you put this here (any format basic-pitch/librosa reads: mp3, wav, ogg, flac...)
workspace/song.mid          <- transcribe_audio writes this
workspace/song.musicxml     <- midi_to_score writes this (open in MuseScore/Guitar Pro/Sibelius/Finale/Dorico)
workspace/song.notes.json   <- score_to_notes writes this (feed into daw-mcp's batch_set_notes)

查看方式:直接用你手头的任何记谱应用打开 .mid.musicxml——本项目不会为你启动任何应用。如果 MuseScore 提示 .musicxml"已损坏",在断定文件有问题之前,请先查看下面的复调注意事项。

环境搭建

需要 Python 3.11 特定版本——basic-pitch 依赖 TensorFlow 2.15,其 wheel 只支持到 cp311;3.12 和 3.13 将无法解析。生成的虚拟环境约为 2GB(完整版 TensorFlow,而非更轻量的后端)。

uv venv --python 3.11 venv
uv pip install -r requirements.txt --python venv/Scripts/python.exe

依赖项已精确锁定(basic-pitch==0.4.0music21==10.5.0setuptools==65.5.0mcp==2.0.0)——本项目没有自动化测试套件,因此一个与已验证环境完全一致的全新环境就是替代方案。setuptools 特别被锁定,是因为较新版本会破坏 basic-pitch 所需的传递依赖 resampy 的导入。

用法:CLI

venv/Scripts/python.exe transcribe.py "C:\path\to\song.mp3"
# -> C:\path\to\song.mid

venv/Scripts/python.exe to_score.py "C:\path\to\song.mid"
# -> C:\path\to\song.musicxml

venv/Scripts/python.exe score_to_notes.py "C:\path\to\song.mid"
# -> C:\path\to\song.notes.json  (daw-mcp's batch_set_notes format - also
#    takes a .musicxml/.mxl directly, e.g. from OMR, no separate step needed)

输出始终生成在输入旁边,同名不同扩展名。三个脚本都拒绝覆盖已存在的输出文件——如果想重新运行,请先删除或移动旧文件。错误(输入缺失、库故障)会向 stderr 打印清晰的消息并以非零状态退出;不会有静默失败。

只运行你的实际目标所需的工具——不要默认把三个全部串联起来。 每个工具只生成一个文件;运行超出需要的工具只会产生没人要的文件。

目标

运行

生成的文件

将录音作为记谱查看/编辑

transcribe_audiomidi_to_score

.mid.musicxml

将录音的音符导入 daw-mcp

transcribe_audioscore_to_notes

.mid.notes.json(跳过 midi_to_score——此目标不需要)

将扫描/排版好的乐谱导入 daw-mcp

Audiveris(外部工具,参见"此项目连接到的格式")→ 对 .mxl 运行 score_to_notes

.mxl.notes.json(完全没有 MIDI 步骤)

将扫描乐谱作为记谱查看/编辑

仅 Audiveris

.mxl——已经是 MusicXML,直接打开即可,这里不需要任何工具

前两行中的 .mid 与其说是"输出",不如说是不可避免的检查点——basic-pitch 只能输出 MIDI,而且在信任其后续结果之前值得检查一下(原因参见下面的"已知问题")。

实际示例

这是一个真实运行,而非假设。输入:一个合成的单声道 WAV,C 大调琶音(C4-E4-G4-C5,四分音符,带有短衰减包络,因此起音清晰)——这是本项目关心的意义上的"真实音频"(磁盘上实际的波形,而非手打的 MIDI),只是合成而非录制,因此转写结果可以在没有版权文件散落在公共仓库中的情况下复现。

$ venv/Scripts/python.exe transcribe.py c_major_arpeggio.wav
WARNING:root:Coremltools is not installed. ...
WARNING:root:tflite-runtime is not installed. ...
WARNING:root:onnxruntime is not installed. ...
Wrote c_major_arpeggio.mid

$ venv/Scripts/python.exe to_score.py c_major_arpeggio.mid
Wrote c_major_arpeggio.musicxml

$ venv/Scripts/python.exe score_to_notes.py c_major_arpeggio.mid
Wrote c_major_arpeggio.notes.json

三行 WARNING:root 是 basic-pitch 提示可选后端(CoreML、TFLite、ONNX)未安装——无害,实际使用的是 TensorFlow 后端,而且这正是 transcribe.py v1.1.1 现在正确隐藏的内容,不会破坏 mcp_server.py 的 stdout 流(参见 CHANGELOG.md)——它只出现在终端上,不会进入 MCP 协议通道。

c_major_arpeggio.notes.json,即 daw-mcp 就绪的输出:

[[0.0, 60, 83, 1.0], [1.25, 64, 80, 1.0], [2.3333, 67, 80, 1.0], [3.5, 72, 78, 0.5], [4.0, 72, 78, 0.5]]

输入了四个音符(C4、E4、G4、C5);basic-pitch 正确检测了全部四个音符的音高和力度(60/64/67/72,与琶音完全一致),但将最后一个音符(C5)拆成了两个连续的条目而非一个——衰减包络的尾部显然被识别为第二个起音。这就是上文"目录内容"部分警告的自动转写有损性,在第一个具有自然(非平直)音量形状的音符上就实际出现了:在盲目信任 .musicxml/.notes.json 之前,请检查 .mid,尤其是在持续音或衰减音附近。

c_major_arpeggio.musicxml 可以在任何记谱应用中正常打开(已验证格式良好:正确的 MusicXML 4.0 DOCTYPE,C4/E4/G4/G4/C5/C5/C5 的 <step>/<octave> 音高——被拆分的 C5 以跨小节线的连音形式出现,这是 MusicXML 中一个音符无法放入单个小节时的标准表示,而非第二个 bug)。

用法:MCP 服务器

在 Claude Code 的配置中注册为 audio2score——全新安装后请重启 Claude Code 才能看到它(MCP 服务器在启动时加载)。

三个工具,与三个脚本完全对应:

  • transcribe_audio(audio_path) → 返回 .mid 路径

  • midi_to_score(midi_path) → 返回 .musicxml 路径

  • score_to_notes(score_path) → 返回 .notes.json 路径(daw-mcp 的 batch_set_notes 音符数组格式;接受 MIDI 或 MusicXML)

底层行为与 CLI 相同(相同的覆盖保护、相同的错误)——MCP 服务器是薄封装,而非不同的实现。

如果调用似乎挂起,需要知道一件事: 如果 transcribe_audio 调用看起来超时或被取消,转写可能仍在后台运行,并且无论如何都会完成 .mid 文件的写入。重试时就会触发覆盖保护("已存在"),即使第一次调用看起来从未成功。这不是 bug——重试前先检查 .mid 是否已存在。

要在其他地方自行注册服务器,请将以下内容添加到你的 MCP 配置(mcpServers)中,两个字段都使用绝对路径——客户端启动 stdio 服务器时没有定义工作目录,因此相对路径无法解析:

"audio2score": {
  "type": "stdio",
  "command": "<absolute path to>\\venv\\Scripts\\python.exe",
  "args": ["<absolute path to>\\mcp_server.py"],
  "env": {}
}

此项目不做什么

  • 不提供乐谱/MIDI → 音频、PDF 或六线谱输出,也不提供 MusicXML → MIDI 转换——原因及替代方案参见下文"此项目连接到的格式"

  • 不提供声部分离或多乐器拆分

  • 刻意不设自动化测试套件——验证始终是对真实音频的真实运行

此项目连接到的格式

一旦生成了 .musicxml,本项目就刻意止步——每个记谱应用都已原生支持打开 MusicXML,并从自己的菜单中导出所需内容(PDF、音频、六线谱、MIDI)。围绕这些导出构建自动化封装的做法曾被尝试过,但大部分已回退(完整的反复过程参见 CHANGELOG.md v1.2.0 至 v2.0.0)——在确认 score_to_notes.py 可以直接接受 MusicXML 而无需单独转换步骤之后,最终发现仍然值得自动化的方向一个都没有。

方向

使用

备注

MusicXML → PDF、音频、六线谱、MIDI

MuseScore Studio 或 Guitar Pro,正常打开

刻意不在此封装——见上文。(MuseScore 的 CLI 转换模式 -j job.json 确实可以可靠地自动化 PDF 导出,如果你想在自己的脚本中使用的话——只是没有内置到本项目中)

PDF(扫描/排版乐谱)→ MusicXML

AudiverisC:\Program Files\Audiveris\Audiveris.exe):Audiveris.exe -batch -export -output "<文件夹>" "<输入>.pdf"

-batch 确实会跳过其 GUI。已在 3 个真实 PDF 上测试:2 个干净的单页乐谱正确导出(其中一个有轻微拍号警告);一本 24 页的吉他六线谱书在多个页面上遇到了 Audiveris 内部崩溃(其节奏分析中的 NullPointerException/IndexOutOfBoundsException)——OMR 在复杂、多页或六线谱密集的输入上可靠性会迅速下降

PDF → daw-mcp 的音符格式

Audiveris(上文)→ 本项目的 score_to_notes.py,直接对 .mxl 运行

两步,都是真实的,并且已在真实乐谱上端到端测试——中间无需 MIDI 转换

对待 OMR 输出的怀疑程度至少应与对待 basic-pitch 的音频转写相同——在信任之前检查中间的 .musicxml,并且不要期望 Audiveris 能成功处理每个 PDF(参见上面六线谱书的失败案例)。

已知问题:MuseScore 可能会将转录的 .musicxml 文件视为“已损坏”并拒绝打开

高度复调的转录可能会生成一个 MuseScore Studio 拒绝打开并称之为“已损坏”的 .musicxml 文件。根本原因:当一首曲子需要多个同时进行的声部(5+)时,music21 自带的 MusicXML 写入器会在某些 <note> 元素上省略 <voice> 标签——这已通过一段真实的 45 秒录音得到验证,该录音被转录为密集且经常重叠的音符(这是 basic-pitch 在真实音频上拾取泛音/伪影所导致的副作用,而不是干净的单一旋律线)。已确认这是 music21 写入器的问题,而不是本项目的代码:to_score.py 只是一个两行的 parse() + write() 调用,本身没有任何音符/声部逻辑;即使在写入前显式调用 score.makeNotation() 也无法修复。用 music21 本身重新解析同一文件时,它只会发出警告(Cannot put in an element with a missing voice tag),并通过将这些音符默认归入声部 1 来恢复;而 MuseScore 的导入器只是更严格,直接拒绝,而不是容忍这种情况。

变通方法:点击“仍然打开”——文件可以正常加载,只是那些特定音符会进入声部 1,而不是原先检测到的声部;这只是小的排版异常,不是数据丢失。在干净、低复调的输入(手工创作的旋律 MIDI,转录并重新验证后没有任何 voice 标签问题)上不会出现——这专门针对杂乱、密集的真实音频转录输出。

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    MCP server that provides a transcribe_audio tool to convert voice messages from channels into text using OpenAI Whisper, enabling Claude Code to process audio attachments.
    1
    MIT
  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    MCP server for vibe coding with music, enabling format conversion (LilyPond, MusicXML, MIDI, ABC, etc.), audio-to-sheet transcription, and transposition with robust fallback outputs.
    1

View all related MCP servers

Related MCP Connectors

  • MCP server for Producer/Riffusion AI music generation

  • Generate AI music via the Lacuna Music API from MCP clients like Claude Desktop & Code.

  • MCP server for Suno AI music generation, lyrics, and covers

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/David7ce/audio2score-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server