2009-01-31 22:11:09 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Sound System "MME Buddy" Library
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
|
|
* FILE: lib/drivers/sound/mmebuddy/mmewrap.c
|
|
|
|
*
|
|
|
|
* PURPOSE: Interface between MME functions and MME Buddy's own.
|
|
|
|
*
|
|
|
|
* PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
|
|
|
|
*/
|
|
|
|
|
2011-07-28 16:17:04 +00:00
|
|
|
#include "precomp.h"
|
2009-01-31 22:11:09 +00:00
|
|
|
|
2009-10-26 00:15:22 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
Sets the device into running or stopped state
|
|
|
|
*/
|
|
|
|
|
|
|
|
MMRESULT
|
|
|
|
MmeSetState(
|
2010-06-04 18:37:14 +00:00
|
|
|
IN DWORD_PTR PrivateHandle,
|
2009-10-26 00:15:22 +00:00
|
|
|
IN BOOL bStart)
|
|
|
|
{
|
|
|
|
MMRESULT Result;
|
|
|
|
PMMFUNCTION_TABLE FunctionTable;
|
|
|
|
PSOUND_DEVICE SoundDevice;
|
|
|
|
PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
|
2011-02-25 14:10:31 +00:00
|
|
|
BOOL OldState;
|
2009-10-26 00:15:22 +00:00
|
|
|
|
|
|
|
VALIDATE_MMSYS_PARAMETER( PrivateHandle );
|
|
|
|
SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle;
|
|
|
|
|
|
|
|
VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
|
|
|
|
|
|
|
|
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
|
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
|
|
|
/* Get the function table, and validate it */
|
|
|
|
Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
|
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
|
|
|
SND_ASSERT( FunctionTable->SetState );
|
|
|
|
if ( FunctionTable->SetState == NULL )
|
|
|
|
{
|
|
|
|
/* FIXME */
|
|
|
|
return MMSYSERR_NOTSUPPORTED;
|
|
|
|
}
|
|
|
|
/* Try change state */
|
|
|
|
Result = FunctionTable->SetState(SoundDeviceInstance, bStart);
|
|
|
|
|
2011-02-25 14:10:31 +00:00
|
|
|
if ( MMSUCCESS(Result) )
|
|
|
|
{
|
|
|
|
/* Get old audio stream state */
|
|
|
|
OldState = SoundDeviceInstance->bPaused;
|
|
|
|
|
|
|
|
/* Store audio stream pause state */
|
|
|
|
SoundDeviceInstance->bPaused = !bStart;
|
|
|
|
|
2014-11-16 14:07:37 +00:00
|
|
|
if (SoundDeviceInstance->bPaused == FALSE && OldState)
|
2011-02-25 14:10:31 +00:00
|
|
|
{
|
|
|
|
InitiateSoundStreaming(SoundDeviceInstance);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-26 00:15:22 +00:00
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2009-01-31 22:11:09 +00:00
|
|
|
/*
|
|
|
|
Call the client application when something interesting happens (MME API
|
|
|
|
defines "interesting things" as device open, close, and buffer
|
|
|
|
completion.)
|
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
NotifyMmeClient(
|
|
|
|
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
|
2010-06-04 18:37:14 +00:00
|
|
|
IN UINT Message,
|
|
|
|
IN DWORD_PTR Parameter)
|
2009-01-31 22:11:09 +00:00
|
|
|
{
|
|
|
|
SND_ASSERT( SoundDeviceInstance );
|
|
|
|
|
|
|
|
SND_TRACE(L"MME client callback - message %d, parameter %d\n",
|
|
|
|
(int) Message,
|
|
|
|
(int) Parameter);
|
|
|
|
|
|
|
|
if ( SoundDeviceInstance->WinMM.ClientCallback )
|
|
|
|
{
|
|
|
|
DriverCallback(SoundDeviceInstance->WinMM.ClientCallback,
|
|
|
|
HIWORD(SoundDeviceInstance->WinMM.Flags),
|
|
|
|
SoundDeviceInstance->WinMM.Handle,
|
|
|
|
Message,
|
|
|
|
SoundDeviceInstance->WinMM.ClientCallbackInstanceData,
|
|
|
|
Parameter,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
This is a helper function to alleviate some of the repetition involved with
|
|
|
|
implementing the various MME message functions.
|
|
|
|
*/
|
|
|
|
MMRESULT
|
|
|
|
MmeGetSoundDeviceCapabilities(
|
|
|
|
IN MMDEVICE_TYPE DeviceType,
|
|
|
|
IN DWORD DeviceId,
|
|
|
|
IN PVOID Capabilities,
|
|
|
|
IN DWORD CapabilitiesSize)
|
|
|
|
{
|
|
|
|
PSOUND_DEVICE SoundDevice;
|
|
|
|
MMRESULT Result;
|
|
|
|
|
|
|
|
SND_TRACE(L"MME *_GETCAPS for device %d of type %d\n", DeviceId, DeviceType);
|
|
|
|
|
2009-02-22 22:31:26 +00:00
|
|
|
/* FIXME: Validate device ID */
|
2009-01-31 22:11:09 +00:00
|
|
|
VALIDATE_MMSYS_PARAMETER( Capabilities );
|
2009-02-22 22:31:26 +00:00
|
|
|
VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
|
2009-01-31 22:11:09 +00:00
|
|
|
|
|
|
|
/* Our parameter checks are done elsewhere */
|
2009-02-22 22:31:26 +00:00
|
|
|
|
2009-01-31 22:11:09 +00:00
|
|
|
Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice);
|
|
|
|
|
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
return Result;
|
|
|
|
|
|
|
|
return GetSoundDeviceCapabilities(SoundDevice,
|
2009-07-11 23:49:24 +00:00
|
|
|
DeviceId,
|
2009-01-31 22:11:09 +00:00
|
|
|
Capabilities,
|
|
|
|
CapabilitiesSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
MMRESULT
|
2010-10-31 13:20:11 +00:00
|
|
|
MmeOpenDevice(
|
2009-01-31 22:11:09 +00:00
|
|
|
IN MMDEVICE_TYPE DeviceType,
|
2010-06-04 18:37:14 +00:00
|
|
|
IN UINT DeviceId,
|
2009-01-31 22:11:09 +00:00
|
|
|
IN LPWAVEOPENDESC OpenParameters,
|
|
|
|
IN DWORD Flags,
|
2010-06-04 18:37:14 +00:00
|
|
|
OUT DWORD_PTR* PrivateHandle)
|
2009-01-31 22:11:09 +00:00
|
|
|
{
|
|
|
|
MMRESULT Result;
|
2010-10-31 13:20:11 +00:00
|
|
|
UINT Message;
|
2009-01-31 22:11:09 +00:00
|
|
|
PSOUND_DEVICE SoundDevice;
|
|
|
|
PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
|
2010-12-03 11:14:29 +00:00
|
|
|
LPWAVEFORMATEX Format = NULL;
|
2009-01-31 22:11:09 +00:00
|
|
|
|
2024-08-09 20:50:51 +02:00
|
|
|
SND_TRACE(L"Opening device\n");
|
2009-01-31 22:11:09 +00:00
|
|
|
|
2010-12-03 11:14:29 +00:00
|
|
|
VALIDATE_MMSYS_PARAMETER( IS_WAVE_DEVICE_TYPE(DeviceType) || IS_MIXER_DEVICE_TYPE(DeviceType) || IS_MIDI_DEVICE_TYPE(DeviceType) ); /* FIXME? wave in too? */
|
2009-01-31 22:11:09 +00:00
|
|
|
VALIDATE_MMSYS_PARAMETER( OpenParameters );
|
|
|
|
|
|
|
|
Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice);
|
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
2010-10-31 13:20:11 +00:00
|
|
|
if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE)
|
2009-01-31 22:11:09 +00:00
|
|
|
{
|
2010-10-31 13:20:11 +00:00
|
|
|
Format = OpenParameters->lpFormat;
|
|
|
|
|
|
|
|
/* Does this device support the format? */
|
|
|
|
Result = QueryWaveDeviceFormatSupport(SoundDevice, Format, sizeof(WAVEFORMATEX));
|
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
{
|
|
|
|
SND_ERR(L"Format not supported\n");
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If the caller just wanted to know if a format is supported, end here */
|
|
|
|
if ( Flags & WAVE_FORMAT_QUERY )
|
|
|
|
return MMSYSERR_NOERROR;
|
2009-01-31 22:11:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check that winmm gave us a private handle to fill */
|
|
|
|
VALIDATE_MMSYS_PARAMETER( PrivateHandle );
|
|
|
|
|
|
|
|
/* Create a sound device instance and open the sound device */
|
|
|
|
Result = CreateSoundDeviceInstance(SoundDevice, &SoundDeviceInstance);
|
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
2009-07-11 23:21:09 +00:00
|
|
|
Result = SetWaveDeviceFormat(SoundDeviceInstance, DeviceId, Format, sizeof(WAVEFORMATEX));
|
2009-01-31 22:11:09 +00:00
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
{
|
|
|
|
/* TODO: Destroy sound instance */
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
}
|
|
|
|
|
2010-06-04 18:37:14 +00:00
|
|
|
/* Store the device instance pointer in the private handle */
|
|
|
|
*PrivateHandle = (DWORD_PTR)SoundDeviceInstance;
|
2009-01-31 22:11:09 +00:00
|
|
|
|
|
|
|
/* Store the additional information we were given - FIXME: Need flags! */
|
|
|
|
SetSoundDeviceInstanceMmeData(SoundDeviceInstance,
|
2010-10-31 13:20:11 +00:00
|
|
|
(HDRVR)OpenParameters->hWave, /* works because LPMIXEROPENDESC/etc has also the handle as first member */
|
2009-01-31 22:11:09 +00:00
|
|
|
OpenParameters->dwCallback,
|
|
|
|
OpenParameters->dwInstance,
|
|
|
|
Flags);
|
|
|
|
|
2010-10-31 13:20:11 +00:00
|
|
|
if (DeviceType == WAVE_OUT_DEVICE_TYPE || DeviceType == WAVE_IN_DEVICE_TYPE ||
|
|
|
|
DeviceType == MIDI_OUT_DEVICE_TYPE || DeviceType == MIDI_IN_DEVICE_TYPE)
|
|
|
|
{
|
|
|
|
/* Let the application know the device is open */
|
|
|
|
|
|
|
|
if (DeviceType == WAVE_OUT_DEVICE_TYPE)
|
|
|
|
Message = WOM_OPEN;
|
|
|
|
else if (DeviceType == WAVE_IN_DEVICE_TYPE)
|
|
|
|
Message = WIM_OPEN;
|
|
|
|
else if (DeviceType == MIDI_IN_DEVICE_TYPE)
|
|
|
|
Message = MIM_OPEN;
|
|
|
|
else
|
|
|
|
Message = MOM_OPEN;
|
2009-01-31 22:11:09 +00:00
|
|
|
|
2010-10-31 13:20:11 +00:00
|
|
|
ReleaseEntrypointMutex(DeviceType);
|
2009-01-31 22:11:09 +00:00
|
|
|
|
2010-10-31 13:20:11 +00:00
|
|
|
NotifyMmeClient(SoundDeviceInstance,
|
|
|
|
Message,
|
|
|
|
0);
|
|
|
|
|
|
|
|
AcquireEntrypointMutex(DeviceType);
|
|
|
|
}
|
|
|
|
|
|
|
|
SND_TRACE(L"device now open\n");
|
2009-01-31 22:11:09 +00:00
|
|
|
|
|
|
|
return MMSYSERR_NOERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
MMRESULT
|
|
|
|
MmeCloseDevice(
|
2010-06-04 18:37:14 +00:00
|
|
|
IN DWORD_PTR PrivateHandle)
|
2009-01-31 22:11:09 +00:00
|
|
|
{
|
|
|
|
MMRESULT Result;
|
|
|
|
PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
|
|
|
|
PSOUND_DEVICE SoundDevice;
|
|
|
|
MMDEVICE_TYPE DeviceType;
|
2010-10-31 13:20:11 +00:00
|
|
|
UINT Message = 0;
|
2009-01-31 22:11:09 +00:00
|
|
|
|
|
|
|
SND_TRACE(L"Closing wave device (WIDM_CLOSE / WODM_CLOSE)\n");
|
|
|
|
|
|
|
|
VALIDATE_MMSYS_PARAMETER( PrivateHandle );
|
|
|
|
SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle;
|
|
|
|
|
2009-02-22 21:14:54 +00:00
|
|
|
if ( ! IsValidSoundDeviceInstance(SoundDeviceInstance) )
|
|
|
|
return MMSYSERR_INVALHANDLE;
|
|
|
|
|
2009-01-31 22:11:09 +00:00
|
|
|
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
|
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
|
|
|
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
|
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
2009-02-22 21:14:54 +00:00
|
|
|
|
|
|
|
/* TODO: Check device is stopped! */
|
|
|
|
|
2010-10-31 13:20:11 +00:00
|
|
|
|
|
|
|
if (DeviceType != MIXER_DEVICE_TYPE)
|
|
|
|
{
|
|
|
|
ReleaseEntrypointMutex(DeviceType);
|
|
|
|
|
|
|
|
if (DeviceType == WAVE_OUT_DEVICE_TYPE)
|
|
|
|
Message = WOM_CLOSE;
|
|
|
|
else if (DeviceType == WAVE_IN_DEVICE_TYPE)
|
|
|
|
Message = WIM_CLOSE;
|
|
|
|
else if (DeviceType == MIDI_IN_DEVICE_TYPE)
|
|
|
|
Message = MIM_CLOSE;
|
|
|
|
else if (DeviceType == MIDI_OUT_DEVICE_TYPE)
|
|
|
|
Message = MOM_CLOSE;
|
|
|
|
|
|
|
|
/* TODO: Work with MIDI devices too */
|
|
|
|
NotifyMmeClient(SoundDeviceInstance,
|
|
|
|
Message,
|
|
|
|
0);
|
|
|
|
AcquireEntrypointMutex(DeviceType);
|
|
|
|
}
|
2009-01-31 22:11:09 +00:00
|
|
|
|
|
|
|
Result = DestroySoundDeviceInstance(SoundDeviceInstance);
|
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
2009-02-22 21:14:54 +00:00
|
|
|
|
|
|
|
MMRESULT
|
|
|
|
MmeResetWavePlayback(
|
2010-06-04 18:37:14 +00:00
|
|
|
IN DWORD_PTR PrivateHandle)
|
2009-02-22 21:14:54 +00:00
|
|
|
{
|
|
|
|
PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
|
|
|
|
|
|
|
|
SND_TRACE(L"Resetting wave device (WODM_RESET)\n");
|
|
|
|
|
|
|
|
VALIDATE_MMSYS_PARAMETER( PrivateHandle );
|
|
|
|
SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle;
|
|
|
|
|
|
|
|
return StopStreaming(SoundDeviceInstance);
|
|
|
|
}
|
2009-07-11 23:21:09 +00:00
|
|
|
|
2009-10-26 23:10:05 +00:00
|
|
|
MMRESULT
|
|
|
|
MmeGetDeviceInterfaceString(
|
|
|
|
IN MMDEVICE_TYPE DeviceType,
|
|
|
|
IN DWORD DeviceId,
|
|
|
|
IN LPWSTR Interface,
|
|
|
|
IN DWORD InterfaceLength,
|
|
|
|
OUT DWORD * InterfaceSize)
|
|
|
|
{
|
|
|
|
MMRESULT Result;
|
|
|
|
PSOUND_DEVICE SoundDevice;
|
|
|
|
PMMFUNCTION_TABLE FunctionTable;
|
|
|
|
|
|
|
|
Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice);
|
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
|
|
|
Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
|
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
|
|
|
if ( FunctionTable->GetDeviceInterfaceString == NULL )
|
|
|
|
{
|
|
|
|
/* querying device interface string / size not supported */
|
|
|
|
return MMSYSERR_NOTSUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call the driver */
|
|
|
|
Result = FunctionTable->GetDeviceInterfaceString(DeviceType, DeviceId, Interface, InterfaceLength, InterfaceSize);
|
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-11 23:21:09 +00:00
|
|
|
MMRESULT
|
|
|
|
MmeGetPosition(
|
|
|
|
IN MMDEVICE_TYPE DeviceType,
|
|
|
|
IN DWORD DeviceId,
|
2010-06-04 18:37:14 +00:00
|
|
|
IN DWORD_PTR PrivateHandle,
|
2009-07-11 23:21:09 +00:00
|
|
|
IN MMTIME* Time,
|
|
|
|
IN DWORD Size)
|
|
|
|
{
|
|
|
|
MMRESULT Result;
|
|
|
|
PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
|
|
|
|
PSOUND_DEVICE SoundDevice;
|
|
|
|
PMMFUNCTION_TABLE FunctionTable;
|
|
|
|
|
|
|
|
VALIDATE_MMSYS_PARAMETER( PrivateHandle );
|
|
|
|
SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle;
|
|
|
|
|
|
|
|
if ( ! IsValidSoundDeviceInstance(SoundDeviceInstance) )
|
|
|
|
return MMSYSERR_INVALHANDLE;
|
|
|
|
|
|
|
|
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
|
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
|
|
|
if ( Size != sizeof(MMTIME) )
|
|
|
|
return MMSYSERR_INVALPARAM;
|
|
|
|
|
|
|
|
Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
|
|
|
|
if ( ! MMSUCCESS(Result) )
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
|
|
|
if ( FunctionTable->GetPos == NULL )
|
|
|
|
{
|
|
|
|
/* This indicates bad practice, really! If you can open, why not close?! */
|
|
|
|
return MMSYSERR_NOTSUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call the driver */
|
|
|
|
Result = FunctionTable->GetPos(SoundDeviceInstance, Time);
|
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
[AUDIO] Implement volume control support (#6922)
Implement volume level changing for Aux/MidiOut/WaveOut devices. It's represented the following WINMM functions:
- auxGetVolume,
- auxSetVolume,
- midiOutGetVolume,
- midiOutSetVolume,
- waveOutGetVolume,
- waveOutSetVolume,
which are calling the followind messages appropriately:
- AUXDM_GETVOLUME,
- AUXDM_SETVOLUME,
- MODM_GETVOLUME,
- MODM_SETVOLUME,
- WODM_GETVOLUME,
- WODM_SETVOLUME.
This fixes volume control for several 3rd-party programs (like Fox Audio Player 0.10.2 from Rapps, Winamp 2.95 with WaveOut plugin). However it does not fix changing the volume in system volume mixers (SndVol32, MMSys), since they are using their own functionality instead. They technically do the same things, but apart from the functions mentioned above.
CORE-14780
2024-06-01 12:30:33 +02:00
|
|
|
MMRESULT
|
|
|
|
MmeGetVolume(
|
|
|
|
_In_ MMDEVICE_TYPE DeviceType,
|
|
|
|
_In_ DWORD DeviceId,
|
|
|
|
_In_ DWORD_PTR PrivateHandle,
|
|
|
|
_Out_ DWORD_PTR pdwVolume)
|
|
|
|
{
|
|
|
|
MMRESULT Result;
|
|
|
|
PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
|
|
|
|
PSOUND_DEVICE SoundDevice;
|
|
|
|
PMMFUNCTION_TABLE FunctionTable;
|
|
|
|
|
|
|
|
/* Sanity check */
|
|
|
|
SND_ASSERT(DeviceType == AUX_DEVICE_TYPE ||
|
|
|
|
DeviceType == MIDI_OUT_DEVICE_TYPE ||
|
|
|
|
DeviceType == WAVE_OUT_DEVICE_TYPE);
|
|
|
|
|
|
|
|
VALIDATE_MMSYS_PARAMETER(PrivateHandle);
|
|
|
|
SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE)PrivateHandle;
|
|
|
|
|
|
|
|
if (!IsValidSoundDeviceInstance(SoundDeviceInstance))
|
|
|
|
return MMSYSERR_INVALHANDLE;
|
|
|
|
|
|
|
|
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
|
|
|
|
if (!MMSUCCESS(Result))
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
|
|
|
Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
|
|
|
|
if (!MMSUCCESS(Result))
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
|
|
|
if (!FunctionTable->GetVolume)
|
|
|
|
return MMSYSERR_NOTSUPPORTED;
|
|
|
|
|
|
|
|
/* Call the driver */
|
|
|
|
Result = FunctionTable->GetVolume(SoundDeviceInstance, DeviceId, (PDWORD)pdwVolume);
|
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
MMRESULT
|
|
|
|
MmeSetVolume(
|
|
|
|
_In_ MMDEVICE_TYPE DeviceType,
|
|
|
|
_In_ DWORD DeviceId,
|
|
|
|
_In_ DWORD_PTR PrivateHandle,
|
|
|
|
_In_ DWORD_PTR dwVolume)
|
|
|
|
{
|
|
|
|
MMRESULT Result;
|
|
|
|
PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
|
|
|
|
PSOUND_DEVICE SoundDevice;
|
|
|
|
PMMFUNCTION_TABLE FunctionTable;
|
|
|
|
|
|
|
|
/* Sanity check */
|
|
|
|
SND_ASSERT(DeviceType == AUX_DEVICE_TYPE ||
|
|
|
|
DeviceType == MIDI_OUT_DEVICE_TYPE ||
|
|
|
|
DeviceType == WAVE_OUT_DEVICE_TYPE);
|
|
|
|
|
|
|
|
VALIDATE_MMSYS_PARAMETER(PrivateHandle);
|
|
|
|
SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE)PrivateHandle;
|
|
|
|
|
|
|
|
if (!IsValidSoundDeviceInstance(SoundDeviceInstance))
|
|
|
|
return MMSYSERR_INVALHANDLE;
|
|
|
|
|
|
|
|
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
|
|
|
|
if (!MMSUCCESS(Result))
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
|
|
|
Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
|
|
|
|
if (!MMSUCCESS(Result))
|
|
|
|
return TranslateInternalMmResult(Result);
|
|
|
|
|
|
|
|
if (!FunctionTable->SetVolume)
|
|
|
|
return MMSYSERR_NOTSUPPORTED;
|
|
|
|
|
|
|
|
/* Call the driver */
|
|
|
|
Result = FunctionTable->SetVolume(SoundDeviceInstance, DeviceId, (DWORD)dwVolume);
|
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|