关于东方音乐的播放器代码分析及一些结论
本帖最后由 kelvin 于 2013-12-17 13:12 编辑我用UE32看到的曲(NO.16 麓の神社)开始的数据的确是00 00 00 00 00 00……,
但那个开始循环的地址用UE32看不出来。
于是用FILEMON检测游戏里的music room,发现如:
116 18:01:34 th10.exe:2860 FASTIO_READ G:\LocalGame\东方TH10\th10\thbgm.dat SUCCESS
Offset: 365698768 Length: 705600
这句,把365698768换成16进制(15CC1ED0)到UE32里看数据,恰好是00 00 00 00 00 00…
…,然后就
该曲开始的地址:15CC1ED0
接下来下面的有:
858 18:02:58 th10.exe:2860 FASTIO_READ G:\LocalGame\东方TH10\th10\thbgm.dat SUCCESS
Offset: 381045568 Length: 44100
859 18:02:58 th10.exe:2860 FASTIO_READ G:\LocalGame\东方TH10\th10\thbgm.dat SUCCESS
Offset: 381089668 Length: 31052
860 18:02:58 th10.exe:2860 IRP_MJ_READ* G:\LocalGame\东方TH10\th10\thbgm.dat
SUCCESS Offset: 373702656 Length: 16384
861 18:02:58 th10.exe:2860 FASTIO_READ G:\LocalGame\东方TH10\th10\thbgm.dat SUCCESS
Offset: 373705424 Length: 13048
红字部分,程序读到381089668(16B6F784)又跳回去了373702656(16464000),
开始循环的地址:16464000
该曲结束的地址:16B6F784
代入公式得(注意:是16进制减法,可用MS计算器)
前奏部分长度=开始循环的地址-该曲开始的地址=16464000-15CC1ED0=7A2130
循环部分长度=该曲结束的地址-循环部分地址=16B6F784-16464000=70B784
于是:
BGM = 麓の神社, 0x15CC1ED0, 0x7A2130, 0x16464000, 0x70B784
http://bbs.thproject.net/read.php?tid=84702这篇帖子是看到以上帖子的启发而写出来的,总结要点如下:
東方風神録:
16.麓の神社:开始地址:15CC1ED0(365698768)
[开始]循环地址:16464000(373702656)
结束地址:16B6F784(381089668) (均为16进制)
由前奏部分长度(B)=[开始]循环的地址(C)-开始地址(A)
=16464000-15CC1ED0=7A2130
得:开始循环的地址(C)=前奏[部分]长度(B)+开始地址(A)
由循环部分长度(D)=结束的地址(X)-[开始]循环部分地址(C)
=16B6F784-16464000=70B784
得:结束的地址(X)=[开始]循环部分地址(C)+循环部分长度(D)
在東方Wiki查找资料时,发现了東方蓄音機这个播放软件,特点之一就是播放器代码开放,
可以随意复制,添加新作的代码.
仍以上面的麓の神社为例,在東方蓄音機的代码如下:
15CC1ED0,007A2130,007130D0,麓の神社
从左到右依次是开始地址,前奏部分长度,循环部分长度,曲名
而另一个国人写的播放器BgmForAll同一首曲子的代码是:
麓の神社, 0x15CC1ED0, 0x7A2130, 0x16464000, 0x7130D0
从左到右依次是曲名,开始地址,前奏部分长度,[开始]循环部分地址,循环部分长度
仔细对比后会发现,東方蓄音機没有"[开始]循环部分地址"的代码,而BgmForAll有,
要编辑BgmForAll这部分的代码,怎么办呢?
根据前面得出的结论:开始循环的地址(C)=前奏[部分]长度(B)+开始地址(A)
即:15CC1ED0+7A2130=16464000
这样代码编辑的问题就解决了.
--------------------------------------------------------------------------------------------------
另一个重要发现:
在我们用BgmForAll或者THxxBGM时,保存的音乐都放在播放器指定的目录下,要查看音乐
的长度往往都要其他的音乐编辑软件(如Cool Edit Pro2等)打开才能查看,比较麻烦,有没有
更方便的方法呢?
实际上,在前面提到的那篇帖子,在发帖之后就注意到这个问题,在从紅魔郷到輝針城的180
多首音乐中仔细寻找(详细请看附件),发现輝針城的リバースイデオロギー的循环部分长
度刚好是2分06秒整,而文件大小是1532610(16进制,即22226448字节),那么有:
22226448字节÷126秒=176400.380952......字节/秒,这个代表什么呢?
就是每秒.wav格式的文件大小是176400字节(即172.265625kB,小数部分忽略不计)
且WAV格式只限定16位深,采样率为44.1kHz的文件(其他格式不能保证)
也就是说,用某一首曲子的"前奏[部分]长度"和"循环部分长度"的地址[代码],除以176400,得
数就是该曲子前奏[部分]长度和循环部分长度的时间长(单位为秒,保留小数点后三位,不
要四舍五入)。
以輝針城的"幻想浄瑠璃"为例,前奏[部分]长度是5240E0(即5390560字节),用刚刚得出的结论,有:5390560÷176400=30.558秒,即前奏长30.558秒;
同理,循环部分长度是130F160(即19984736字节),同样有:19984736÷176400=113.292秒,即循环部分长1分53.292秒.
当然,在这180多首曲子里,只有那么极个别的几首有误差(都在1毫秒左右),不过这也是相当准确了.补充:東方蓄音機,该播放器只能播放,不能提取;而BgmForAll既能播放,又能提取,而且还有一个特别功能:"将前奏部分和循环部分
分开保存",这功能给偶帮了不少忙.
附件是与本帖相关的一些数据.
以下是一些推论:
对应文件大小时间长16进制代码
176400字节1秒2B110
176字节1毫秒B0
10584000字节1分钟A17FC0
……
……
完全看不懂 可惜专业不对口……要不然……真的很酷啊 专业对口的表示鸭梨山大 。。。总之意思是东方的音乐很厉害
的意思吧 关于第二条,用文件大小与音乐时长直接挂钩是不对的,因为文件本身的大小除了音乐数据本身之外还包括了一些格式性的东西,就算只是纯WAV的文件也有个文件头。 完全看不懂。。。
页:
[1]