From d5ceace41906dbce2ebd44697f7ba421f651c813 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 4 Feb 2019 23:54:04 +0100 Subject: [PATCH] [MMSYS] Take the balance between channels into account for the master volume trackbar. --- dll/cpl/mmsys/speakervolume.c | 14 +++-- dll/cpl/mmsys/volume.c | 109 +++++++++++++++++++++++++++------- 2 files changed, 96 insertions(+), 27 deletions(-) diff --git a/dll/cpl/mmsys/speakervolume.c b/dll/cpl/mmsys/speakervolume.c index 63eb9d4e386..a21c9406dcb 100644 --- a/dll/cpl/mmsys/speakervolume.c +++ b/dll/cpl/mmsys/speakervolume.c @@ -151,7 +151,7 @@ OnHScroll( LPARAM lParam) { MIXERCONTROLDETAILS mxcd; - DWORD dwValue, dwPos; + DWORD dwValue, dwPosition; INT id, idx, i, j; id = (INT)GetWindowLongPtr((HWND)lParam, GWLP_ID); @@ -161,8 +161,14 @@ OnHScroll( if ((id - 9475) % 4 != 0) return; - dwPos = (DWORD)SendDlgItemMessage(hwndDlg, id, TBM_GETPOS, 0, 0); - dwValue = (dwPos * pPageData->volumeStep) + pPageData->volumeMinimum; + dwPosition = (DWORD)SendDlgItemMessage(hwndDlg, id, TBM_GETPOS, 0, 0); + + if (dwPosition == VOLUME_MIN) + dwValue = pPageData->volumeMinimum; + else if (dwPosition == VOLUME_MAX) + dwValue = pPageData->volumeMaximum; + else + dwValue = (dwPosition * pPageData->volumeStep) + pPageData->volumeMinimum; if (pPageData->volumeSync) { @@ -170,7 +176,7 @@ OnHScroll( { j = 9475 + (i * 4); if (j != id) - SendDlgItemMessage(hwndDlg, j, TBM_SETPOS, (WPARAM)TRUE, dwPos); + SendDlgItemMessage(hwndDlg, j, TBM_SETPOS, (WPARAM)TRUE, dwPosition); pPageData->volumeValues[i].dwValue = dwValue; } diff --git a/dll/cpl/mmsys/volume.c b/dll/cpl/mmsys/volume.c index 2d080374842..10f61f8222e 100644 --- a/dll/cpl/mmsys/volume.c +++ b/dll/cpl/mmsys/volume.c @@ -31,10 +31,15 @@ typedef struct _GLOBAL_DATA DWORD muteControlID; DWORD volumeControlID; + DWORD volumeChannels; DWORD volumeMinimum; DWORD volumeMaximum; - DWORD volumeValue; DWORD volumeStep; + + DWORD maxVolume; + PMIXERCONTROLDETAILS_UNSIGNED volumeInitValues; + PMIXERCONTROLDETAILS_UNSIGNED volumeCurrentValues; + } GLOBAL_DATA, *PGLOBAL_DATA; @@ -154,6 +159,8 @@ GetVolumeControl(PGLOBAL_DATA pGlobalData) != MMSYSERR_NOERROR) return; + pGlobalData->volumeChannels = mxln.cChannels; + mxlc.cbStruct = sizeof(MIXERLINECONTROLS); mxlc.dwLineID = mxln.dwLineID; mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; @@ -168,54 +175,92 @@ GetVolumeControl(PGLOBAL_DATA pGlobalData) pGlobalData->volumeMaximum = mxc.Bounds.dwMaximum; pGlobalData->volumeControlID = mxc.dwControlID; pGlobalData->volumeStep = (pGlobalData->volumeMaximum - pGlobalData->volumeMinimum) / (VOLUME_MAX - VOLUME_MIN); + + pGlobalData->volumeInitValues = HeapAlloc(GetProcessHeap(), + 0, + mxln.cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED)); + if (pGlobalData->volumeInitValues == NULL) + return; + + pGlobalData->volumeCurrentValues = HeapAlloc(GetProcessHeap(), + 0, + mxln.cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED)); + if (pGlobalData->volumeCurrentValues == NULL) + return; } VOID GetVolumeValue(PGLOBAL_DATA pGlobalData) { - MIXERCONTROLDETAILS_UNSIGNED mxcdVolume; MIXERCONTROLDETAILS mxcd; + DWORD i; if (pGlobalData->hMixer == NULL) return; mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID = pGlobalData->volumeControlID; - mxcd.cChannels = 1; + mxcd.cChannels = pGlobalData->volumeChannels; mxcd.cMultipleItems = 0; mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); - mxcd.paDetails = &mxcdVolume; + mxcd.paDetails = pGlobalData->volumeInitValues; if (mixerGetControlDetails((HMIXEROBJ)pGlobalData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR) return; - pGlobalData->volumeValue = mxcdVolume.dwValue; + pGlobalData->maxVolume = 0; + for (i = 0; i < pGlobalData->volumeChannels; i++) + { + pGlobalData->volumeCurrentValues[i].dwValue = pGlobalData->volumeInitValues[i].dwValue; + + if (pGlobalData->volumeInitValues[i].dwValue > pGlobalData->maxVolume) + pGlobalData->maxVolume = pGlobalData->volumeInitValues[i].dwValue; + } } VOID -SetVolumeValue(PGLOBAL_DATA pGlobalData){ - MIXERCONTROLDETAILS_UNSIGNED mxcdVolume; +SetVolumeValue(PGLOBAL_DATA pGlobalData, + DWORD dwPosition) +{ MIXERCONTROLDETAILS mxcd; + DWORD dwVolume, i; if (pGlobalData->hMixer == NULL) return; - mxcdVolume.dwValue = pGlobalData->volumeValue; + if (dwPosition == VOLUME_MIN) + dwVolume = pGlobalData->volumeMinimum; + else if (dwPosition == VOLUME_MAX) + dwVolume = pGlobalData->volumeMaximum; + else + dwVolume = (dwPosition * pGlobalData->volumeStep) + pGlobalData->volumeMinimum; + + for (i = 0; i < pGlobalData->volumeChannels; i++) + { + if (pGlobalData->volumeInitValues[i].dwValue == pGlobalData->maxVolume) + { + pGlobalData->volumeCurrentValues[i].dwValue = dwVolume; + } + else + { + pGlobalData->volumeCurrentValues[i].dwValue = + pGlobalData->volumeInitValues[i].dwValue * dwVolume / pGlobalData-> maxVolume; + } + } + mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID = pGlobalData->volumeControlID; - mxcd.cChannels = 1; + mxcd.cChannels = pGlobalData->volumeChannels; mxcd.cMultipleItems = 0; mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); - mxcd.paDetails = &mxcdVolume; + mxcd.paDetails = pGlobalData->volumeCurrentValues; if (mixerSetControlDetails((HMIXEROBJ)pGlobalData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR) return; - - pGlobalData->volumeValue = mxcdVolume.dwValue; } @@ -306,7 +351,7 @@ InitVolumeControls(HWND hwndDlg, PGLOBAL_DATA pGlobalData) SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(VOLUME_MIN, VOLUME_MAX)); SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETTICFREQ, VOLUME_TICFREQ, 0); SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETPAGESIZE, 0, VOLUME_PAGESIZE); - SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(pGlobalData->volumeValue - pGlobalData->volumeMinimum) / pGlobalData->volumeStep); + SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(pGlobalData->maxVolume - pGlobalData->volumeMinimum) / pGlobalData->volumeStep); } VOID @@ -362,7 +407,7 @@ VolumeDlgProc(HWND hwndDlg, case MM_MIXM_CONTROL_CHANGE: { GetVolumeValue(pGlobalData); - SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(pGlobalData->volumeValue - pGlobalData->volumeMinimum) / pGlobalData->volumeStep); + SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(pGlobalData->maxVolume - pGlobalData->volumeMinimum) / pGlobalData->volumeStep); break; } case WM_INITDIALOG: @@ -454,21 +499,39 @@ VolumeDlgProc(HWND hwndDlg, HWND hVolumeTrackbar = GetDlgItem(hwndDlg, IDC_VOLUME_TRACKBAR); if (hVolumeTrackbar == (HWND)lParam) { - pGlobalData->volumeValue = ((DWORD)SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_GETPOS, 0, 0) * pGlobalData->volumeStep) + pGlobalData->volumeMinimum; - SetVolumeValue(pGlobalData); + switch (LOWORD(wParam)) + { + case TB_THUMBPOSITION: + break; - if (LOWORD(wParam) == TB_ENDTRACK) - PlaySound((LPCTSTR)SND_ALIAS_SYSTEMDEFAULT, NULL, SND_ALIAS_ID | SND_ASYNC); + case TB_ENDTRACK: + PlaySound((LPCTSTR)SND_ALIAS_SYSTEMDEFAULT, NULL, SND_ALIAS_ID | SND_ASYNC); + break; + + default: + SetVolumeValue(pGlobalData, + (DWORD)SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_GETPOS, 0, 0)); + break; + } } break; } case WM_DESTROY: - mixerClose(pGlobalData->hMixer); - DestroyIcon(pGlobalData->hIconMuted); - DestroyIcon(pGlobalData->hIconUnMuted); - DestroyIcon(pGlobalData->hIconNoHW); - HeapFree(GetProcessHeap(), 0, pGlobalData); + if (pGlobalData) + { + if (pGlobalData->volumeInitValues) + HeapFree(GetProcessHeap(), 0, pGlobalData->volumeInitValues); + + if (pGlobalData->volumeCurrentValues) + HeapFree(GetProcessHeap(), 0, pGlobalData->volumeCurrentValues); + + mixerClose(pGlobalData->hMixer); + DestroyIcon(pGlobalData->hIconMuted); + DestroyIcon(pGlobalData->hIconUnMuted); + DestroyIcon(pGlobalData->hIconNoHW); + HeapFree(GetProcessHeap(), 0, pGlobalData); + } break; case WM_NOTIFY: