[MMSYS] Take the balance between channels into account for the master volume trackbar.

This commit is contained in:
Eric Kohl 2019-02-04 23:54:04 +01:00
parent eea81f5274
commit d5ceace419
2 changed files with 96 additions and 27 deletions

View file

@ -151,7 +151,7 @@ OnHScroll(
LPARAM lParam) LPARAM lParam)
{ {
MIXERCONTROLDETAILS mxcd; MIXERCONTROLDETAILS mxcd;
DWORD dwValue, dwPos; DWORD dwValue, dwPosition;
INT id, idx, i, j; INT id, idx, i, j;
id = (INT)GetWindowLongPtr((HWND)lParam, GWLP_ID); id = (INT)GetWindowLongPtr((HWND)lParam, GWLP_ID);
@ -161,8 +161,14 @@ OnHScroll(
if ((id - 9475) % 4 != 0) if ((id - 9475) % 4 != 0)
return; return;
dwPos = (DWORD)SendDlgItemMessage(hwndDlg, id, TBM_GETPOS, 0, 0); dwPosition = (DWORD)SendDlgItemMessage(hwndDlg, id, TBM_GETPOS, 0, 0);
dwValue = (dwPos * pPageData->volumeStep) + pPageData->volumeMinimum;
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) if (pPageData->volumeSync)
{ {
@ -170,7 +176,7 @@ OnHScroll(
{ {
j = 9475 + (i * 4); j = 9475 + (i * 4);
if (j != id) if (j != id)
SendDlgItemMessage(hwndDlg, j, TBM_SETPOS, (WPARAM)TRUE, dwPos); SendDlgItemMessage(hwndDlg, j, TBM_SETPOS, (WPARAM)TRUE, dwPosition);
pPageData->volumeValues[i].dwValue = dwValue; pPageData->volumeValues[i].dwValue = dwValue;
} }

View file

@ -31,10 +31,15 @@ typedef struct _GLOBAL_DATA
DWORD muteControlID; DWORD muteControlID;
DWORD volumeControlID; DWORD volumeControlID;
DWORD volumeChannels;
DWORD volumeMinimum; DWORD volumeMinimum;
DWORD volumeMaximum; DWORD volumeMaximum;
DWORD volumeValue;
DWORD volumeStep; DWORD volumeStep;
DWORD maxVolume;
PMIXERCONTROLDETAILS_UNSIGNED volumeInitValues;
PMIXERCONTROLDETAILS_UNSIGNED volumeCurrentValues;
} GLOBAL_DATA, *PGLOBAL_DATA; } GLOBAL_DATA, *PGLOBAL_DATA;
@ -154,6 +159,8 @@ GetVolumeControl(PGLOBAL_DATA pGlobalData)
!= MMSYSERR_NOERROR) != MMSYSERR_NOERROR)
return; return;
pGlobalData->volumeChannels = mxln.cChannels;
mxlc.cbStruct = sizeof(MIXERLINECONTROLS); mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
mxlc.dwLineID = mxln.dwLineID; mxlc.dwLineID = mxln.dwLineID;
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
@ -168,54 +175,92 @@ GetVolumeControl(PGLOBAL_DATA pGlobalData)
pGlobalData->volumeMaximum = mxc.Bounds.dwMaximum; pGlobalData->volumeMaximum = mxc.Bounds.dwMaximum;
pGlobalData->volumeControlID = mxc.dwControlID; pGlobalData->volumeControlID = mxc.dwControlID;
pGlobalData->volumeStep = (pGlobalData->volumeMaximum - pGlobalData->volumeMinimum) / (VOLUME_MAX - VOLUME_MIN); 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 VOID
GetVolumeValue(PGLOBAL_DATA pGlobalData) GetVolumeValue(PGLOBAL_DATA pGlobalData)
{ {
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume;
MIXERCONTROLDETAILS mxcd; MIXERCONTROLDETAILS mxcd;
DWORD i;
if (pGlobalData->hMixer == NULL) if (pGlobalData->hMixer == NULL)
return; return;
mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
mxcd.dwControlID = pGlobalData->volumeControlID; mxcd.dwControlID = pGlobalData->volumeControlID;
mxcd.cChannels = 1; mxcd.cChannels = pGlobalData->volumeChannels;
mxcd.cMultipleItems = 0; mxcd.cMultipleItems = 0;
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mxcd.paDetails = &mxcdVolume; mxcd.paDetails = pGlobalData->volumeInitValues;
if (mixerGetControlDetails((HMIXEROBJ)pGlobalData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE) if (mixerGetControlDetails((HMIXEROBJ)pGlobalData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE)
!= MMSYSERR_NOERROR) != MMSYSERR_NOERROR)
return; 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 VOID
SetVolumeValue(PGLOBAL_DATA pGlobalData){ SetVolumeValue(PGLOBAL_DATA pGlobalData,
MIXERCONTROLDETAILS_UNSIGNED mxcdVolume; DWORD dwPosition)
{
MIXERCONTROLDETAILS mxcd; MIXERCONTROLDETAILS mxcd;
DWORD dwVolume, i;
if (pGlobalData->hMixer == NULL) if (pGlobalData->hMixer == NULL)
return; 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.cbStruct = sizeof(MIXERCONTROLDETAILS);
mxcd.dwControlID = pGlobalData->volumeControlID; mxcd.dwControlID = pGlobalData->volumeControlID;
mxcd.cChannels = 1; mxcd.cChannels = pGlobalData->volumeChannels;
mxcd.cMultipleItems = 0; mxcd.cMultipleItems = 0;
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mxcd.paDetails = &mxcdVolume; mxcd.paDetails = pGlobalData->volumeCurrentValues;
if (mixerSetControlDetails((HMIXEROBJ)pGlobalData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE) if (mixerSetControlDetails((HMIXEROBJ)pGlobalData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE)
!= MMSYSERR_NOERROR) != MMSYSERR_NOERROR)
return; 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_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_SETTICFREQ, VOLUME_TICFREQ, 0);
SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETPAGESIZE, 0, VOLUME_PAGESIZE); 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 VOID
@ -362,7 +407,7 @@ VolumeDlgProc(HWND hwndDlg,
case MM_MIXM_CONTROL_CHANGE: case MM_MIXM_CONTROL_CHANGE:
{ {
GetVolumeValue(pGlobalData); 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; break;
} }
case WM_INITDIALOG: case WM_INITDIALOG:
@ -454,21 +499,39 @@ VolumeDlgProc(HWND hwndDlg,
HWND hVolumeTrackbar = GetDlgItem(hwndDlg, IDC_VOLUME_TRACKBAR); HWND hVolumeTrackbar = GetDlgItem(hwndDlg, IDC_VOLUME_TRACKBAR);
if (hVolumeTrackbar == (HWND)lParam) if (hVolumeTrackbar == (HWND)lParam)
{ {
pGlobalData->volumeValue = ((DWORD)SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_GETPOS, 0, 0) * pGlobalData->volumeStep) + pGlobalData->volumeMinimum; switch (LOWORD(wParam))
SetVolumeValue(pGlobalData); {
case TB_THUMBPOSITION:
break;
if (LOWORD(wParam) == TB_ENDTRACK) case TB_ENDTRACK:
PlaySound((LPCTSTR)SND_ALIAS_SYSTEMDEFAULT, NULL, SND_ALIAS_ID | SND_ASYNC); 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; break;
} }
case WM_DESTROY: case WM_DESTROY:
mixerClose(pGlobalData->hMixer); if (pGlobalData)
DestroyIcon(pGlobalData->hIconMuted); {
DestroyIcon(pGlobalData->hIconUnMuted); if (pGlobalData->volumeInitValues)
DestroyIcon(pGlobalData->hIconNoHW); HeapFree(GetProcessHeap(), 0, pGlobalData->volumeInitValues);
HeapFree(GetProcessHeap(), 0, pGlobalData);
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; break;
case WM_NOTIFY: case WM_NOTIFY: