MIDI语义作曲工具

fcp-midi是一个允许LLM通过描述音乐意图(如音符、和弦、动态、速度变化)来创作音乐,并将其渲染为标准MIDI文件的工具。

  • by os-tack
  • Python
  • 本地部署
  • 7 星标
  • 更新于
在 GitHub 查看 aetherwing-io/fcp-midi

使用说明

fcp 中午

用于语义MIDI合成的MCP服务器。

它的作用

fcp-midi允许LLM通过描述音乐意图(音符、和弦、动态、节奏变化)来创作音乐,并将其渲染为标准midi文件。LLM不处理原始字节或MIDI事件,而是使用以下操作 note Bass E2 at:1.1 dur:quarter vel:90 和 crescendo @track:Lead vel:45-75 @range:3.1-6.4.建立在 FCP 框架;一 mido.MidiFile 始终是事实的来源,因此没有单独的序列化步骤。

快速示例

midi_session('new "Voltage Drop" tempo:140 key:E-minor')

midi([
  'note Drums kick at:1.1 dur:eighth vel:100',
  'note Bass E2 at:1.1 dur:quarter vel:90',
  'chord Pad Em at:1.1 dur:whole vel:70',
  'crescendo @track:Lead vel:45-75 @range:3.1-6.4',
  'tempo 174 at:11.1',
])

midi_session('save as:./voltage_drop.mid')

可用的MCP工具

工具 目的
midi(ops) 批量突变——音符、和弦、曲目、节奏、动态、复制/转置
midi_query(q) 检查构图——地图、曲目、事件、钢琴曲、乐器,找到
midi_session(action) 生命周期——新建、打开、保存、检查点、撤消、重做
midi_help() 完整参考卡

英雄示例

水管工之旅 --忠实再现经典游戏主题:4首曲目,288个音符,16秒,180 BPM。

电压降 --一首带有节奏加速(140->155->174BPM)的鼓和低音曲目,5首曲目,破拍,低音,琶音和一个标志性的DROP部分。FCP与原始Python代理之战中也使用了FCP——FCP在87秒内在12个轨道上生成了1674个音符,而手写Python约689行中生成了694个音符。

看 docs/examples/ 用于MIDI文件和完整的写入。

安装

需要Python>=3.11。

pip install fcp-midi

MCP客户端配置

{
  "mcpServers": {
    "midi": {
      "command": "uv",
      "args": ["run", "python", "-m", "fcp_midi"]
    }
  }
}

建筑

Mido-native——操作处理程序和文件格式之间没有并行语义模型:

MCP Server (fcp-core create_fcp_server + MidiAdapter)
  Parses op strings, dispatches to verb handlers, session lifecycle
        |
MidiModel (mido.MidiFile is the source of truth)
  Op handlers read/write mido messages directly on the tracks;
  a NoteIndex gives fast selector lookups. Undo/redo and batch
  atomicity are byte snapshots of the file, not event replay.

主要特点:

  • 仪器库 --GM仪器名称(acoustic-grand-piano, synth-bass-1, standard-kit)
  • Soundfont支持 --加载自定义仪器库
  • 节拍寻址 -- at:1.1 (第1杆,第1拍), at:3.2.240 (第3杆,第2拍,第240拍)
  • 持续时间词汇 -- whole, half, quarter, eighth, sixteenth, triplet
  • 动力学 -- crescendo, diminuendo 跨范围
  • 复制/转置 --复制和转换音乐短语

发展

uv sync
uv run pytest       # 620 tests
uv run pytest -m "not slow"  # skip stress tests (604 tests, ~0.25s)
uv run ruff check   # linting
uv run pyright      # type checking

许可证

麻省理工学院