mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-28 06:53:40 +00:00
- Do not call midiOutSetVolume() when playing with the "Microsoft GS Wavetable Synth" on
Vista and above, because it doesn't do what you expect. SVN r2136 (trunk)
This commit is contained in:
parent
02909bd71c
commit
5125e11d25
1 changed files with 74 additions and 4 deletions
|
@ -41,6 +41,10 @@
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "m_swap.h"
|
#include "m_swap.h"
|
||||||
|
|
||||||
|
#ifndef __GNUC__
|
||||||
|
#include <mmdeviceapi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||||
|
@ -49,6 +53,8 @@
|
||||||
|
|
||||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||||
|
|
||||||
|
static bool IgnoreMIDIVolume(UINT id);
|
||||||
|
|
||||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||||
|
|
||||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
@ -100,11 +106,18 @@ int WinMIDIDevice::Open(void (*callback)(UINT, void *, DWORD, DWORD), void *user
|
||||||
|
|
||||||
if (err == MMSYSERR_NOERROR)
|
if (err == MMSYSERR_NOERROR)
|
||||||
{
|
{
|
||||||
// Set master volume to full, if the device allows it on this interface.
|
if (IgnoreMIDIVolume(DeviceID))
|
||||||
VolumeWorks = (MMSYSERR_NOERROR == midiOutGetVolume((HMIDIOUT)MidiOut, &SavedVolume));
|
|
||||||
if (VolumeWorks)
|
|
||||||
{
|
{
|
||||||
VolumeWorks &= (MMSYSERR_NOERROR == midiOutSetVolume((HMIDIOUT)MidiOut, 0xffffffff));
|
VolumeWorks = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Set master volume to full, if the device allows it on this interface.
|
||||||
|
VolumeWorks = (MMSYSERR_NOERROR == midiOutGetVolume((HMIDIOUT)MidiOut, &SavedVolume));
|
||||||
|
if (VolumeWorks)
|
||||||
|
{
|
||||||
|
VolumeWorks &= (MMSYSERR_NOERROR == midiOutSetVolume((HMIDIOUT)MidiOut, 0xffffffff));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -391,4 +404,61 @@ void CALLBACK WinMIDIDevice::CallbackFunc(HMIDIOUT hOut, UINT uMsg, DWORD_PTR dw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// IgnoreMIDIVolume
|
||||||
|
//
|
||||||
|
// Should we ignore this MIDI device's volume control even if it works?
|
||||||
|
//
|
||||||
|
// Under Windows Vista and up, when using the standard "Microsoft GS
|
||||||
|
// Wavetable Synth", midiOutSetVolume() will affect the application's audio
|
||||||
|
// session volume rather than the volume for just the MIDI stream. At first,
|
||||||
|
// I thought I could get around this by enumerating the streams in the
|
||||||
|
// audio session to find the MIDI device's stream to set its volume
|
||||||
|
// manually, but there doesn't appear to be any way to enumerate the
|
||||||
|
// individual streams in a session. Consequently, we'll just assume the MIDI
|
||||||
|
// device gets created at full volume like we want. (Actual volume changes
|
||||||
|
// are done by sending MIDI channel volume messages to the stream, not
|
||||||
|
// through midiOutSetVolume().)
|
||||||
|
//
|
||||||
|
// This is using VC++'s __uuidof extension instead of the the CLSID_ and
|
||||||
|
// IID_ definitions because I couldn't figure out why it wasn't finding them
|
||||||
|
// when linking, and __uuidof circumvents that problem. I'd also be
|
||||||
|
// surprised if w32api includes any WASAPI stuff any time soon, so it's no
|
||||||
|
// big loss making this VC++-specific for the time being
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static bool IgnoreMIDIVolume(UINT id)
|
||||||
|
{
|
||||||
|
#ifndef __GNUC__
|
||||||
|
MIDIOUTCAPS caps;
|
||||||
|
|
||||||
|
if (MMSYSERR_NOERROR == midiOutGetDevCaps(id, &caps, sizeof(caps)))
|
||||||
|
{
|
||||||
|
// The Microsoft GS Wavetable Synth advertises itself as MOD_SWSYNTH with a VOLUME control.
|
||||||
|
// If the one we're using doesn't match that, we don't need to bother checking the name.
|
||||||
|
if (caps.wTechnology == MOD_SWSYNTH && (caps.dwSupport & MIDICAPS_VOLUME))
|
||||||
|
{
|
||||||
|
if (strncmp(caps.szPname, "Microsoft GS", 12) == 0)
|
||||||
|
{
|
||||||
|
IMMDeviceEnumerator *enumerator;
|
||||||
|
|
||||||
|
// Now try to create an IMMDeviceEnumerator interface. If it succeeds,
|
||||||
|
// we know we're using the new audio stack introduced with Vista and
|
||||||
|
// should ignore this MIDI device's volume control.
|
||||||
|
if (SUCCEEDED(CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL,
|
||||||
|
__uuidof(IMMDeviceEnumerator), (void**)&enumerator))
|
||||||
|
&& enumerator != NULL)
|
||||||
|
{
|
||||||
|
enumerator->Release();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue