sungle-spec/rocktron-all-access
GitHub: sungle-spec/rocktron-all-access
为 1994 年款 Rocktron All Access MIDI 脚踏控制器提供的基于逆向工程 SysEx 协议的 Web 编辑器与虚拟脚踏控制器。
Stars: 0 | Forks: 0
# Rocktron All Access — Web 编辑器 + 虚拟脚踏控制器
适用于 Rocktron All Access MIDI 脚踏控制器(1994年;18个开关 / 2个踏板 / 16通道 MIDI)的 Web 编辑器。在您的笔记本电脑上运行一个小型 Flask + Socket.IO + python-rtmidi 服务器,在 提供海军蓝金属质感的单页 UI,并通过操作系统的标准 MIDI 端口与硬件进行通信。
**新来这儿?请从 [docs/GETTING_STARTED.md](docs/GETTING_STARTED.md) 开始。**
## 功能
### MIDI / 设备 I/O
- 顶部栏中的**输入/输出端口下拉菜单**带有绿色/红色连接 LED 指示灯,每 4 秒自动刷新一次,因此新插入的 USB-MIDI 接口无需重新加载页面即可显示。
- **加载 .syx** — 使用浏览器的文件选择器选取批量转储文件。
- **保存 .syx** — 将当前内存中的转储(包含您编辑的内容)下载到您的 `Downloads` 文件夹中,命名为 `rocktron-YYYYMMDD-HHMMSS.syx`。
- **Read All** — 启动捕获会话;从设备上触发(`SYSX → DUMP → CTR STORE`)。当接收到 23 字节的转储结束标记时,编辑器会累积这 145 帧并自动解析。
- **Write All** — 将当前转储发送回设备,严格按照手册中“每 15 毫秒 1 个字节”的速率逐字节发送(完整的 43 KB 转储大约需要 11 分钟)。toast 提示和服务器日志中会显示实时进度。**拒绝写入不完整/损坏的转储**(首先验证精确的 145 帧多重集)。
- **部分转储横幅** — 加载时将转储标记为 `complete: true/false`;如果捕获不完整,会显示黄色横幅并禁用 Write All。
- **服务器端写入日志** — Write All 进度会记录到运行服务器的终端中,因此即使浏览器标签页失去焦点,您也可以观察传输过程。
### 单预设编辑(Presets 标签页)
点击左侧列表中的任意 120 个预设,即可打开工作台:
| 编辑器 | 涵盖内容 |
|---|---|
| **Name** | 13 个字符(A-Z, 0-9,`.` 渲染为空格)。 |
| **PC slots — 16 channels** | 每个通道的值 (0-127) + 激活/OFF 开关,带有通道名称标签(LOOP, HEAD, DIEZ 等)。一键保存。 |
| **IA bitmap** | 所有 15 个 IA 开关 (SW1-15) 显示为切换胶囊。点击翻转开/关,保存。 |
| **Custom MIDI** | **CMD2 和 CMD3 可写**;CMD1 和 CMD4 只读(显示为灰色),因为它们的字节位置与 IA 位图 (CMD1) 和 SysEx ON/OFF 开关 (CMD4 data2) 重叠。CMD5 隐藏 — 插槽位置未确定。待在后续硬件捕获确认真实的 CMD 偏移量后,再放宽此保护限制。 |
| **SysEx string** | 30 字节 payload + 每个预设的 ON/OFF 开关。 |
### 全局设置(Global Config 标签页)
可编辑并回写至转储:
- 操作模式 (BANK / SONG / REMOTE)
- Bank 大小 (1, 5, 10, 15)
- Bank 样式 (FIRST / CURNT / NONE)
- MIDI 接收通道 (1-16 + OMNI)
- 起始预设编号
- Remote Title # (0-255)
- Program Change Status (OFF / ON / MAP)
- **Write All 调速** (chunk size / byte delay / inter-frame pause) — 默认值与手册规范匹配。
### Channels & Switches 标签页
- 16 个通道名称 (CH1-CH16),支持自定义 4 字符标签。
- 15 个开关名称 (SW1-SW15)。
- 2 个踏板名称 (PED1, PED2)。
- IA 路由参考表(*虚拟*脚踏控制器针对每个 IA 开关发送的通道 + CC# )。
- **将名称保存到转储** — 将新名称拼接回 279 B 的名称块中。
### Songs / Sets / PC Map 标签页
- **Songs** — 从 150 首歌曲中选择,编辑每首歌曲的 10 个预设插槽。
- **Sets** — 从 10 个组中选择,将 150 首歌曲中的一首分配给 50 个 Bank 中的每一个。
- **PC Map** — 128 行的表格,映射传入的 PC# → 预设(用于 MIDI P5 = MAP 时)。
### Virtual Foot Controller 标签页
- **All Access SVG** — 阳极氧化蓝色底盘,配有大理石纹圆顶脚踏开关,发光的青色 **14 段** LCD,使用正确的斜体字母拼写出预设名称(`M`, `N`, `V`, `W`, `K`, `X`, `Y`, `Z`, `/`),红色脚踏 LED,金色的斜体衬线 "All Access" 品牌标识,机械感十足的 "ROCKTRON" 字样。
- 顶行 = 2ND,中间 = BANK +,底部 = BANK -。
- SW1..SW(bank-size) = 当前 Bank 中的预设开关。
- 点击预设开关会调用该预设,点亮其 LED,并且**根据预设存储的开/关位图更新 IA 开关 LED**。
- SW(bank-size+1)..SW15 = 即时访问开关,使用转储中的 IA 名称(VOX1, DIEZ, MARS 等)。
- **表情踏板** — 两个镜像 PED1/PED2 的滑块,在拖动时发送实时 CC。
- **快速发送** — 触发任何单个 PC 或 CC(通道 / 编号 / 数值),用于测试设备连接。
### MIDI 活动日志
控制器下方的一个 240 像素高的滚动文本日志,捕获编辑器发送和从设备返回的每一个 PC/CC,最新事件显示在最上面。通道使用已加载转储文件自身的通道名称进行标记:
```
22:55:49.260 RX CH2 CC#12 DIEZ ON · AS4 (CH2) 127
22:55:49.252 TX CH2 CC#12 DIEZ ON (AS4 (CH2)) 127
22:55:49.408 TX CH0 BANK + Bank 2/24 (PR006-010)
```
## 逆向工程状态
经过 7 个捕获/对比周期 (T0-T6),手册中记录的每个可编辑字段均已解码。逐字段说明:
| 字段 | 解码 | 编辑 | 回写至设备 |
|---------------------------------------------|:------:|:----:|:---:|
| 预设名称 (13 chars) | ✅ | ✅ | ✅ |
| 每个预设 16 个 PC 插槽 | ✅ | ✅ | ✅ |
| IA 开/关位图 (SW1-15) | ✅ | ✅ | ✅ |
| Custom MIDI (CMD2, CMD3) | ✅ | ✅ | ✅ |
| Custom MIDI (CMD1, CMD4, CMD5) | 部分 — CMD1 类型字节与 IA 位图重叠 (0xCA);CMD4 data2 与 SysEx ON/OFF 开关重叠 (0xF6),且 CMD4 尾部延伸至 SysEx 字符串中;CMD5 位置未确认 | ⛔ | ⛔ 直到硬件上确定偏移量 |
| SysEx 字符串 (30 bytes) + ON/OFF 开关 | ✅ | ✅ | ✅ |
| 通道 / 开关 / 踏板名称 (4 chars) | ✅ | ✅ | ✅ (拼接至名称块) |
| 歌曲 (150 songs × 10 preset slots) | ✅ | ✅ | ✅ |
| 组 (10 sets × 50 banks → song) | ✅ | ✅ | ✅ |
| PC 映射 (incoming PC1..128 → preset) | ✅ | ✅ | ✅ |
| 操作模式 / Bank 大小 / Bank 样式 | ✅ | ✅ | ✅ |
| MIDI 接收通道 (incl. OMNI) | ✅ | ✅ | ✅ |
| Remote Title Number | ✅ | ✅ | ✅ |
| Program Change Status (OFF/ON/MAP) | ✅ | ✅ | ✅ |
| 开关类型 (LATCH/MOM/HOLD per IA) | ✅ | ⛔ | ⛔ — 堆栈式索引未确定 |
| 每个预设的 PER-PR 覆盖块 | 部分 | ⛔ | ⛔ |
| MIDI 过滤器掩码 (per type / per channel) | 部分 | ⛔ | ⛔ |
| 最终 F7 之前的尾部 "66 01" | 确认为常量 — 不是校验和 | n/a | n/a |
有关字节级的映射,请参见 [docs/REVERSE_ENGINEERING.md](docs/REVERSE_ENGINEERING.md)。
## 安全性与稳健性
该编辑器将 SysEx 直接流式传输到昂贵的硬件上,且没有身份验证,因此针对明显的威胁模型(*您在同一浏览器中访问的网页悄悄与 localhost 通信*)进行了锁定。请参见 [`security_patch.py`](security_patch.py)。
- **默认绑定回环地址** — `127.0.0.1:5002`。仅当您在其前方设置了身份验证时,才设置 `AA_BIND=0.0.0.0`。
- **Socket.IO CORS** 锁定为 `http://localhost:5002` / `http://127.0.0.1:5002`(之前为 `*`)。
- **基于会话的 CSRF token** 通过 `X-AA-CSRF` 响应头下发;每次更改状态的 `/api/*` POST 请求都需要回传该 token。`templates/index.html` 中的 fetch 垫片会透明地将其回显。
- **Origin 检查** — 跨域 POST/PUT/DELETE/PATCH 返回 403。
- **仅通过上传加载转储** — `/api/dump/load` 仅接受浏览器上传的字节(上限为 1 MB 十六进制数据);服务器绝不读取客户端提供路径的文件。
- **每次启动生成随机 `SECRET_KEY`**(之前是硬编码字符串)。可通过 `AA_SECRET_KEY` 覆盖。
- **MIDI 初始化保护** — rtmidi 端口构建失败会回退到仅文件模式,而不是在启动时导致应用程序崩溃。
- **转储验证** — `validate_dump()` 在 Write All 之前强制执行精确的 145 帧多重集;不完整的捕获将被拒绝并给出明确的错误提示。
## 测试
`tools/uat_headless.py` 是一个包含 23 项检查的回归测试工具,它导入 `app.py` 的真实解析/编码函数,并以字节级文件往返的方式测试每个编辑端点。**无需硬件,无需浏览器,无需服务器。** 可将其接入 CI。
```
.venv/bin/python tools/uat_headless.py path/to/your-full-dump.syx
# -> 结果:23/23 个检查通过
```
(手头没有转储文件?可以不带参数运行它——它会合成一个结构有效的 145 帧转储并执行相同的检查。)
包含针对历史上 CMD4 / SysEx 开关冲突的回归测试,确保该 Bug 不会悄无声息地重现。
## 文档
| 文档 | 受众 | 目的 |
|---|---|---|
| [docs/GETTING_STARTED.md](docs/GETTING_STARTED.md) | 最终用户 | 安装、首次启动、首次 Read All / Write All、故障排除 |
| [docs/USER_MANUAL.md](docs/USER_MANUAL.md) | 最终用户 | 9 个章节的详细指南 — 安装、每个标签页、常见工作流、故障排除 |
| [docs/REVERSE_ENGINEERING.md](docs/REVERSE_ENGINEERING.md) | 开发者 | 批量转储格式的字节级字段映射 |
| [docs/MANUAL_SUMMARY.md](docs/MANUAL_SUMMARY.md) | 参考资料 | 77 页 Rocktron 手册的摘要 |
| [docs/MIDI_SPEC.md](docs/MIDI_SPEC.md) | 参考资料 | 官方 MIDI 实现图表 |
## 运行
```
# Mac / Linux
./run.sh
# Windows
run.bat
```
首次运行将创建 `.venv/` 并安装 `flask`, `flask-socketio`, `python-rtmidi`, `simple-websocket`。打开 。
## 配合真实设备使用
1. 通过 USB-MIDI 接口连接 All Access(该设备具有带幻象电源的 7 针 DIN 输入/输出接口;标准的 5 针 MIDI 接口也能正常工作 — 7 针多出来的引脚只负责供电)。
2. 从标题栏的下拉菜单中选择您的 **IN** 和 **OUT** 端口。当端口打开时,两个 LED 指示灯都会变绿。
3. **Read All**(云朵向下下载图标) — 在设备上执行 `2ND → SYSX → CTR STORE`。145 帧数据将流入;当转储结束标记到达时,编辑器将进行解析并刷新。
4. 在任意标签页中编辑字段。每个部分的 **Save** 按钮都会将您的更改拼接到已加载的转储字节中(非破坏性操作 — 保留其他所有字节)。
5. **Save .syx**(软盘图标) — 下载内存转储的备份副本。
6. **Write All**(黄色上传图标) — 将设备置于 `SYSX → LOAD` 状态,点击 Write All。toast 提示和服务器终端将显示实时进度。按默认速率(1 byte / 15 ms / 0 inter-frame)完成完整转储大约需要 11 分钟。
7. **Write All 后重启设备电源** — 在此固件上,名称和全局设置似乎缓存在 RAM 中,只有在启动时才会刷新。
### 工具
`tools/diff_dumps.py` — 帧对齐的转储对比助手。用法:
```
.venv/bin/python tools/diff_dumps.py baseline.syx edited.syx
```
报告具有偏移量集群的逐帧字节级差异 — 这对于进一步的逆向工程来说极其宝贵。
### 参考数据
字节映射是经过 7 次针对性的捕获/对比周期 (T0–T6),在真实的 All Access 设备上进行逆向工程和验证得出的。原始硬件捕获文件未随 repo 一起分发 — 在进行任何编辑之前,请先使用 **Read All → Save .syx** 捕获您自己的基准数据。
## 支持
如果这款编辑器把您的 All Access 从废旧抽屉里拯救了出来,您可以[请我喝杯咖啡](https://buymeacoffee.com/sungle.spec) ☕ — 这能支持我继续进行逆向工程。
## 许可证
MIT — 随您怎么用。如果它能为您省下一个周末的时间,请提及本 repo。
标签:Flask, MIDI控制器, Python, 云资产清单, 后端开发, 数字音乐, 无后门, 硬件设备管理, 逆向工具, 逆向工程