SDL_Mixer在Windows Vista/7上的MIDI音量问题

6
我并不精通C++或SDL_Mixer,但我代表Doom社区提出这个问题。简而言之,在Windows Vista或7上使用SDL_Mixer时,没有人能够弄清楚如何独立控制普通声音和MIDI声音的音量。让Eternity Engine的作者James Haley用他自己的话来说吧:“似乎在Windows Vista或7下,原生MIDI的独立音量概念不存在,因为在任何具有MIDI音量滑块的应用程序中(包括大多数使用SDL_mixer的游戏),都会影响数字声音输出的音量。这使得尝试调整音乐相对音量以获得舒适感变得不可能。” 有人找到了解决方法吗?考虑到微软似乎在整个操作系统中都缺乏控制单独声音设备音量的方式,我猜这是不可能的。 我听说过各种解决方法,都涉及Timidity驱动程序,但这需要用户超越仅仅在系统上安装游戏。我知道唯一一个明确解决此问题的端口是ZDoom,但它使用GPL不兼容的FModEx,因此不是一个合适的解决方案。
如果您想查看一些代码,Chocolate Doom可能是最容易理解的Doom源代码端口,您可以在此处获取其源代码here
欢迎提出其他开源声音和音乐库的建议。

1
为什么不直接将现有的MIDI文件转换为WAV(或任何可以解压缩为PCM流的文件格式),并将音乐流管理为您与其他声音混合的任何其他声音一样呢? - selbie
2
MIDI文件嵌入在.WAD数据文件中,有数以万计的用户制作的.WAD数据文件,其中一些可以追溯到1994年。预先进行转换可能行不通。程序本身有Timidity++和Fluidsynth可用于此操作,但我听说两种情况下的转换都不太令人满意。 - AlexMax
5个回答

1
一个解决方案是使用启用了FluidSynth的SDL_mixer。您还需要提供一个SoundFont2文件。幸运的是,有免费的SF2可用,其中一些甚至针对Doom的MIDI文件进行了优化。许可证不应该是问题,因为SoundFonts是资产,而不是代码。
然后,您可以使用Mix_SetSoundFonts()加载SF2。


0

0
所以我之前给出的答案有一个问题,就是有时候MIDI子进程不听话,会以奇怪的方式崩溃或停止工作。Eternity的具体实现使用了IDL,我个人使用管道重新实现了它,但子进程本身就是一个错误的磁铁。
幸运的是,最近又找到了另一个答案。你可以完全绕过SDL_Mixer,直接处理Windows的本机MIDI支持,一旦你知道该怎么做,其实并不需要很多代码。

https://github.com/chocolate-doom/chocolate-doom/blob/master/src/i_winmusic.c

您也可以使用PortMIDI实现此类想法,并获得能够与外部MIDI设备通信的好处。

https://github.com/odamex/odamex/blob/stable/client/sdl/i_musicsystem_portmidi.cpp


0
我正在维护一个类似的游戏端口(Descent 2),并且遇到了同样的问题。根据我所知,当使用SDL_mixer时,没有解决方案。我找到的避免声音在关闭midi音乐时被静音的方法是获取临时midi设备的句柄,将midi音量设置为最大,然后再关闭临时设备。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接