diff --git a/dll/win32/wdmaud.drv/legacy.c b/dll/win32/wdmaud.drv/legacy.c index 95d38c3c43a80..d67ad72c16ef2 100644 --- a/dll/win32/wdmaud.drv/legacy.c +++ b/dll/win32/wdmaud.drv/legacy.c @@ -850,6 +850,25 @@ WdmAudGetWavePositionByLegacy( return MMSYSERR_NOERROR; } +MMRESULT +WdmAudGetVolumeByLegacy( + _In_ struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + _In_ DWORD DeviceId, + _Out_ PDWORD pdwVolume) +{ + /* FIXME */ + return MMSYSERR_NOTSUPPORTED; +} + +MMRESULT +WdmAudSetVolumeByLegacy( + _In_ struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + _In_ DWORD DeviceId, + _In_ DWORD dwVolume) +{ + /* FIXME */ + return MMSYSERR_NOTSUPPORTED; +} MMRESULT WdmAudResetStreamByLegacy( diff --git a/dll/win32/wdmaud.drv/mmixer.c b/dll/win32/wdmaud.drv/mmixer.c index 3b032531026c8..aab7453f5e484 100644 --- a/dll/win32/wdmaud.drv/mmixer.c +++ b/dll/win32/wdmaud.drv/mmixer.c @@ -805,6 +805,123 @@ WdmAudGetWavePositionByMMixer( return MMSYSERR_NOTSUPPORTED; } +MMRESULT +WdmAudGetVolumeByMMixer( + _In_ struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + _In_ DWORD DeviceId, + _Out_ PDWORD pdwVolume) +{ + MMRESULT Result; + MIXERLINE MixLine; + MIXERCONTROL MixControl; + MIXERLINECONTROLS MixLineControls; + MIXERCONTROLDETAILS MixControlDetails; + MIXERCONTROLDETAILS_UNSIGNED MixControlDetailsU[2]; + + MixLine.cbStruct = sizeof(MIXERLINE); + MixLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; + + /* Get line info */ + Result = WdmAudGetLineInfo(SoundDeviceInstance->Handle, + DeviceId, + &MixLine, + MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_COMPONENTTYPE); + if (!MMSUCCESS(Result)) + return TranslateInternalMmResult(Result); + + MixLineControls.cbStruct = sizeof(MIXERLINECONTROLS); + MixLineControls.dwLineID = MixLine.dwLineID; + MixLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; + MixLineControls.cControls = 1; + MixLineControls.cbmxctrl = sizeof(MIXERCONTROL); + MixLineControls.pamxctrl = &MixControl; + + /* Get line controls */ + Result = WdmAudGetLineControls(SoundDeviceInstance->Handle, + DeviceId, + &MixLineControls, + MIXER_OBJECTF_MIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE); + if (!MMSUCCESS(Result)) + return TranslateInternalMmResult(Result); + + MixControlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS); + MixControlDetails.dwControlID = MixControl.dwControlID; + MixControlDetails.cChannels = MixLine.cChannels; + MixControlDetails.cMultipleItems = 0; + MixControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); + MixControlDetails.paDetails = MixControlDetailsU; + + /* Get volume control details */ + Result = WdmAudGetControlDetails(SoundDeviceInstance->Handle, + DeviceId, + &MixControlDetails, + MIXER_OBJECTF_MIXER); + + if (MMSUCCESS(Result)) + *pdwVolume = MAKELONG(LOWORD(MixControlDetailsU[0].dwValue), HIWORD(MixControlDetailsU[1].dwValue)); + + return Result; +} + +MMRESULT +WdmAudSetVolumeByMMixer( + _In_ struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + _In_ DWORD DeviceId, + _In_ DWORD dwVolume) +{ + MMRESULT Result; + MIXERLINE MixLine; + MIXERCONTROL MixControl; + MIXERLINECONTROLS MixLineControls; + MIXERCONTROLDETAILS MixControlDetails; + MIXERCONTROLDETAILS_UNSIGNED MixControlDetailsU[2]; + + MixLine.cbStruct = sizeof(MIXERLINE); + MixLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; + + /* Get line info */ + Result = WdmAudGetLineInfo(SoundDeviceInstance->Handle, + DeviceId, + &MixLine, + MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_COMPONENTTYPE); + if (!MMSUCCESS(Result)) + return TranslateInternalMmResult(Result); + + MixLineControls.cbStruct = sizeof(MIXERLINECONTROLS); + MixLineControls.dwLineID = MixLine.dwLineID; + MixLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; + MixLineControls.cControls = 1; + MixLineControls.cbmxctrl = sizeof(MIXERCONTROL); + MixLineControls.pamxctrl = &MixControl; + + /* Get line controls */ + Result = WdmAudGetLineControls(SoundDeviceInstance->Handle, + DeviceId, + &MixLineControls, + MIXER_OBJECTF_MIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE); + if (!MMSUCCESS(Result)) + return TranslateInternalMmResult(Result); + + /* Convert volume level to be set */ + MixControlDetailsU[0].dwValue = LOWORD(dwVolume); // Left channel + MixControlDetailsU[1].dwValue = HIWORD(dwVolume); // Right channel + + MixControlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS); + MixControlDetails.dwControlID = MixControl.dwControlID; + MixControlDetails.cChannels = MixLine.cChannels; + MixControlDetails.cMultipleItems = 0; + MixControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); + MixControlDetails.paDetails = MixControlDetailsU; + + /* Set volume control details */ + Result = WdmAudSetControlDetails(SoundDeviceInstance->Handle, + DeviceId, + &MixControlDetails, + MIXER_OBJECTF_MIXER); + + return Result; +} + static VOID WINAPI CommitWaveBufferApc(PVOID ApcContext, diff --git a/dll/win32/wdmaud.drv/wdmaud.c b/dll/win32/wdmaud.drv/wdmaud.c index 45308b3aff24e..6b8561f19f3ef 100644 --- a/dll/win32/wdmaud.drv/wdmaud.c +++ b/dll/win32/wdmaud.drv/wdmaud.c @@ -76,6 +76,12 @@ PopulateWdmDeviceList( FuncTable.Close = FUNC_NAME(WdmAudCloseSoundDevice); FuncTable.GetDeviceInterfaceString = FUNC_NAME(WdmAudGetDeviceInterfaceString); + if (DeviceType == AUX_DEVICE_TYPE || DeviceType == MIDI_OUT_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE) + { + FuncTable.GetVolume = FUNC_NAME(WdmAudGetVolume); + FuncTable.SetVolume = FUNC_NAME(WdmAudSetVolume); + } + if (DeviceType == MIXER_DEVICE_TYPE) { FuncTable.SetWaveFormat = FUNC_NAME(WdmAudSetMixerDeviceFormat); diff --git a/dll/win32/wdmaud.drv/wdmaud.h b/dll/win32/wdmaud.drv/wdmaud.h index d3900b3adfa7f..d057de1dc0fdf 100644 --- a/dll/win32/wdmaud.drv/wdmaud.h +++ b/dll/win32/wdmaud.drv/wdmaud.h @@ -144,6 +144,18 @@ WdmAudGetWavePositionByMMixer( IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, IN MMTIME* Time); +MMRESULT +WdmAudGetVolumeByMMixer( + _In_ struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + _In_ DWORD DeviceId, + _Out_ PDWORD pdwVolume); + +MMRESULT +WdmAudSetVolumeByMMixer( + _In_ struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + _In_ DWORD DeviceId, + _In_ DWORD dwVolume); + MMRESULT WdmAudCommitWaveBufferByMMixer( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, @@ -224,6 +236,18 @@ WdmAudGetWavePositionByLegacy( IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, IN MMTIME* Time); +MMRESULT +WdmAudGetVolumeByLegacy( + _In_ struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + _In_ DWORD DeviceId, + _Out_ PDWORD pdwVolume); + +MMRESULT +WdmAudSetVolumeByLegacy( + _In_ struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + _In_ DWORD DeviceId, + _In_ DWORD dwVolume); + MMRESULT WriteFileEx_Committer2( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, diff --git a/sdk/include/reactos/libs/sound/mmebuddy.h b/sdk/include/reactos/libs/sound/mmebuddy.h index 4056621b1811c..96594e0be9a59 100644 --- a/sdk/include/reactos/libs/sound/mmebuddy.h +++ b/sdk/include/reactos/libs/sound/mmebuddy.h @@ -190,6 +190,16 @@ typedef MMRESULT(*MMRESETSTREAM_FUNC)( IN MMDEVICE_TYPE DeviceType, IN BOOLEAN bStartReset); +typedef MMRESULT(*MMGETVOLUME_FUNC)( + _In_ struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + _In_ DWORD DeviceId, + _Out_ PDWORD pdwVolume); + +typedef MMRESULT(*MMSETVOLUME_FUNC)( + _In_ struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + _In_ DWORD DeviceId, + _In_ DWORD dwVolume); + typedef struct _MMFUNCTION_TABLE { union @@ -216,6 +226,9 @@ typedef struct _MMFUNCTION_TABLE MMQUERYDEVICEINTERFACESTRING_FUNC GetDeviceInterfaceString; MMRESETSTREAM_FUNC ResetStream; + MMGETVOLUME_FUNC GetVolume; + MMSETVOLUME_FUNC SetVolume; + // Redundant //MMWAVEHEADER_FUNC PrepareWaveHeader; //MMWAVEHEADER_FUNC UnprepareWaveHeader; @@ -369,6 +382,20 @@ MmeGetPosition( IN MMTIME* Time, IN DWORD Size); +MMRESULT +MmeGetVolume( + _In_ MMDEVICE_TYPE DeviceType, + _In_ DWORD DeviceId, + _In_ DWORD_PTR PrivateHandle, + _Out_ PDWORD_PTR pdwVolume); + +MMRESULT +MmeSetVolume( + _In_ MMDEVICE_TYPE DeviceType, + _In_ DWORD DeviceId, + _In_ DWORD_PTR PrivateHandle, + _In_ DWORD_PTR dwVolume); + MMRESULT MmeGetDeviceInterfaceString( IN MMDEVICE_TYPE DeviceType, diff --git a/sdk/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c b/sdk/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c index 6a164de0c8b05..cb2407ffe3b32 100644 --- a/sdk/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c +++ b/sdk/lib/drivers/sound/mmebuddy/auxiliary/auxMessage.c @@ -45,6 +45,22 @@ auxMessage( Parameter2); break; } + + case AUXDM_GETVOLUME : + { + Result = MmeGetVolume(AUX_DEVICE_TYPE, + DeviceId, + PrivateHandle, + &Parameter1); + } + + case AUXDM_SETVOLUME : + { + Result = MmeSetVolume(AUX_DEVICE_TYPE, + DeviceId, + PrivateHandle, + Parameter1); + } } SND_TRACE(L"auxMessage returning MMRESULT %d\n", Result); diff --git a/sdk/lib/drivers/sound/mmebuddy/midi/modMessage.c b/sdk/lib/drivers/sound/mmebuddy/midi/modMessage.c index e6c09004a5b83..a5fc73c9b6d07 100644 --- a/sdk/lib/drivers/sound/mmebuddy/midi/modMessage.c +++ b/sdk/lib/drivers/sound/mmebuddy/midi/modMessage.c @@ -75,6 +75,21 @@ modMessage( break; } + case MODM_GETVOLUME : + { + Result = MmeGetVolume(MIDI_OUT_DEVICE_TYPE, + DeviceId, + PrivateHandle, + &Parameter1); + } + + case MODM_SETVOLUME : + { + Result = MmeSetVolume(MIDI_OUT_DEVICE_TYPE, + DeviceId, + PrivateHandle, + Parameter1); + } } SND_TRACE(L"modMessage returning MMRESULT %d\n", Result); diff --git a/sdk/lib/drivers/sound/mmebuddy/mmewrap.c b/sdk/lib/drivers/sound/mmebuddy/mmewrap.c index 186b69a0c5eb3..81c5ed5b0ebb5 100644 --- a/sdk/lib/drivers/sound/mmebuddy/mmewrap.c +++ b/sdk/lib/drivers/sound/mmebuddy/mmewrap.c @@ -365,3 +365,85 @@ MmeGetPosition( return Result; } + +MMRESULT +MmeGetVolume( + _In_ MMDEVICE_TYPE DeviceType, + _In_ DWORD DeviceId, + _In_ DWORD_PTR PrivateHandle, + _Out_ PDWORD_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, 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, dwVolume); + + return Result; +} + diff --git a/sdk/lib/drivers/sound/mmebuddy/wave/wodMessage.c b/sdk/lib/drivers/sound/mmebuddy/wave/wodMessage.c index e73bdf0ecc83b..51aec759f2863 100644 --- a/sdk/lib/drivers/sound/mmebuddy/wave/wodMessage.c +++ b/sdk/lib/drivers/sound/mmebuddy/wave/wodMessage.c @@ -118,6 +118,22 @@ wodMessage( break; } + case WODM_GETVOLUME : + { + Result = MmeGetVolume(WAVE_OUT_DEVICE_TYPE, + DeviceId, + PrivateHandle, + &Parameter1); + } + + case WODM_SETVOLUME : + { + Result = MmeSetVolume(WAVE_OUT_DEVICE_TYPE, + DeviceId, + PrivateHandle, + Parameter1); + } + case DRV_QUERYDEVICEINTERFACESIZE : { Result = MmeGetDeviceInterfaceString(WAVE_OUT_DEVICE_TYPE, DeviceId, NULL, 0, (DWORD*)Parameter1); //FIXME DWORD_PTR @@ -129,6 +145,7 @@ wodMessage( Result = MmeGetDeviceInterfaceString(WAVE_OUT_DEVICE_TYPE, DeviceId, (LPWSTR)Parameter1, Parameter2, NULL); //FIXME DWORD_PTR break; } + } SND_TRACE(L"wodMessage returning MMRESULT %d\n", Result);