東方輝針城BGM解出

我是廢話

大家好,老實說我已經一段時間沒有更新我的 Blog 了,感覺上除了霉味外,我還看見了一大堆菇菇長出來了,當然自從有了工作以後真的時間並沒有比較多,應該說在工作性質的關係整天盯著螢幕真的回家後,看到有鍵盤的東西就一整個賭爛(嘆~!)。

正題開始

前幾天,東方例大祭 10 剛結束,當然神主 ZUN 也放出了新的試玩版,剛好手很癢的也去試玩了一下,但是我真的是彈幕苦手啊 QAQ... 老實說這不是重點...

這才是重點

老實說,沒次一看到一個有幸去的東西都會想要把他解剖出來看,就跟之前幫迷ゲーム解圖的感覺一樣,但是這只是讓我純粹筆記用,是不是有參考價值,老實說,網路上已經有一堆可以解 BGM 的程式了,我還在造輪子 ... OTZ,就只是好玩。而且這些資訊都是 google 來的,反正需要就參考吧,我只是把整個流程整理出來而已。

行前動作

這次的重點主要放在兩個檔案上 th14tr.datthbgm_tr.dat,但是重點還是 th14tr.dat 上,這是整個遊戲的腳本檔及特殊音效等都放在這裡,但是要解出來還是要靠特殊的程式 BrightMoon 這是一隻專門解出東方系列作品素材的程式,還好可以在 wine 底下運作無誤,因為這次的重點是 BGM 解出,其他的音效應該很容易吧。打開後會需要兩個檔案 thbgm_tr.fmtmusiccmt_tr.txt,先說 musiccmt_tr.txt 其實這只是音樂的標題及簡短介紹,我只是懶得打所以才解出來而已。

因為在 thbgm_tr.dat 這個檔案的開頭 4 bytes 就只有 ZWAV 而整串都是 PCM ,靠得就是 th14tr.dat/thbgm_tr.fmt 這個檔案 info 說何時要 loop ,如果用 Hexedit 等工具看到的話就會是這種狀況:

00000000   74 68 31 34  5F 30 31 2E  77 61 76 00  00 00 00 00  th14_01.wav.....
00000010   10 00 00 00  60 2F 3D 01  D0 AD 2B 00  60 2F 3D 01  ....`/=...+.`/=.
00000020   01 00 02 00  44 AC 00 00  10 B1 02 00  04 00 10 00  ....D...........
00000030   00 00 00 00  74 68 31 34  5F 30 32 2E  77 61 76 00  ....th14_02.wav.
00000040   00 00 00 00  70 2F 3D 01  00 29 F9 00  C0 D8 15 00  ....p/=..)......
00000050   00 29 F9 00  01 00 02 00  44 AC 00 00  10 B1 02 00  .)......D.......
00000060   04 00 10 00  00 00 00 00  74 68 31 34  5F 30 33 2E  ........th14_03.
00000070   77 61 76 00  00 00 00 00  70 58 36 02  00 30 F1 00  wav.....pX6..0..
00000080   80 51 06 00  00 30 F1 00  01 00 02 00  44 AC 00 00  .Q...0......D...
00000090   10 B1 02 00  04 00 10 00  00 00 00 00  74 68 31 34  ............th14
000000A0   5F 30 34 2E  77 61 76 00  00 00 00 00  70 88 27 03  _04.wav.....p.'.
000000B0   70 8A 12 01  80 24 29 00  70 8A 12 01  01 00 02 00  p....$).p.......
000000C0   44 AC 00 00  10 B1 02 00  04 00 10 00  00 00 00 00  D...............
000000D0   74 68 31 34  5F 30 35 2E  77 61 76 00  00 00 00 00  th14_05.wav.....
000000E0   E0 12 3A 04  E0 11 23 01  30 A1 05 00  E0 11 23 01  ..:...#.0.....#.
000000F0   01 00 02 00  44 AC 00 00  10 B1 02 00  04 00 10 00  ....D...........
00000100   00 00 00 00  74 68 31 34  5F 30 36 2E  77 61 76 00  ....th14_06.wav.
00000110   00 00 00 00  C0 24 5D 05  90 C5 85 01  F0 02 0F 00  .....$].........
00000120   90 C5 85 01  01 00 02 00  44 AC 00 00  10 B1 02 00  ........D.......
00000130   04 00 10 00  00 00 00 00  74 68 31 34  5F 30 37 2E  ........th14_07.
00000140   77 61 76 00  00 00 00 00  50 EA E2 06  80 22 1D 01  wav.....P...."..
00000150   40 CF 23 00  80 22 1D 01  01 00 02 00  44 AC 00 00  @.#.."......D...
00000160   10 B1 02 00  04 00 10 00  00 00 00 00  74 68 31 32  ............th12
---  thbgm_tr.fmt       --0x0/0x1B1--------------------------------------------
generate by Hexedit

可以很清楚的看出規律,其實就是 52bytes 一個 block ,另外寫一隻 python 讓整個看起來更有規律:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
for i in range(8):
    f.seek(i*52)
    j=f.read(52)
    k = list(struct.unpack('16s4s4s4s4s4s4s4s4s4s', j))
    t = k.pop(0).strip()
    lsta=[]
    for l in k:
        lst=[]
        for ch in l:
            hv = hex(ord(ch)).replace('0x', '')
            if len(hv) == 1:
                hv = '0'+hv
            lst.insert(0,hv)
        lsta.append(' '.join(lst))
    print t, '  '.join(lsta)

解出後就是這樣子:


   name        seek         full         intro        full      以下unknow
                            (len)        (len)        (len)
th14_01.wav 00 00 00 10  01 3d 2f 60  00 2b ad d0  01 3d 2f 60  00 02 00 01  00 00 ac 44  00 02 b1 10  00 10 00 04  00 00 00 00
th14_02.wav 01 3d 2f 70  00 f9 29 00  00 15 d8 c0  00 f9 29 00  00 02 00 01  00 00 ac 44  00 02 b1 10  00 10 00 04  00 00 00 00
th14_03.wav 02 36 58 70  00 f1 30 00  00 06 51 80  00 f1 30 00  00 02 00 01  00 00 ac 44  00 02 b1 10  00 10 00 04  00 00 00 00
th14_04.wav 03 27 88 70  01 12 8a 70  00 29 24 80  01 12 8a 70  00 02 00 01  00 00 ac 44  00 02 b1 10  00 10 00 04  00 00 00 00
th14_05.wav 04 3a 12 e0  01 23 11 e0  00 05 a1 30  01 23 11 e0  00 02 00 01  00 00 ac 44  00 02 b1 10  00 10 00 04  00 00 00 00
th14_06.wav 05 5d 24 c0  01 85 c5 90  00 0f 02 f0  01 85 c5 90  00 02 00 01  00 00 ac 44  00 02 b1 10  00 10 00 04  00 00 00 00
th14_07.wav 06 e2 ea 50  01 1d 22 80  00 23 cf 40  01 1d 22 80  00 02 00 01  00 00 ac 44  00 02 b1 10  00 10 00 04  00 00 00 00

知道這些東西後就很方便了,接著就可以手動解出這些音樂,以下過程參考了這些資料 http://goo.gl/Z23iZ ,者裡以解出第一首為例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
dat_path = ur'thbgm.dat'
f = open(dat_path, 'rb')
f.seek(0x10)              #第二首就插入其 seek HEX
intro = f.read(0x2badd0)  #插入intro len HEX
loop = f.read(0x1118190)  #插入(full len)-(intro len) HEX
f.close()
import wave
w = wave.open(u'th14tr_01.wav', 'wb')
w.setnchannels(2)
w.setsampwidth(2)
w.setframerate(44100)
w.writeframes(intro)
for i in range(2)
    w.writeframes(loop)
w.close()

此時 wave 應該就可以聽了,先暫時筆記到此晚點看看能不能把整個 script 寫出來...

Sat Jun. 8 2013
Comments

Comments