romerojopro-web/MGS2-Audio-Tool
GitHub: romerojopro-web/MGS2-Audio-Tool
一款《合金装备2》PC 版音频 Mod 工具,支持对话、音效和音乐的浏览、导出与替换,为游戏音频自定义改造提供完整工作流。
Stars: 2 | Forks: 0
# MGS2 音频工具
一款用于 PC 平台 **Metal Gear Solid** 系列游戏的音频 Mod 工具 —— 目前支持
**Metal Gear Solid 2: Master Collection** (2023) 和 **Substance** (2003),
其架构设计旨在未来支持更多游戏(MGS3、ZoE 等)。
打开游戏音频,试听,导出为 WAV,并(针对对话)将其替换为您自己的音频。
顶部的**游戏选择器**用于切换显示的选项卡,并为整个窗口重新着色。
每款游戏都有专属配色主题:Master Collection 为绿色,Substance 为琥珀色。
## 项目状态
- **MGS2 Master Collection — 稳定版。** 每个 MC 选项卡均可在真实游戏数据上运行:对话浏览/导出/替换 (SDT)、声音库扫描和替换 (SDX)、cue 序列器以及音乐替换 (Musique · BGM) ——
**已在实际游戏中确认可用**,包括处理替换后 bundle 加载的 Unity FSB5/Addressables-CRC 机制。
- **更多 MC 功能正在开发中**(例如,启动器的 13 个 UI 音效共享一个 bundle,目前尚无法单独替换)。
- **MGS2 Substance (2003) — 开发中。** 浏览和 WAV 导出功能可用 (VOX、BGM、Dém、SDX 仅支持打开),但仍有部分格式正在逆向工程中:`vox.dat` 编解码器尚未确认,`demo.dat` 解码后存在伪影,Substance 的 `.sdx` 布局与 MC 不同,且目前不存在 Substance 的替换路径。请参阅 `docs/AUDIT.md` 了解未决问题。
### Master Collection 选项卡
- **SDT · Dialogues** — 角色语音台词(可替换,用于自定义配音)。
- **Musique · BGM** — 6 首场景音乐曲目(ARMS DEPOT、BATTLE、INFILTRATION…)以及启动器的主菜单和片尾曲,以 Unity AssetBundles 形式存储在游戏安装目录中。试听,导出为 WAV,并**用您自己的 WAV 替换曲目** —— 该工具会重新构建有效的 `.bundle`,并显示游戏文件夹中每个文件的确切路径,让您知道该替换什么。需要可选的 `UnityPy` 依赖(见下文)。
- **SDX · Sound banks** — 舞台采样库(脚步声、门、武器…)。全盘扫描模式:索引游戏中的每个声音库,将相同的声音分组,编辑其中一个即可立即重写所有副本。
- **Séquenceur · Cues SDX** — 高精度合成器,用于渲染隐藏在 `.sdx` 库中的 SE cue 序列。**这些是原始音效,而非游戏完整的管弦乐配乐** —— 真正的配乐编排需要单独的 `mdx` 文件(见下文),但该文件至今未被找到;如果出现,它很可能会拥有专门的选项卡,而不会并入此项。
### Substance (2003) 选项卡
- **VOX · Voices** — `vox.dat`,游戏的完整语音库(44 100 Hz 的 53 K PS-ADPCM 数据块)。试听、导出或为单个数据块配音。
- **SDX · Sound effects** — `pk000000`–`pk000005.sdx`,六个舞台采样库(22 050 Hz)。一次只能打开一个。
- **Musique · BGM** — `bgm.dat`、`movie.dat`:预渲染的 MS-ADPCM 音乐流(98 + 90 条),直接解码为 WAV。
- **Dém Cutscenes** — `demo.dat`:过场动画和演示音频(135 条 MS-ADPCM 数据),采用相同的解码和导出工作流。
## 需求
- **Python 3.10+**
- **PyQt6** — `pip install PyQt6`(仅图形界面需要)
- **UnityPy** — `pip install UnityPy`(可选;仅 Master Collection 的 **Musique · BGM** 选项卡需要,用于读取/重建 Unity AssetBundles)
- 针对对话文件的 **[MGS2MC Better Audio Mod](https://www.nexusmods.com/metalgearsolid2mc)** `.sdt`
- 游戏的合法副本。请仅使用您自己安装的文件。
底层引擎(`mgs2_audio.codec`、`mgs2_audio.formats`)是纯 Python 编写的,**完全没有依赖项** —— 命令行无需 PyQt6 即可运行。
## 安装与运行
下载项目,然后:
```
pip install PyQt6
python run.py
```
## 它能做什么
### SDT 选项卡 — 对话 (Master Collection)
1. **Voice 文件夹** — 将其指向包含 `.sdt` 文件的文件夹。列表会瞬间显示,即使有一千个文件也是如此。
2. **Database 文件夹** — 存储标签和备注的地方,与游戏文件分开保存。
3. 单击文件进行标记,双击加载并试听。
4. 将其标记为**已完成**,为其添加自由文本**标签**、**说话者**和**备注**。
5. 选择您的录音,生成修改后的 `.sdt`,然后将其放回游戏中。
按名称、标签、说话者或备注进行搜索;按*已完成/待办*或标签进行过滤。
标记完全是手动的 —— 该工具绝不会猜测某行是否已完成。
### VOX 选项卡 — 语音库 (Substance)
打开 `vox.dat`(Substance 语音库)。列出了其中的 5.3 万个 PS-ADPCM 数据块;选择一个进行试听和导出,或选择一个 WAV 进行配音替换。文件对话框默认开启 `.dat` 过滤。
### SDX 选项卡 — 音效
**Master Collection** — 打开单个库,或**扫描整个游戏**:将其指向您的 MGS2 文件夹,它会自动找到 `us/stage`,索引每个库,并将相同的声音分组。
**Substance** — 打开六个 `pk*.sdx` 库之一(扫描模式不可用:Substance 库使用不同的内部布局)。打开对话框默认过滤 `.sdx`。
### BGM / Dém 选项卡 — 流式音乐
**Master Collection** — 打开 `.sdx` 库,其音乐片段将显示在列表中。单击其中一个,它就会在原地合成并播放。导出一个片段,或一次导出所有片段。有两个选项可以改变合成效果:**立体声**(使用每个轨道的声像)和**调音**(使用每种乐器的基础速率,44 100 Hz)。
**Substance** — **BGM** 选项卡打开 `bgm.dat` 或 `movie.dat`(预渲染的 MS-ADPCM 流)。**Dém** 选项卡打开 `demo.dat`(过场动画音频)。两者都会列出包含采样率、声道数和持续时间的条目;选择一个进行试听和导出,或一次全部导出。
### 音乐序列器,来自命令行
`.sdx` 库不仅包含采样:它们还包含乐谱。列出库的 cue 并将其渲染为 WAV:
```
python -m mgs2_audio.cli seq cues pk000002.sdx --min-notes 20
python -m mgs2_audio.cli seq render pk000002.sdx melody.wav
python -m mgs2_audio.cli seq render pk000002.sdx out/ --all --min-notes 8
```
如果没有 `--cue`,将渲染最复杂的 cue —— 通常是音乐。渲染是一个小型的软件 SPU:每个轨道一个声音,在音符按住时循环采样,以及音量、声像、滑音、弯音和转调。
听起来会比游戏中的单薄。PlayStation 在硬件中应用了混响,而这从未存储在任何文件中。
### 命令行
无 Qt,无 GUI,可脚本化:
```
python -m mgs2_audio.cli sdt info vc000101.sdt
python -m mgs2_audio.cli sdt export vc000101.sdt out.wav
python -m mgs2_audio.cli sdt replace vc000101.sdt dub.wav out.sdt
python -m mgs2_audio.cli sdx list pk000000.sdx
python -m mgs2_audio.cli sdx scan "C:/Games/.../MGS2"
python -m mgs2_audio.cli sdx export-key "C:/Games/.../MGS2" sound.wav
python -m mgs2_audio.cli sdx replace-all "C:/Games/.../MGS2" mine.wav
```
`scan` 接受游戏文件夹、语言文件夹或 stage 文件夹本身。
## 提示
- 尽可能以文件本身的速率进行录制 —— `.sdt` 为 **44100 Hz**,`.sdx` 为 **22050 Hz**。否则工具将进行重采样。
- **长度固定。** 较长的音频会被修剪,较短的会被静音填充。输出保持原始的确切字节大小,这是游戏要求的。
- 在立体声 `.sdt` 上,您的单声道录音将被放置在两个声道上。
- **在首次 `replace-all` 之前进行备份。** `.bak` 文件会自动写入,但备份一份 `stage/` 目录毫无成本。
## 架构
```
run.py launch the GUI
mgs2_audio/
codec/ PS-ADPCM, MS-ADPCM and WAV. Knows nothing about MGS2.
formats/ sdt.py, sdx.py, sequence.py, bgm.py — the game's file formats.
detect.py does structural auto-detection.
library/ the tagging databases.
render.py a small software SPU: plays a sequencer cue.
core/ GamePlugin ABC, PageSpec, REGISTRY — the plugin interface.
base.py GamePlugin, PageSpec, AudioFormat, AudioContainer
registry.py Plugin discovery and global registry
games/ Each game is a subpackage that registers itself.
mgs2_mc/ MGS2 Master Collection (SDT, SDX, Sequencer)
mgs2_substance/ MGS2 Substance 2003 (VOX, SDX, BGM, DEMOS)
ui/ PyQt6 interface (app.py = shell, one page per tab).
cli.py the command line.
docs/FORMATS.md the reverse-engineering notes.
tests/ pytest suite, no game files needed.
```
每一层只了解它下面的层。游戏是独立的插件,在导入时被发现 —— UI 外壳从不直接导入特定于游戏的代码。添加新游戏意味着在 `mgs2_audio/games//` 中创建一个新的子包,其中包含扩展了 `GamePlugin` 的 `Plugin` 类。
如果您想了解这些文件、做出贡献或基于此构建其他东西,**请先阅读 [`docs/FORMATS.md`](docs/FORMATS.md)**。代码可以重写;但获取这些知识所花费的时间要长得多。
运行测试:
```
pip install pytest
python -m pytest
```
它们从零开始构建合成的 `.sdt` 和 `.sdx` 文件 —— 无需游戏数据,并且这种默认运行被刻意保持轻量(几秒钟,除了真实的测试内容外,没有对任何内容进行暴力的 PS-ADPCM 编码)。如果您将真实游戏文件放在 `tests/mgs2_substance_2003/` 下,少数测试会针对其进行额外验证 —— 这些测试是可选的(`python -m pytest --realdata`),因为解析 1 GB 以上的文件很慢且确实非常耗费 CPU;它们默认被跳过,因此普通的测试运行永远不会长时间占用某个 CPU 核心。
### 仅运行您正在修改的部分
测试套件按子系统拆分为一个文件一个,因此 `pytest tests/test_X.py` 仅运行与 `X` 相关的内容 —— 在迭代某个领域时无需运行完整的测试套件(或 `--realdata`)。消耗 CPU 更少,阅读速度更快。
| 正在处理… | 运行 |
|-------------------------------------------|-------------------------------|
| PS-ADPCM / MS-ADPCM 编解码器 | `pytest tests/test_codec.py` |
| `.sdt` 格式 (对话) / `vox.dat` | `pytest tests/test_sdt.py` |
| `.sdx` 格式 (声音库) | `pytest tests/test_sdx.py` |
| `bgm.dat` / `movie.dat` / `demo.dat` | `pytest tests/test_bgm.py` |
| MC 音乐 bundle (`formats/mcbgm.py`) | `pytest tests/test_mcbgm.py` |
| 序列器 / `render.py` (SPU, 混响) | `pytest tests/test_sequence.py` |
| 标记数据库 (`library/db.py`) | `pytest tests/test_library.py` |
| 应用外壳 (`ui/app.py`, `db_folder`) | `pytest tests/test_app.py` |
单个测试也有效(在排查某个失败原因时很方便):`pytest tests/test_bgm.py::test_quad_matches_separate_stereo_decode`。
在发布之前,或者每当某项更改可能涉及多个子系统时,请执行完整的 `pytest`(或 `--realdata`)运行 —— 而不要将其作为开发期间的默认操作。
## 已知限制
- **编码速度慢。** PS-ADPCM 编码器是纯 Python 的,它通过暴力搜索为每 28 个真实音频采样寻找最佳的过滤器和偏移量。生成一长段配音可能需要一些时间,并且看起来像是卡住了。静音被设置为快速通道(`.sdt` 替换总是会填充或修剪到目标的确切字节大小,并且填充/修剪掉的部分通常是静音),但真实的录音本身仍然需要经过完整的搜索过程。解码速度很快。
- **扫描整个游戏**(仅限 Master Collection)会读取约 200 个库,每个约 1 MB。请稍等一分钟;进度条是真实的,并且您可以取消。
- **Substance `.sdx` 库**使用不同的内部布局(`voice_tbl` 不在 `0x800` 处);它们目前无法在序列器中解析。仅限打开模式。
- **Substance `vox.dat` 播放可能存在问题。** 目前它被解码为 PS-ADPCM,但容器结构表明实际编解码器可能是 Konami 的 DPCM_KCEJ —— 未经听感证实。在依赖它之前,请参阅 `docs/AUDIT.md`。
- **Substance `codec.dat`**(`b9 2a 90 3d` header)是未知格式;仍需进行逆向工程。目前已在 UI 中将其排除。
- **立体声配音被复制**到两个声道。不支持真正的左/右立体声替换。
- **`replace-all` 会就地写入您的游戏文件**(带有 `.bak` 备份)。
- **以 Windows 为主。** 它应该可以在任何运行 PyQt6 的平台上运行;其他平台未经测试。
## 免责声明
非官方、粉丝制作,与 Konami Digital Entertainment 无关联、未获其认可或赞助。*Metal Gear Solid 2: Sons of Liberty* 及所有相关名称、角色和资产均为 Konami 的商标和版权所有。
- **不包含任何游戏文件。** 此项目仅包含原创代码。
- **使用您自己的副本。**对如何使用它负责。
- **仅用于个人、非商业性质的 Mod 制作。**
- **备份您的文件。** 按“原样”提供,不提供任何形式的保证;对于因使用本工具而造成的任何损害或数据丢失,作者概不负责。
文件格式是通过对互操作性进行独立分析确定的。如果您是版权所有者并对此项目有任何疑问,请提交 issue,我们将予以处理。
## 许可证
[MIT](LICENSE) — 随意使用,请保留许可声明。
标签:Unity, WAV, 安全规则引擎, 文件解析, 游戏 Mod, 游戏工具, 逆向工具, 音频处理