- UID
- 4293
- 精华
- 积分
- 11130
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
本帖最后由 系统消息 于 2019-8-28 20:52 编辑
原帖来源:【DirectX】用 DirectMusic 实现可更换音色库和多轨的 midiOuthttps://www.0xaa55.com/forum.php ... 59&fromuid=4293(出处: 技术宅的结界,转载请保留出处。)
参考来源:【C语言】Midi文件播放器(可跨平台)https://www.0xaa55.com/forum.php ... 89&fromuid=4293(出处: 技术宅的结界)
之前看过A5大神写的midi文件解析,并用winmm.dll的midiOut函数输出实现播放midi音乐,我在研究的过程发现了一些不太理想的问题:
1.midiOut 设备不能打开多个实例(也就基本上告别了同时播放多个文件),软件设备一个进程只能打开1个实例,硬件设备整个系统只能打开1个实例。
2.midiOut 设备没有多轨支持,A5大神的代码是忽略了音轨序号,这样做对于一些比较大的midi文件会出现冲突。
3.midiOut 设备没有精确时间控制,A5大神的代码是每Sleep1毫秒,更新一次midi进度,这样只能做到毫秒级精度控制,但是Sleep本身又不稳定。
4.midiOut 设备无法更换音色库,只能局限于midiOut设备驱动提供的音色。
5.midiOut API只能选择用哪个midi设备来合成声音,不能选择最终合成的声音输出到哪张声卡。
我在之前接触过DirectMusic,知道DirectMusic支持在应用层自行midi合成,再通过DirectSound做最终输出,因此以上问题在它这里都不是问题。
不过网上的DirectMusic资料全部是老掉牙的,只有上层接口的相关API调用代码(加载、解析midi文件都封装好了,完全不用接触底层),但是我想要的不是这些,而是像winmm.dll的midiOut,自己输出原始midi命令的功能,而且微软在很多年已经放弃了对DirectMusic的上层接口支持(x86下还在兼容,但新版DXSDK里面不再提供头文件了,x64下直接连dll都没有了),只有DirectMusic的底层接口微软一直提供支持(SDK一直在提供头文件,x64也有对于的dll),可是微软从来没有给过这方面的例子,只有接口描述文档,网上也找不到有人给过这方面的例子。于是我就自己慢慢研究DirectMusic的底层接口,最后终于成功自己实现midiOut的功能,再与A5大神的midi文件解析代码结合,不仅完美解决所有问题,还可以结合DirectSound实现音量、音高、平衡、3D空间音效以及DX8的声音特效。现在是时候来分享技术了:
DX MIDI 播放器
从上图可以看到,基于DirectMusic实现的MIDI播放器,我们除了可以更换midi文件外,还可以自由更换音色库文件,可以随时调节音量、音高、平衡,中间的输出内容就是A5大神的midi文件解析库的输出内容(A5大神原版是输出到控制台)。
提示:DirectMusic每个合成器实例最大支持1000个音轨,每个音轨又各自有16个独立通道(每个通道9都是架子鼓),但是这16000个通道都是在同一个DirectSoundBuffer上输出的,因此单独调整DirectSoundBuffer属性,请分别创建多个DirectMusicPort实例(并为它们各自己绑定一个DirectSoundBuffer)。
推荐用法:在一个游戏进程内同时播放多个midi文件时,只需要创建一个DirectSound+DirectMusic,给每个midi文件创建一个DirectSoundBuffer+DirectMusicPort,而同一个midi文件的多个音轨分配在同一个DirectMusicPort的不同通道组即可。
在附件中提供了,DXMIDIOut(用DX模拟的midiOut)、midiPlayer(MIDI播放器,不带GUI)、midiPiano(MIDI电钢琴)等源码,以及MIDI播放器和MIDI电钢琴的二进制文件(需要VC2013运行库)。
MIDI 电钢琴是模仿当年4399上的flash键盘钢琴做的,只不过我没有做界面(只有一个空白对话框,方便让你拖拽dls文件去更换音色库,不然我就直接做成控制台了)。
附件中的压缩包密码是没有密码的拼音,其中 ReadMe.txt 提供压缩包内文件描述,MusicScore.txt 是MIDI电钢琴的乐谱(从flash键盘钢琴上继承,少部分是我自己添加)。
提示:由于附件资源的大小有限,无法上传Demo中测试用的音色库文件(一百多兆),如有学习需要请QQ联系我,或者自己去网上找找。(如需商用请自己注意版权问题)。
免责声明:Demo中的资源文件全部来源网络,仅供学习参考,未避免版权纠纷问题,请勿用于商业。
|
|