Files
rix2midi/README.md

86 lines
3.7 KiB
Markdown
Raw Permalink Normal View History

2026-08-22 05:54:36 +00:00
# rix-midi —— 《大富翁 2》RIX → MIDI 轉換器by Qwen 3.8:27B
2026-08-22 05:52:55 +00:00
把 DOS 遊戲《大富翁 2》的 `.RIX` 音樂檔,轉成標準 `.MIDI` 樂譜。
可以一次轉單一個、也可以整個資料夾批次轉。
> 同一批 `.RIX` 用 **adplay / AdPlug** 也可以轉成 WAV純音訊
2026-08-22 05:53:57 +00:00
> 這裡只處理「轉成 MIDI 樂譜」這件比較有挑戰的事。
2026-08-22 05:52:55 +00:00
---
## 為什麼 RIX 不能直接「拿出來」當 MIDI
`.RIX` **不是存音符**的格式。它是 **AdLib OPL 晶片**的「機器碼」:
一段由「時鐘節拍tick」驅動的下載程式每個 tick 告訴 OPL 晶片
要寫哪些「暫存器」(頻率、開聲、音量……)。所以 RIX 裡只有
「要讓硬體發出什麼」的指令,沒有現成的音符——得「還原」出來。
## 原理(我們怎麼還原)
1. **借用 AdPlug** 來 decode + 模擬 OPL 晶片(它已把 RIX 的機器碼
正確地「跑成」一串 OPL 暫存器寫入)。
2. **劫持 OPL 的 write()**AdPlug 發聲前會走 `Copl::write(reg,val)`
我們繼承它的模擬器、順手把「每個 tick、每個聲道的 A / B 暫存器」記下。
3. **暫存器 → 頻率 → 音符**OPL 的標準公式):
```
F-number = A暫存器(低8位) | B暫存器bit0-1(高2位)
block = B暫存器 bit2-4 (決定八度倍頻)
key-on = B暫存器 bit5 1=開、0=關)
頻率Hz = F-number × 2^block × 3579545 / (72 × 2^24) × 8
MIDI音符 = round( 69 + 12×log2( 頻率 / 440 ) ) # 69 = A4, 60 = 中音C
```
4. **節奏一致**:測出 RIX 是「70 tick / 秒」。把 MIDI 速度設成
`tempo = 1e6 × 96 ÷ 70 ≈ 1,371,428 µs/quat`96 ticks/quat
讓 1 個 RIX tick == 1 個 MIDI tick整首的時值就和原曲一致。
5. **樂器**OPL 不分旋律/和聲,依每個聲道音高的「中位數」粗略指派
GM 樂器(偏低→貝斯、其餘→方波 Lead。聽起來像原曲的務實選擇。
### 已驗證
對全部 23 首,**MIDI 時長與同曲 WAV 時長比對22 首幾乎完全一致ratio 1.00**、
1 首RICHX因 WAV 尾端多靜音而略短。音高也抽樣驗證正確(中音 C=60
---
## 編譯
依賴 **AdPlug**RIX/OPL**libbinio**`build.sh` 會自動找/編它們,
再以**靜態連結**產出自給自足的執行檔(不用設 `LD_LIBRARY_PATH`
```bash
./build.sh # 在本機 AdPlug=/tmp/AdPlug、libbinio=/tmp/libbinio 的前提下
```
想指定位置:
```bash
ADPLUG=/path/to/AdPlug BINIO=/path/to/libbinio ./build.sh
```
## 使用
```bash
./rix2midi --help
# 單一個 .RIX → 同名 .mid
2026-08-22 05:53:57 +00:00
./rix2midi ./RICHU.RIX # 產出 RICHU.mid
./rix2midi ./RICHU.RIX 我的.mid # 指定輸出檔名
2026-08-22 05:52:55 +00:00
# 批次:把「整個資料夾」裡所有 .RIX 轉到「輸出資料夾」
./rix2midi ../ ../mid # ../ 所有 .RIX → ../mid/*.mid
./rix2midi -v ../ ../mid # 加 -v 看 tick 數等詳細訊息
```
## 檔案
| 檔案 | 說明 |
|--------------|----------------------------------------|
| `rix2midi.cpp` | 轉換器本體(含完整中文註解) |
| `build.sh` | 一鍵編譯(找/編 AdPlug、靜態連結 |
| `rix2midi` | 編譯出的執行檔 |
## 小限制MIDI 本質)
- 只能還原 OPL「發聲的音色」層次的音高+時值,是**旋律骨架**
不是完整編曲(沒有真正的和聲/鼓聲)——這是 RIX/OPL 格式的天花板。
- 樂器指派是「猜」的(依音域),不是原曲精確編配。
- 若你想要「聽起來就等於 DOS 原版」的 WAV用 adplay 那一套(`../wav/`)。