Files
rix2midi/README.md
2026-08-22 05:54:36 +00:00

86 lines
3.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# rix-midi —— 《大富翁 2》RIX → MIDI 轉換器by Qwen 3.8:27B
把 DOS 遊戲《大富翁 2》的 `.RIX` 音樂檔,轉成標準 `.MIDI` 樂譜。
可以一次轉單一個、也可以整個資料夾批次轉。
> 同一批 `.RIX` 用 **adplay / AdPlug** 也可以轉成 WAV純音訊
> 這裡只處理「轉成 MIDI 樂譜」這件比較有挑戰的事。
---
## 為什麼 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
./rix2midi ./RICHU.RIX # 產出 RICHU.mid
./rix2midi ./RICHU.RIX 我的.mid # 指定輸出檔名
# 批次:把「整個資料夾」裡所有 .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/`)。