Проблемы с громкостью SDL_mixer MIDI в Windows Vista / 7

#c #windows #sdl #midi #sdl-mixer

#c #Windows #sdl #midi #sdl-микшер

Вопрос:

На самом деле я не очень хорошо разбираюсь в C или SDL_mixer, но я все равно задаю этот вопрос от имени сообщества Doom. Проще говоря, никто, пишущий исходные порты Doom, не может понять, как независимо управлять обычной громкостью звука и громкостью MIDI звука с помощью SDL_mixer в Windows Vista или 7. Я позволю Джеймсу Хейли, автору Eternity Engine, изложить это своими словами:

Похоже, концепция независимой громкости для встроенного MIDI не существует в Windows Vista или 7, поскольку использование ползунков громкости MIDI в любом приложении, в котором они есть (включая большинство игр, использующих SDL_mixer), также влияет на громкость цифрового звукового вывода. Это делает невозможными попытки настроить относительную громкость музыки для удобства.

Кто-нибудь нашел какие-либо обходные пути для этого? Я предполагаю, что это маловероятно, учитывая, как Microsoft, похоже, обошла всю ОС стороной в любом способе управления громкостью отдельных звуковых устройств по отдельности.

Я слышал о различных обходных путях, все из которых связаны с драйвером Timidity, но это требует от пользователя сделать больше, чем просто установить игру в свою систему. Единственный известный мне порт, который окончательно устраняет эту проблему, — это ZDoom, но он использует FModEx, несовместимый с GPL, и поэтому не является подходящим решением.

Если вам нужен какой-нибудь код для просмотра, Chocolate Doom, пожалуй, самый простой исходный порт Doom для грокинга, и вы можете получить его исходный код здесь.

Также приветствуются любые предложения по другим библиотекам звука и музыки с открытым исходным кодом.

Комментарии:

1. Почему бы просто не преобразовать существующие MIDI-файлы в WAV (или любой формат файла, который можно распаковать в поток PCM) и управлять музыкальным потоком, как если бы это был любой другой звук, с которым вы микшируете?

2. Файлы MIDI встроены в . Множество файлов данных, и их десятки тысяч, созданных пользователем. Файлы данных WAD, некоторые из которых датируются 1994 годом. О предварительном преобразовании, вероятно, не может быть и речи. Для этого в самой программе есть Timidity и Fluidsynth, но я слышал жалобы на менее чем удовлетворительные преобразования в обоих случаях.

Ответ №1:

Решением было бы поставлять SDL_mixer с поддержкой FluidSynth. Вам также потребуется отправить файл SoundFont2 в комплекте с ним. К счастью, существуют бесплатные версии SF2, а некоторые даже оптимизированы для MIDI-файлов Doom. Лицензии не должны быть проблемой, поскольку звуковые шрифты — это ресурсы, а не код.

Затем вы загружаете SF2 с помощью Mix_SetSoundFonts().

Ответ №2:

Возможно, вы захотите ознакомиться с другими библиотеками MIDI за пределами SDL.

http://wildmidi.sourceforge.net/

http://sourceforge.net/apps/trac/fluidsynth/

http://timidity.sourceforge.net

Ответ №3:

Я поддерживаю аналогичный игровой порт (Descent 2), и я столкнулся с той же проблемой. Afaik, для этого нет решения при использовании SDL_mixer. Способ избежать отключения звука при выключении музыки midi, который я нашел, — это восстановить дескриптор временного midi-устройства, установить громкость midi на max, а затем снова закрыть временное устройство.

Ответ №4:

Долгое время единственным решением, которое мы нашли, было использование чего-то вроде PortMidi. Тем не менее, Quasar of Eternity Engine нашел отличное решение:

http://www.doomworld.com/vb/showthread.php?s=amp;postid=1124981#post1124981

По сути, он помещает SDL_mixer в свой собственный процесс и управляет им с помощью RPC. Очень умный.

Ответ №5:

Итак, одна из проблем с предыдущим ответом, который я дал, заключалась в том, что иногда подпроцесс MIDI не вел себя должным образом и странным образом прерывался или переставал работать. Конкретная реализация Eternity использовала IDL, и я лично повторно внедрил ее с использованием каналов, но сам подпроцесс был магнитом для ошибок.

К счастью, совсем недавно был найден другой ответ. Вы можете просто полностью обойти SDL_mixer и напрямую обращаться к встроенной поддержке MIDI Windows, что, оказывается, не требует тонны кода, как только вы знаете, что делаете.

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