内容
# 索尼克

> **适用于 Ableton Live 12 的 AI 原生音乐制作界面。**
> 索尼克将您的 DAW 变成一个编码代理可以实际使用的车间 — 编排安排、生成 MIDI、设计声音,并在每个轨道、每个剪辑、每个旋钮的粒度上控制插件。
## 论文
DAW 是为人类设计的,用于点击旋钮。
大型语言模型(LLM)现在可以编写代码、编辑散文、设计 UI、与 API 对话 — 但它们不能 *与您一起制作音乐*,因为没有代理和工作会话之间的干净界面。现有的 MIDI 输出工具将代理变成一个高级的步进式音序器;现有的自动化钩子最多只能暴露少数预先映射的参数。
索尼克就是那个界面,专为 AI 设计。
告诉克劳德 *"为我创建一个深宅风格的介绍:第一个轨道上的四分之一拍的低音鼓,第二个轨道上的一个忧郁的垫子,使用 Serum,八小节,慢攻击"* — 它应该能够做到。端到端。在 Live 中。作为工具调用。
## 代理可以做什么
| 支柱 | 代理的作用 | 状态 |
|---|---|---|
| 🎨 **声音设计** | 读取和写入 **完整** 的任何 VST 的参数空间。 Serum 2 的 2,623 个参数都可以访问;代理通过发出 JSON-RPC 批次来设计声音,比如 "一次设置 16 个旋钮以创建黑暗的电影般的垫子"。 | ✅ 今天就能用 |
| 🎚️ **轨道 / 会话控制** | 创建、命名、启用、静音轨道;加载设备;查询会话状态;路由音频。 | 🟡 计划 2 |
| 🎼 **MIDI 生成** | 在剪辑中写入音符,构建琶音、和弦进程、生成序列;播放测试音。 | 🟡 计划 2 |
| 💾 **预设和波表管理** | 在插件中保存 / 加载预设,交换波表,浏览库 — 代理在合成过程中链接的操作。 | 🟡 计划 2 |
**故意让人类参与其中。** 今天的 LLM 还不能 *聆听* 渲染并将温暖的垫子与易碎的垫子区分开来 — 这仍然是人类的工作。索尼克就是围绕这一点设计的:用户聆听,说 "太亮了,多一些低音,慢一些攻击",然后代理将其翻译成精确的参数更改。代理贡献 *合成器的词汇*(哪些旋钮,什么范围,合理的默认值);用户贡献 *耳朵*。代理本身的音频反馈故意不作为,直到多模态模型可以有用地判断音色。
## 为什么这种架构有效
Ableton 的 "配置" 模式将任何 VST 限制在 128 个自动参数 — 对于 MIDI 控制器来说足够,对于声音设计代理来说远远不够。 Serum 2 独自就有 2,623 个参数。
索尼克通过在 Max for Live 设备(通过 Max 的 `vst~` 对象)内托管 VST,然后通过本地 WebSocket → MCP 服务器管道暴露每个参数来规避限制。从 Claude Code 的角度来看,每个旋钮都只是一个工具调用。与原生轨道插件相同的音质,相同的 MIDI 流,但解锁了完整的表达键盘。
```
Claude Code / 任意 MCP 代理
│ stdio (MCP)
▼
┌──────────────────────┐
│ MCP 服务器 (TS) │ 工具:read_vst_schema, set_vst_param, ...
└──────────┬───────────┘
│ JSON-RPC 2.0 通过 WebSocket (127.0.0.1:9123)
▼
┌──────────────────────────────────────────┐
│ Soniq.Bridge.amxd (Max for Live) │
│ ├── Node for Max ──► WebSocket 服务器│
│ ├── vst~ ──► Serum / Vital │
│ └── LOM ──► 轨道,剪辑 │
└──────────────────────────────────────────┘
│
▼
Ableton Live 12
```
协议 **按设计是 VST 无关的**:模式在运行时从 `vst~` 反映出来。放入 Vital、Pigments、Massive X — 索尼克会适配。轨道 / MIDI 路径使用 Live 的对象模型(LOM),这是通用的 Live API。
## 状态,以数字表示
计划 1(基础 + Serum 垂直切片)在 macOS / Live 12 Suite / Max 9 上运行:
- **2,623** Serum 2 参数可达(543 个音乐参数,在过滤掉 2,080 个 MIDI 直通参数后)
- **23/23** 测试通过(15 个协议模式 + 8 个设备 RPC)
- 端到端演示:代理读取模式 → 设计一个 16 参数的 "温暖的垫子" → 编写批次 → 用户播放
## 路线图
### ✅ 计划 1 — 基础(已发货)
| 已完成 | 详情 |
|---|---|
| 仓库 + 工作空间 | pnpm 工作空间,共享协议包(zod),JSON-Schema 构建管道 |
| M4L 设备骨架 | `Soniq.Bridge.amxd` + Max 项目 + 启动器模式(跨平台稳定) |
| 线路协议 | `127.0.0.1:9123` 上的 JSON-RPC 2.0 通过 WebSocket,版本握手,错误代码 |
| Max 的节点 RPC 服务器 | 路由,问候握手,正常关闭(EADDRINUSE 重试 + 僵尸 PID 恢复) |
| `vst~` 桥 | 模式反射:1 `params` + 1 `get -4` + N `get i` → 装配成 `{index, name, min, max, default}` |
| MCP 服务器骨架 | TypeScript,stdio 入口,3 个工具(`read_vst_schema`, `read_vst_params`, `set_vst_param`) |
| MIDI 直通过滤器 | 剥离约 2,080 个 `CC<N> Chan <M>` 参数,以便代理仅看到合成器旋钮 |
| 双向读写 | 验证实时:代理设计了一个 16 旋钮的 "电影垫",用户播放了它 |
| 文档 + 开源 | 规格 + 计划提交;存储库在 github.com/enkerewpo/soniq 上公开 |
### 🟡 计划 2 — 作曲界面(下一步)
这是一件大事:让代理能够作曲,而不仅仅是调整。
| 能力 | 它解锁了什么 | 备注 |
|---|---|---|
| `tracks.list` / `select` / `create` | "新建一个名为 'pad' 的 MIDI 轨道" | 通过 `live.path` 直接 LOM |
| `clips.create` / `clips.setNotes` | "在剪辑 1 中写入一个 4 小节的 C 小调琶音" | 通过 LOM 剪辑 API 将音符推入 |
| `midi.testTone` | 在声音设计时一次性聆听,无需启用剪辑 | 通过 Max `noteout` 很简单 |
| `vst.savePreset` / `loadPreset` | 代理保存 "v1 电影垫" 以便迭代;可以 A/B | 使用 `vst~` `read` / `write` 消息(.fxp 文件) |
| `transport.play` / `stop` / `tempo` | 代理驱动播放以进行聆听和调整循环 | LOM 歌曲 API |
| 事件通知 | 当用户在 Serum 的 UI 中触摸旋钮时,将 `param_changed` 推到客户端 — 代理保持同步 | WS 服务器 → 通知,无 `id` |
| `mcp-server` 重新连接和节流 | 服务器端合并 50ms 内的快速写入;Live 重启时自动重新连接 | 已在设计文档中,但尚未编码 |
### 🔭 计划 3+ — 延伸目标
- **波表交换** — 需要预设级别的加载(Serum 不公开波表文件选择为连续参数)。可能通过 `vst.loadPreset` 一旦计划 2 发布。
- **调矩阵路由** — `Mod N Out` 是一个归一化的参数,映射到目标 ID;我们需要枚举映射(可能通过实验,因为 Serum 不公开表格)并公开 `vst.modRoute(src, dst, amount)`。
- **多个插件槽** — 目前每个 `Soniq.Bridge.amxd` 实例一个 `vst~`。 "多音轨" 版本将允许一个设备通过设备间路由驱动多个插件在不同轨道上。
- **Windows 端口** — 代码是平台无关的,但 M4L 补丁和 node.script 行为尚未在 Windows 上重新验证。
- **插件配方库** — 一旦预设 I/O 就位,运送一组精选的起点,代理可以从中分叉("808 低音鼓 v3", "环境无人区 v1")而不是每次都从头设计。
- **`live.audio.capture`** — 仅在多模态 LLM 可以有用地分类音色时有意义。在那之前,人类耳朵会闭环(参见上面的注释)。
### ⏳ 清洁后标记 v0.1
- [ ] 完成计划 1 任务 8(正确的 `SoniqClient` 重新连接逻辑 + 单元测试)
- [ ] 计划 1 任务 14 / 15(MCP 工具层集成测试与 `InMemoryTransport`)
- [ ] 执行手动验证检查清单(`tests/manual-verify.md`)针对 Serum 1(目前仅验证 Serum 2)
- [ ] 许可证文件(目前待定)
## 要求
| 项目 | 版本 |
|------|---------|
| macOS | 在 Darwin / Apple Silicon 上测试(Windows 一旦计划 2 落地) |
| Ableton Live 12 Suite | 包括 Max for Live |
| Max | 9.x(与 M4L 捆绑);Node for Max 运送 Node 22.x |
| Node.js | ≥ 20(用于 MCP 服务器) |
| pnpm | ≥ 8 |
| VST3 仪器 | Serum / Serum 2 推荐;任何 VST3 都有效 |
## 快速入门
```bash
git clone https://github.com/enkerewpo/soniq && cd soniq
# 安装
pnpm install
cd Soniq.Bridge/code && npm install && cd ../..
# 构建 + 生成 Node for Max 消耗的 JSON Schema 工件
pnpm -r build
pnpm generate-schema
# 测试(不需要 Ableton)— 使用假桥
pnpm test
cd Soniq.Bridge/code && npm test && cd ../..
```
### 将设备加载到 Live 中
1. 打开 Ableton Live 12。
2. 在 Finder 中,双击 `Soniq.Bridge/Soniq.Bridge.amxd`(或将其拖到 MIDI 轨道上)。
3. 在设备内,点击 `vst~` 对象并加载 Serum(或您选择的 VST3)。
4. Max 控制台应该打印:
```
[soniq] node v22.x.x darwin/arm64
[soniq] WebSocket RPC listening on 127.0.0.1:9123
```
### 注册 Claude Code
```bash
claude mcp add soniq node "$(pwd)/mcp-server/dist/index.js"
```
然后询问 Claude 类似的事情:
- *"加载了哪个合成器?显示 5 个振荡器参数。"*
- *"设计一个 Serum 上的黑暗电影垫 — 显示你的更改。"*
- *"在 2 秒内将滤波器截止频率上下扫描。"*
## MCP 工具(当前)
| 工具 | 目的 |
|------|---------|
| `read_vst_schema` | 插件名称,参数计数和完整模式(默认为过滤 MIDI 直通) |
| `read_vst_params` | 读取一个或多个 0 基于索引的当前值 |
| `set_vst_param` | 通过索引设置参数(归一化 0..1) |
计划 2 将添加:`list_tracks`, `set_clip_notes`, `play_test_tone`, `save_preset`, `load_preset`, 以及 `param_changed` / `schema_reloaded` 的事件通知。
## 线路协议
[JSON-RPC 2.0](https://www.jsonrpc.org/specification) 通过 `127.0.0.1:9123` 上的 WebSocket。无需 MCP 服务器直接测试:
```bash
npx wscat -c ws://127.0.0.1:9123
> {"jsonrpc":"2.0","id":1,"method":"soniq.hello","params":{"version":"0.1.0"}}
> {"jsonrpc":"2.0","id":2,"method":"soniq.vst.schema","params":{}}
> {"jsonrpc":"2.0","id":3,"method":"soniq.vst.write","params":{"writes":[{"index":0,"value":0.7}]}}
```
方法到目前为止:`soniq.hello`, `soniq.vst.schema`, `soniq.vst.read`, `soniq.vst.write`. 完整的メソッド目录在 [`shared/src/protocol.ts`](shared/src/protocol.ts) 中。
## 存储库布局
```
soniq/
├── Soniq.Bridge/ # M4L 设备 + Max 项目
│ ├── Soniq.Bridge.amxd # 设备本身(二进制)
│ ├── Soniq.Bridge.maxproj # Max 项目描述符
│ ├── soniq.bridge.launcher.js # node.script 入口(启动器模式,跨平台)
│ ├── package.json # 将文件夹范围限定为 CommonJS
│ └── code/ # Node for Max 脚本
│ ├── server.js # WebSocket JSON-RPC 服务器
│ ├── max-vst-bridge.js # Node 和 vst~ 之间的桥梁
│ ├── rpc/vst.js # vst.* RPC 处理程序(更多将在计划 2 中添加)
│ ├── protocol.schema.json # 从 shared/protocol.ts 生成
│ └── tests/ # node --test
├── mcp-server/ # MCP 适配器(TypeScript)
│ └── src/{index,client}.ts + tools/
├── shared/ # 协议类型(zod)— 唯一真实来源
├── tools/generate-json-schema.ts # TS 模式 → Node for Max 的 JSON 模式
└── docs/superpowers/ # 设计规格和实施计划
```
## 架构笔记
- **为什么使用启动器** — `node.script` 通过 Max 的文件搜索路径系统解析文件名,而不是 Node.js 的 `require()`。子目录路径(如 `code/server.js`)在 macOS/Windows 上的行为不一致。启动器位于项目的顶级 — 一个唯一命名的文件,Max 始终可以找到 — 然后从那里使用 Node 的标准 `require()`。这是 [Cycling '74 社区推荐的模式](https://cycling74.com/forums/nodescript-with-relative-path-windows-mac)。
- **为什么 VST 在 M4L 设备内** — `vst~` 将每个参数公开为归一化的 0..1 控制,与 Live 的轨道级 VST 托管不同,后者限制在 128 个配置参数。
- **为什么使用 JSON-RPC + WebSocket + MCP** — 三层具有干净的分离:M4L 只关心 Max 消息;WS 服务器只关心 JSON-RPC;MCP 服务器只关心工具描述。每个都可以独立测试。
完整设计:[`docs/superpowers/specs/2026-05-28-soniq-design.md`](docs/superpowers/specs/2026-05-28-soniq-design.md)。实施计划:[`docs/superpowers/plans/2026-05-28-soniq-plan-1-foundation.md`](docs/superpowers/plans/2026-05-28-soniq-plan-1-foundation.md)。
## 调试模式
在启动 `node.script` 之前将 `SONIQ_DEBUG=1` 设置为在 Max 控制台中启用详细的处理器日志记录。
## 许可证
待定。
## 作者
[@enkerewpo](https://github.com/enkerewpo)