找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 6119|回复: 16

【DirectX】用 DirectMusic 实现可更换音色库和多轨的 midiOut

[复制链接]
发表于 2019-8-28 01:13:09 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 系统消息 于 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 播放器

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中的资源文件全部来源网络,仅供学习参考,未避免版权纠纷问题,请勿用于商业。

dxmidilib_src.rar

16.68 KB, 阅读权限: 20, 下载次数: 14

售价: 1 个宅币  [记录]

DXMIDI库源码

dxmidilib_bin.rar

195.57 KB, 下载次数: 17

DXMIDI库测试Demo

回复

使用道具 举报

发表于 2019-9-30 23:47:53 | 显示全部楼层
YY菌的改良效果不错!
回复 赞! 1 靠! 0

使用道具 举报

发表于 2019-8-28 10:17:44 | 显示全部楼层
我记得我似乎没有忽略多音轨的问题
回复 赞! 1 靠! 0

使用道具 举报

发表于 2019-8-28 12:01:31 | 显示全部楼层
支持系统消息大佬。
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2019-8-28 19:32:05 | 显示全部楼层
本帖最后由 系统消息 于 2019-8-28 19:42 编辑
0xAA55 发表于 2019-8-28 10:17
我记得我似乎没有忽略多音轨的问题


你的是解析多轨的确是对的,我是说最后用midiOutShortMsg输出的时候,你忽略了音轨参数,直接把所有音轨往同一个音轨上输出的。
举个例子,假如说音轨1和音轨2在同时在使用通道1,它们就会发生冲突,比如音轨1把通道1设成钢琴,音轨2把通道1设成小提琴,谁执行的晚一步就会覆盖上一个音轨内容,还有就是两个音轨互相开关冲突问题。
DirectMusic的多轨机制是每个音轨各自都有独立的16个通道,音轨1的通道1和音轨2的通道1是两个单独的通道实例。
我帖子截图里面那个梁祝.mid就存在这个现象(好像有三十多个音轨),从截图上的输出内容可以看出20、21、22三个音轨在同时使用D(13)通道,改用DirectMusic的多轨机制后就正常了。
回复 赞! 靠!

使用道具 举报

发表于 2019-8-28 22:05:00 | 显示全部楼层
系统消息 发表于 2019-8-28 19:32
你的是解析多轨的确是对的,我是说最后用midiOutShortMsg输出的时候,你忽略了音轨参数,直接把所有音轨 ...


与其说我忽略了多音轨的问题,不如说,我把音轨和通道概念搞混了。

图片是多年前写的VB6播放midi时解析midi字节的逻辑
20190828225538.png
回复 赞! 靠!

使用道具 举报

发表于 2019-9-30 23:27:12 | 显示全部楼层
我就坐等你出vb6版的再下载
回复 赞! 靠!

使用道具 举报

发表于 2020-2-12 16:59:50 | 显示全部楼层
膜拜大佬
回复

使用道具 举报

发表于 2020-4-21 19:27:40 | 显示全部楼层
好了,不过你啥时解决一下大文件卡住的问题 ?
回复 赞! 靠!

使用道具 举报

发表于 2021-6-21 06:38:50 | 显示全部楼层
正需要这个代码,音色库在什么地方下载?
回复 赞! 靠!

使用道具 举报

发表于 2021-6-21 06:40:27 | 显示全部楼层
手上有sf2音色库,可以转成dls音色库吗
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2021-6-21 09:58:06 | 显示全部楼层
clhenyan 发表于 2021-6-21 06:40
手上有sf2音色库,可以转成dls音色库吗

可以,有专门的音色库格式转换工具(比如Awave Studio)。
回复 赞! 靠!

使用道具 举报

发表于 2022-1-18 02:28:46 | 显示全部楼层
系统消息YYDS
回复 赞! 靠!

使用道具 举报

发表于 2022-3-25 19:00:40 | 显示全部楼层
牛蛙 牛蛙
回复

使用道具 举报

发表于 2022-3-29 10:55:26 | 显示全部楼层
大神,可以提供一下源代码研究研究嘛,最近在弄这个
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2022-3-29 22:26:20 | 显示全部楼层
COCO在丫 发表于 2022-3-29 10:55
大神,可以提供一下源代码研究研究嘛,最近在弄这个

源码不是在附件里面吗?
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-22 02:11 , Processed in 0.044235 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表