athousanddetails/penbridge
GitHub: athousanddetails/penbridge
一款 macOS 原生应用,在已有的 rekordbox USB 盘上无损追加 Denon Engine 媒体库,让一根 U 盘同时兼容 Pioneer 和 Denon 播放器且不重复拷贝音频。
Stars: 0 | Forks: 0
# PenBridge
**由 [A Thousand Details](https://github.com/athousanddetails) 出品**
一款小型的原生 macOS 应用(SwiftUI, Apple Silicon),它可以在已经包含 **rekordbox export** 的 USB 驱动器上添加一个 **Denon Engine
Library**,*复用驱动器上已有的音频*。无需复制任何曲目,且永远不会修改 rekordbox 端的数据。
最终结果是:一个 U 盘可以同时适用于 Pioneer CDJ/XDJ 和 Denon Prime。插入驱动器后,它会被自动检测、打开和分析——内置了一个媒体库浏览器,用于在写入任何内容之前检查 U 盘上的内容,并配有一个弹出按钮,方便快速更换 U 盘。
```
/ (USB drive)
├── Contents/ audio — shared by both, written once
├── PIONEER/ read by Pioneer ← never modified
│ └── rekordbox/export.pdb
└── Engine Library/ read by Denon ← the only thing added
└── Database2/m.db
```
## 为什么这可行
Engine 存储 `Track.path` 时使用的是**相对于 `Engine Library` 文件夹的路径**,并且它接受跳出该文件夹的路径。因此,rekordbox 列表显示为 `/Contents/Artist/Track.mp3` 的曲目,在写入 Engine 时会变成 `../Contents/Artist/Track.mp3`。
两个数据库最终都指向磁盘上的同一部分数据字节。
这与 libdjinterop 在其参考示例中使用的约定相同(`relative_path = "../01 - Some Artist - Some Song.mp3"`)。
## 安全模型
* rekordbox 数据库和 ANLZ 分析文件均以**只读**方式打开。
* Engine 数据库在**内部磁盘**的临时文件夹中组装,通过 `PRAGMA integrity_check` 后,才会被复制到驱动器。
* 每个目标路径都会经过一个防护程序,它会拒绝任何不在 `/Engine Library` 内的内容。
* **撤销**操作只需一个按钮,或者执行 `rm -rf "/Volumes/YOURPEN/Engine Library"`。此后该 U 盘将恢复得与之前毫厘不差。
## Schema
`EngineSchema.swift` 中的 `CREATE TABLE`/`INDEX`/`TRIGGER`/`VIEW` 语句是逐字从 libdjinterop 的参考数据库生成的,这些数据库是从真实的 Engine OS 输出中捕获的。Engine 会拒绝加载 schema 不一致的数据库,因此切勿手动编辑此文件。
| 选项 | 原生写入者 | 读取者 |
|---|---|---|
| `2.21.0` | Engine OS 3.1 – 3.4 | Engine OS 3.1 → 5.x(作为旧版格式) |
| `3.0.1` | Engine OS 4.3 – 4.x | Engine OS 4.3+ |
| `3.0.2` **(默认)** | Engine OS 5.0+ | Engine OS 5.0+ |
Engine OS 4.0 仅停止了对 *legacy* (1.x) 数据库的支持,因此 2.x 依然在任何地方被接受——如果你需要支持较旧的播放器,请选择它。
请注意,schema 2.x 和 3.x 在结构上有所不同:在 2.x 中,performance blobs 是 `Track` 上的列,而 `PerformanceData` 是基于它的视图;而在 3.x 中,`PerformanceData` 是一个真实的表,其行由 `Track` 上的 `AFTER INSERT` 触发器创建。写入器对两者均兼容。
## 转换的内容
| rekordbox | Engine |
|---|---|
| 曲目 + 元数据(标题、艺术家、专辑、流派、厂牌、注释、评级、年份) | `Track` |
| 歌单树,包括文件夹和顺序 | `Playlist` / `PlaylistEntity` |
| beatgrid (`PQTZ`) | `beatData`(在节奏变化处设置标记,并小节对齐到第一个重拍) |
| hot cues / memory cues (`PCOB`/`PCO2`) | `quickCues` / `loops` |
| 预览波形 (`PWAV`) | `overviewWaveFormData` |
| 调性名称 | `Track.key`(Engine 的 0–23 索引,同时处理 Camelot 和经典记谱法) |
Engine OS 会在加载曲目时重新生成其自带的详细滚动波形,因此这里仅写入概览条带。
## 下载
从 [最新发布版本](../../releases/latest) 获取 `PenBridge.app.zip`,解压后将其拖入 `/Applications`。
该版本为 ad-hoc 签名,未经公证,因此首次启动时需要进行以下操作之一:
* 右键点击该应用 → **打开** → **打开**,或者
* 执行 `xattr -dr com.apple.quarantine /Applications/PenBridge.app`
适用于 Apple Silicon,macOS 14+。
## 构建
```
./make-app.sh # produces PenBridge.app
```
或者在 Xcode 中打开 `Package.swift` 并点击运行。
无头模式验证:
```
PenBridge.app/Contents/MacOS/PenBridge --headless /Volumes/YOURPEN --dry-run
PenBridge.app/Contents/MacOS/PenBridge --headless /Volumes/YOURPEN [--schema 3]
```
## 致谢
由 **A Thousand Details** 制作。基于 MIT 许可证 —— 尽情 fork、发布,只需保留版权声明。
建立在两个项目的逆向工程工作之上,如果没有它们,这一切都无法实现:
* [Deep-Symmetry/crate-digger](https://github.com/Deep-Symmetry/crate-digger) —
Pioneer PDB 和 ANLZ 格式的 Kaitai 规范。
* [xsco/libdjinterop](https://github.com/xsco/libdjinterop) — Engine schema
和 performance-blob 布局,以及从真实的 Engine OS 固件中捕获的参考数据库。
PenBridge 不附属于、未经认可也未被 Pioneer DJ、AlphaTheta、Denon DJ 或 inMusic 支持。rekordbox 和 Engine DJ 是其各自所有者的商标。
标签:Denon Engine, DJ工具, macOS原生应用, Rekordbox, SwiftUI, 文件系统管理, 音频库转换