标题: 三国志英杰传的音乐系统
性别:未知-离线 likelove

Rank: 2Rank: 2
组别 百姓
级别 破贼校尉
功绩 1
帖子 59
编号 56074
注册 2005-12-27


发表于 2025-8-2 12:19 资料 短消息 只看该作者
三国志英杰传的音乐系统

三国志英杰传的音乐系统
by likelove @xycq.org

关键词:三国志英杰传,Sangokushi Eiketsuden,音乐,音效,声音,adlib,opl

一、音乐系统简介
(注:涉及数字的一般均用16进制)
音乐系统是通过adlib及与其兼容的sound blaster系列声卡,fm音源,通过端口操作实现。驱动文件为sbopl2.com(我们简称为s文件),由启动文件reko3ibm加载并驻留内存,通过提供int8、int 66中断调用接口,具体实现相关设备的初始化、声音和音效播放等等。

二、主程序与驱动的交互过程
主程序中通过int 66指令或调用__int86与驱动程序交互,如播放、停止等功能。
驱动通过int 66的实现,读取数据、设置参数,并通过端口操作设置声卡;
驱动通过int 8实现定时器,读取数据、设置参数,并通过端口操作使声卡发声;
驱动通过int 8实现定时器,提供延时服务,用于动画切换。

三、int 66的子功能分两部分
1.高于80的功能号如f1等,与时钟有关,主要用于动画速度、时滞等。
2.低于80的功能号如0, 1等,与声音有关,其核心操作在于通过操作388, 389端口,实现与adlib声卡的交互。
根据adlib手册,该卡有240多个寄存器,其中388端口用于选择寄存器、决定读写哪个寄存器,389端口用于写的具体内容。因为寄存器选择和写数据后有个等待操作的“闲者时间”,所以会看到s_10782_WaitRegPort、 s_10792_WaitDataPort循环读取数据的等待。
参考了韩国大佬对功能号的解析,项目地址:github.com/likearome/OwnFMDRV
子功能号(ah寄存器):
0~9与音乐相关
0:初始化
1:播放。
2:停止
3:检查状态
4:设置循环播放
9:设置回调函数
10~13与音效相关
10:初始化
11:播放
12:停止
13:检查状态


四、int 8定时器功能
经初始化设置,时钟基本频率为291Hz,设置了4个子定时器,前2个与音乐播放相关,1个未用到,1个与动画计时相关。


五、音乐文件的格式
1.音乐文件为3个带music的r3文件,未压缩。opmusic、edmusic为开始和结束音乐,music为主乐库。
2.文件的基本结构由乐曲数、乐曲节表、乐曲数据构成,正常的小端模式:

乐曲数:开头2字节为乐曲总数,如music中为14。

乐曲节表:每个乐曲节表为6字节,低位4字节(或2字节?)为偏移地址,本乐曲数据的偏移,注意此偏移为相对数据区开始的偏移、而不是相对于music文件开始,所以一开始的偏移值为0;接下来2字节为乐曲数据长度。乐曲节表顺序排列。因空间过于紧张,到节表结束,其后没有用00字节填充,直接就接上了乐曲数据。

乐曲数据:节表之后就是乐曲数据,各乐曲顺序相接。假设我们要替换某乐曲,不仅要删除旧数据、插入新乐曲数据,还需要调整该乐曲节表中的长度、和其后所有乐曲节表的偏移值。
考虑到空间所限,乐曲数据总长度不超过ffff为好。

3.乐曲数据的基本格式。乐曲数据由音轨节表、基本属性数据和通道(音轨?)数据段构成:

音轨节表:占用E字节,共7 word,分别指明各音轨数据的偏移,没有数据的为0000,注意此偏移是相对于本乐曲数据初始位置而言的。

基本属性数据:每个属性长度16字节,其数量未定,为该音轨的乐器音色及有关控制字节,比如钢琴和小号是有区别的,音轨数据中将按指令读取音色数据,来指明音符是哪一种乐器。

音轨数据:接在基本属性数据之后,位置由前面的节表指定。其数据为基本类型为两类,一类是控制字节c0~ff,用于设置开始、结束、速度、响度、音色等;另一类是音符数据,范围0~5f、60~bf。
乐曲数据加载后,一些要素会记录入s文件一个结构体当中,在播放中相关的状态保存在该结构体中。
驱动程序通过int 8定时器去逐个循环读取音轨数据,通过写声卡端口方式实现声音。

4.格式转换的可行性
根据opl手册,adlib的音色文件一般为.ins文件,乐曲文件一般为.rol文件。实现r3与通用文件格式的转换在理论上有可能,实施起来有很大的难度。

5.音效数据在main.exe中,在seg004区段,音效数据偏移为47e,之前应为音色数据。


顶部
性别:未知-离线 likelove

Rank: 2Rank: 2
组别 百姓
级别 破贼校尉
功绩 1
帖子 59
编号 56074
注册 2005-12-27


发表于 2025-8-2 12:20 资料 短消息 只看该作者
koeimu使用
by likelove @xycq.org

目标是分析三国志英传的三个音乐文件。三国志4也可以。三国志5的格式有变化,结果不对。

使用方法:
将koeimu和待分析音乐文件放在一个文件夹下,
进入命令行,进入该文件夹
输入:koeimu,将显示本程序信息
再输入待分析文件,如music.r3
输入待分析乐曲序号,从0开始。music.r3的范围是0~19,opmusic.r3的范围是0~1,edmusic.r3的范围是0~2
文件无误的话会显示部分分析信息,乐曲数据分析结果将保存在result.txt中

乐曲中可能有段落反复、改变乐曲速度的指令,在这种情况下,时间估算是不准的,仅供参考吧


常见信息的含义(以下均为16进制):
I=f2 C=48  Hz=39
f2用于设置乐曲速度,通常出现在第0音轨的开头,此处参数48,换成时钟频率是39hz

I=f8 reset
f8指令通常出现在音轨开头

I=ff channel end
本音轨结束

I=f4 T=2da9
f4指令设置音色地址,作用是选择乐器。在一个音轨内可多次设置

I=f0 S=1c
f0指令设置响度,一般数值越大,声音越小

N=1c  K=E   O=2  R=60  P=2f
音符
K是音名,#是升号
O是八度,0~7组,数值越小八度音越低
R表示用多少tick去读下一指令,P表示本音符演奏多少个tick。
R>P时相当于加了休止符,等一些tick再去读指令;R<P时本音符没演奏结束就读入下一指令
有的音轨很多的K=C,该音轨一般为打击乐器

N=92  K=D   O=4
这类音符,时长沿用前面音符设置


I=d0 repeat begin
A段....
I=fd jump to 2nd room when repeat
B段....
I=d1 repeat 2 times
C段....

这几个指令是反复,中间有fd指令的,最后一次反复时到C段,即本例中演奏顺序为 A - B - A - C;中间如没有fd指令就是A - B - A - B - C

其他指令作用暂时未知


附件: koeimu.zip (2025-8-2 12:20, 86.88 K)
该附件被下载次数 2


顶部

正在浏览此帖的会员 - 共 1 人在线




当前时区 GMT+8, 现在时间是 2025-8-4 00:55
京ICP备2023018092号 轩辕春秋 2003-2023 www.xycq.org.cn

Powered by Discuz! 5.0.0 2001-2006 Comsenz Inc.
Processed in 0.008323 second(s), 10 queries , Gzip enabled

清除 Cookies - 联系我们 - 轩辕春秋 - Archiver - WAP