nospi/dm3-tools

GitHub: nospi/dm3-tools

解析和写入 Yamaha DM3 数字调音台文件格式的命令行工具,支持场景、预设和演出文件的读写、比对与批量编辑。

Stars: 0 | Forks: 0

# dm3-tools 用于解析和写入 **Yamaha DM3** 数字调音台文件(包括场景、预设和完整的演出文件)的 CLI 工具,同时适用于控制台的 USB 保存/加载以及 DM3 Editor。已完成端到端验证:由 `dm3 set` 写入的文件可以在 Yamaha 的 DM3 Editor 中完美加载。 ## 文件类型 | 扩展名 | 内容 | 状态 | |-----------|----------|--------| | `.dm3s` | 单个场景 (SceneInfo + Mixing + Processing + FX) | 读/写 | | `.dm3p` | 单个库预设 (范围限定子树:CH/MX/ST/FXBS) | 读/写 | | `.dm3f` | 所有调音台设置(“演出文件”,USB ↔ 控制台 ↔ 编辑器) | 读/写 | ## 用法 ``` dm3 info scene.dm3s # header + field summary dm3 dump scene.dm3s -f Mixing # decode to JSON dm3 get scene.dm3s SceneInfo.Info.Title dm3 set scene.dm3s "SceneInfo.Info.Title=FSC Town Hall" -o out.dm3s dm3 set scene.dm3s "Mixing.InputChannel[0].Label.Name=Kick" dm3 diff before.dm3s after.dm3s # what changed between saves # .dm3f show files: --entry addresses embedded files # (默认 entry 是 console 的当前 memory) dm3 info show.dm3f # list embedded files dm3 set show.dm3f "Mixing.InputChannel[0].Label.Name=KICK IN" -o out.dm3f dm3 dump show.dm3f -e 88112F6B….dm3s # decode a stored scene dm3 extract show.dm3f -d out/ # unpack all embedded files ``` 仅您设置的值所占用的字节会被修改;文件中的其他所有内容都将按字节原样保留。 ## 工作原理 DM3 文件是 `#YAMAHA MBDF` 容器:包含一个头部 + UUID,随后是 `#MMS FIELD` 部分。每个字段都带有一个 `MMSXLIT` schema 块(函数名 + 锁定 schema 版本的摘要)、一个用于描述参数树的 `COL0`(集合)和 `PR`(参数)记录表,以及一个完全按照树声明进行布局的紧凑型小端序数据块。 权威的 schema 以 Yamaha 自己的 DM3 Editor 随附的 `Descriptor/mms_*.xml` 形式发布(包含名称、C 类型、范围、默认值、结构体大小)。`dm3tools` 会解析这些 XML 文件,并由它们驱动所有的解码/编码过程 —— 无需进行逐个参数的逆向工程。已通过往返测试验证了编辑器附带的全部 278 个出厂预设/场景(845/845 个字段)。 ### 获取 descriptors 与 fixtures Yamaha 的 descriptor XML 文件和出厂预设受版权保护,因此未提交至此仓库。请从 Yamaha 公开的 DM3 Editor 安装程序中获取它们: ``` scripts/fetch_fixtures.sh # downloads editor, extracts via msiextract ``` 或者让 CLI 指向已安装的 DM3 Editor: ``` export DM3_DESCRIPTOR_DIR="/path/to/Yamaha/DM3/Descriptor" ``` ## 在 Linux 上运行 DM3 Editor Windows 版本的编辑器可以在 Wine 下运行(已测试 wine 6.0.3,prefix 设置为 win10)。启动时必须将其安装目录设置为工作目录,否则会在启动时崩溃(因为它会加载相对于 cwd 的 `Descriptor/mms_*.xml`): ``` scripts/dm3-editor.sh ``` ### .dm3f 演出文件 `.dm3f` 是一个类型为 `ProjectFile` 的 MBDF 文件:包含一个 ProjectInfo 字段,随后是一系列 `#FILE` 条目 —— 槽位名(`Current`、`Scene:A`、`SceneList`)、大端序的大小、文件名,以及一个可解压为另一个 MBDF 文件的 **zlib** 负载(即控制台的当前内存、每个已存储的场景、场景列表索引,以及 `.old` 日志副本)。具体的字节布局请参见 `src/dm3tools/dm3f.py`。 ## 先前技术与鸣谢 [netik/decode_dm3](https://github.com/netik/decode_dm3) (Apache-2.0) 首次公开探索了这些格式,并正确识别了 MBDF 容器标记。dm3-tools 与其没有共享任何代码,但正是他们的工作让人明确了这些格式是易于处理的。他们留下的悬而未决的问题 —— `.dm3f` 内嵌文件的压缩方式 —— 最终被证实为普通的 zlib。 ## 法律声明 dm3-tools 是一个独立的互操作性项目,不附属于 Yamaha,也未获得 Yamaha 的认可。它是通过观察 DM3 控制台和 DM3 Editor 生成的文件而构建的;未对任何 Yamaha 软件进行反编译或反汇编,本仓库也不分发任何受 Yamaha 版权保护的材料(descriptor XML、出厂预设、二进制文件)—— `scripts/fetch_fixtures.sh` 会从 Yamaha 自己的公开安装程序中获取这些内容。Yamaha、DM3 及相关标志归 Yamaha Corporation 所有。 ## 注意事项 / 已知问题 - 物理控制台的 USB 加载测试待完成(编辑器加载测试已通过)。 - 一个出厂文件(`PresetDante` 类型,Status/DNTP 字段)在解码时比其 descriptor 少了 148 个字节 —— 疑似是不同的 schema 版本所致。暂且搁置。 - 出厂文件中的字符串字段在 NUL 终止符之后包含垃圾数据(Yamaha 没有将缓冲区清零)。这在语义上无关紧要;我们会为未修改的字段保留原样,并对我们写入的字段进行零填充。 - 重写后的 `.dm3f` 文件比编辑器写入的文件稍大(我们的 zlib 压缩级别 1 不如 Yamaha 的紧凑);这并无大碍,因为容器中已明确指定了大小。 ## 开发 ``` pip install -e . PYTHONPATH=src python3 -m dm3tools.cli ... # without installing python3 scripts/verify_layout.py # structural invariants sweep ```
标签:Homebrew安装, Yamaha DM3, 二进制数据处理, 数字调音台, 文件解析, 文档结构分析, 逆向工具