[SNDVOL32] Initialize and update the volume and balance trackbars. Moving the trackba...
authorEric Kohl <eric.kohl@reactos.org>
Sun, 10 Feb 2019 18:34:22 +0000 (19:34 +0100)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 10 Feb 2019 18:34:22 +0000 (19:34 +0100)
base/applications/sndvol32/dialog.c
base/applications/sndvol32/mixer.c
base/applications/sndvol32/sndvol32.c
base/applications/sndvol32/sndvol32.h

index 564a88b..8ff9a49 100644 (file)
@@ -414,23 +414,31 @@ EnumConnectionsCallback(
     UINT ControlCount = 0, Index;
     LPMIXERCONTROL Control = NULL;
     HWND hDlgCtrl;
+    PMIXERCONTROLDETAILS_UNSIGNED pVolumeDetails = NULL;
     PPREFERENCES_CONTEXT PrefContext = (PPREFERENCES_CONTEXT)Context;
 
-    if (Line->cControls != 0)
+    if (Line->cControls == 0)
+        return TRUE;
+
+    /* get line name */
+    if (SndMixerGetLineName(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, LineName, MIXER_LONG_NAME_CHARS, TRUE) == -1)
+    {
+        /* failed to get line name */
+        LineName[0] = L'\0';
+    }
+
+    pVolumeDetails = HeapAlloc(GetProcessHeap(),
+                               0,
+                               Line->cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
+    if (pVolumeDetails == NULL)
+        goto done;
+
+    /* check if line is found in registry settings */
+    if (ReadLineConfig(PrefContext->DeviceName,
+                       LineName,
+                       Line->szName,
+                       &Flags))
     {
-      /* get line name */
-      if (SndMixerGetLineName(PrefContext->MixerWindow->Mixer, PrefContext->SelectedLine, LineName, MIXER_LONG_NAME_CHARS, TRUE) == -1)
-      {
-          /* failed to get line name */
-          LineName[0] = L'\0';
-      }
-
-      /* check if line is found in registry settings */
-      if (ReadLineConfig(PrefContext->DeviceName,
-                         LineName,
-                         Line->szName,
-                         &Flags))
-      {
           /* is it selected */
           if (Flags != 0x4)
           {
@@ -462,7 +470,7 @@ EnumConnectionsCallback(
                           MIXERCONTROLDETAILS_BOOLEAN Details;
 
                           /* get volume control details */
-                          if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, sizeof(MIXERCONTROLDETAILS_BOOLEAN), (LPVOID)&Details) != -1)
+                          if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, 1, sizeof(MIXERCONTROLDETAILS_BOOLEAN), (LPVOID)&Details) != -1)
                           {
                               /* update dialog control */
                               wID = (PrefContext->Count + 1) * IDC_LINE_SWITCH;
@@ -483,18 +491,60 @@ EnumConnectionsCallback(
                       }
                       else if ((Control[Index].dwControlType & MIXERCONTROL_CT_CLASS_MASK) == MIXERCONTROL_CT_CLASS_FADER)
                       {
-                          MIXERCONTROLDETAILS_UNSIGNED Details;
-
                           /* get volume control details */
-                          if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)&Details) != -1)
+                          if (SndMixerGetVolumeControlDetails(Mixer, Control[Index].dwControlID, Line->cChannels, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)pVolumeDetails) != -1)
                           {
                               /* update dialog control */
-                              DWORD Position, Step;
+                              DWORD volumePosition, volumeStep, maxVolume, i;
+                              DWORD balancePosition, balanceStep;
 
-                              Step = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
-                              Position = (Details.dwValue - Control[Index].Bounds.dwMinimum) / Step;
+                              volumeStep = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
 
-                              /* FIXME support left - right slider */
+                              maxVolume = 0;
+                              for (i = 0; i < Line->cChannels; i++)
+                              {
+                                  if (pVolumeDetails[i].dwValue > maxVolume)
+                                      maxVolume = pVolumeDetails[i].dwValue;
+                              }
+
+                              volumePosition = (maxVolume - Control[Index].Bounds.dwMinimum) / volumeStep;
+
+                              if (Line->cChannels == 1)
+                              {
+                                  balancePosition = BALANCE_CENTER;
+                              }
+                              else if (Line->cChannels == 2)
+                              {
+                                  if (pVolumeDetails[0].dwValue == pVolumeDetails[1].dwValue)
+                                  {
+                                      balancePosition = BALANCE_CENTER;
+                                  }
+                                  else if (pVolumeDetails[0].dwValue == Control[Index].Bounds.dwMinimum)
+                                  {
+                                      balancePosition = BALANCE_RIGHT;
+                                  }
+                                  else if (pVolumeDetails[1].dwValue == Control[Index].Bounds.dwMinimum)
+                                  {
+                                      balancePosition = BALANCE_LEFT;
+                                  }
+                                  else
+                                  {
+                                      balanceStep = (maxVolume - Control[Index].Bounds.dwMinimum) / (BALANCE_STEPS / 2);
+
+                                      if (pVolumeDetails[0].dwValue < pVolumeDetails[1].dwValue)
+                                      {
+                                          balancePosition = (pVolumeDetails[0].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
+                                          balancePosition = BALANCE_RIGHT - balancePosition;
+                                      }
+                                      else if (pVolumeDetails[1].dwValue < pVolumeDetails[0].dwValue)
+                                      {
+                                          balancePosition = (pVolumeDetails[1].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
+                                          balancePosition = BALANCE_LEFT + balancePosition;
+                                      }
+                                  }
+                              }
+
+                              /* Set the volume trackbar */
                               wID = (PrefContext->Count + 1) * IDC_LINE_SLIDER_VERT;
 
                               /* get dialog control */
@@ -504,10 +554,29 @@ EnumConnectionsCallback(
                               {
                                   /* check state */
                                   LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
-                                  if (OldPosition != Position)
+
+                                  if (OldPosition != (VOLUME_MAX - volumePosition))
                                   {
                                       /* update control state */
-                                      SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, VOLUME_MAX - Position);
+                                      SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, VOLUME_MAX - volumePosition);
+                                  }
+                              }
+
+                              /* Set the balance trackbar */
+                              wID = (PrefContext->Count + 1) * IDC_LINE_SLIDER_HORZ;
+
+                              /* get dialog control */
+                              hDlgCtrl = GetDlgItem(PrefContext->MixerWindow->hWnd, wID);
+
+                              if (hDlgCtrl != NULL)
+                              {
+                                  /* check state */
+                                  LRESULT OldPosition = SendMessageW(hDlgCtrl, TBM_GETPOS, 0, 0);
+
+                                  if (OldPosition != balancePosition)
+                                  {
+                                      /* update control state */
+                                      SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, balancePosition);
                                   }
                               }
                           }
@@ -521,8 +590,13 @@ EnumConnectionsCallback(
               /* increment dialog count */
               PrefContext->Count++;
           }
-      }
     }
+
+done:
+    /* Free the volume details */
+    if (pVolumeDetails)
+        HeapFree(GetProcessHeap(), 0, pVolumeDetails);
+
     return TRUE;
 }
 
@@ -611,7 +685,6 @@ VOID
 UpdateDialogLineSliderControl(
     PPREFERENCES_CONTEXT PrefContext,
     LPMIXERLINE Line,
-    DWORD dwControlID,
     DWORD dwDialogID,
     DWORD Position)
 {
@@ -648,7 +721,7 @@ UpdateDialogLineSliderControl(
                 if (OldPosition != Position)
                 {
                     /* update control state */
-                    SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, Position + Index);
+                    SendMessageW(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, Position);
                 }
             }
             break;
index 768aa65..147d3c4 100644 (file)
@@ -471,7 +471,7 @@ SndMixerEnumProducts(PSND_MIXER Mixer,
 }
 
 INT
-SndMixerSetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cbDetails, LPVOID paDetails)
+SndMixerSetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cChannels, DWORD cbDetails, LPVOID paDetails)
 {
     MIXERCONTROLDETAILS MixerDetails;
 
@@ -479,7 +479,7 @@ SndMixerSetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cbDet
     {
         MixerDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
         MixerDetails.dwControlID = dwControlID;
-        MixerDetails.cChannels = 1; //FIXME
+        MixerDetails.cChannels = cChannels;
         MixerDetails.cMultipleItems = 0;
         MixerDetails.cbDetails = cbDetails;
         MixerDetails.paDetails = paDetails;
@@ -495,7 +495,7 @@ SndMixerSetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cbDet
 
 
 INT
-SndMixerGetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cbDetails, LPVOID paDetails)
+SndMixerGetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cChannels, DWORD cbDetails, LPVOID paDetails)
 {
     MIXERCONTROLDETAILS MixerDetails;
 
@@ -503,7 +503,7 @@ SndMixerGetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cbDet
     {
         MixerDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
         MixerDetails.dwControlID = dwControlID;
-        MixerDetails.cChannels = 1; //FIXME
+        MixerDetails.cChannels = cChannels;
         MixerDetails.cMultipleItems = 0;
         MixerDetails.cbDetails = cbDetails;
         MixerDetails.paDetails = paDetails;
index 592323e..864228e 100644 (file)
@@ -663,7 +663,7 @@ SetVolumeCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Ctx)
                 uDetails.dwValue = ((VOLUME_MAX - Context->SliderPos) * Step) + Control[Index].Bounds.dwMinimum;
 
                 /* set volume */
-                SndMixerSetVolumeControlDetails(Preferences.MixerWindow->Mixer, Control[Index].dwControlID, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)&uDetails);
+                SndMixerSetVolumeControlDetails(Preferences.MixerWindow->Mixer, Control[Index].dwControlID, 1, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)&uDetails);
 
                 /* done */
                 break;
@@ -677,7 +677,7 @@ SetVolumeCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Ctx)
                 bDetails.fValue = Context->SliderPos;
 
                 /* set volume */
-                SndMixerSetVolumeControlDetails(Preferences.MixerWindow->Mixer, Control[Index].dwControlID, sizeof(MIXERCONTROLDETAILS_BOOLEAN), (LPVOID)&bDetails);
+                SndMixerSetVolumeControlDetails(Preferences.MixerWindow->Mixer, Control[Index].dwControlID, 1, sizeof(MIXERCONTROLDETAILS_BOOLEAN), (LPVOID)&bDetails);
 
                 /* done */
                 break;
@@ -703,6 +703,7 @@ BOOL
 CALLBACK
 MixerControlChangeCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context)
 {
+    PMIXERCONTROLDETAILS_UNSIGNED pVolumeDetails = NULL;
     UINT ControlCount = 0, Index;
     LPMIXERCONTROL Control = NULL;
 
@@ -720,6 +721,12 @@ MixerControlChangeCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVO
         return FALSE;
     }
 
+    pVolumeDetails = HeapAlloc(GetProcessHeap(),
+                               0,
+                               Line->cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
+    if (pVolumeDetails == NULL)
+        goto done;
+
     /* now go through all controls and compare control ids */
     for (Index = 0; Index < ControlCount; Index++)
     {
@@ -730,7 +737,7 @@ MixerControlChangeCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVO
                 MIXERCONTROLDETAILS_BOOLEAN Details;
 
                 /* get volume control details */
-                if (SndMixerGetVolumeControlDetails(Preferences.MixerWindow->Mixer, Control[Index].dwControlID, sizeof(MIXERCONTROLDETAILS_BOOLEAN), (LPVOID)&Details) != -1)
+                if (SndMixerGetVolumeControlDetails(Preferences.MixerWindow->Mixer, Control[Index].dwControlID, 1, sizeof(MIXERCONTROLDETAILS_BOOLEAN), (LPVOID)&Details) != -1)
                 {
                     /* update dialog control */
                     UpdateDialogLineSwitchControl(&Preferences, Line, Details.fValue);
@@ -738,25 +745,75 @@ MixerControlChangeCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVO
             }
             else if ((Control[Index].dwControlType & MIXERCONTROL_CT_CLASS_MASK) == MIXERCONTROL_CT_CLASS_FADER)
             {
-                MIXERCONTROLDETAILS_UNSIGNED Details;
-
                 /* get volume control details */
-                if (SndMixerGetVolumeControlDetails(Preferences.MixerWindow->Mixer, Control[Index].dwControlID, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)&Details) != -1)
+                if (SndMixerGetVolumeControlDetails(Preferences.MixerWindow->Mixer, Control[Index].dwControlID, Line->cChannels, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)pVolumeDetails) != -1)
                 {
                     /* update dialog control */
-                    DWORD Position, Step;
+                    DWORD volumePosition, volumeStep, maxVolume, i;
+                    DWORD balancePosition, balanceStep;
+
+                    volumeStep = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
+
+                    maxVolume = 0;
+                    for (i = 0; i < Line->cChannels; i++)
+                    {
+                        if (pVolumeDetails[i].dwValue > maxVolume)
+                            maxVolume = pVolumeDetails[i].dwValue;
+                    }
+
+                    volumePosition = (maxVolume - Control[Index].Bounds.dwMinimum) / volumeStep;
+
+                    if (Line->cChannels == 1)
+                    {
+                        balancePosition = BALANCE_CENTER;
+                    }
+                    else if (Line->cChannels == 2)
+                    {
+                        if (pVolumeDetails[0].dwValue == pVolumeDetails[1].dwValue)
+                        {
+                            balancePosition = BALANCE_CENTER;
+                        }
+                        else if (pVolumeDetails[0].dwValue == Control[Index].Bounds.dwMinimum)
+                        {
+                            balancePosition = BALANCE_RIGHT;
+                        }
+                        else if (pVolumeDetails[1].dwValue == Control[Index].Bounds.dwMinimum)
+                        {
+                            balancePosition = BALANCE_LEFT;
+                        }
+                        else
+                        {
+                            balanceStep = (maxVolume - Control[Index].Bounds.dwMinimum) / (BALANCE_STEPS / 2);
+
+                            if (pVolumeDetails[0].dwValue < pVolumeDetails[1].dwValue)
+                            {
+                                balancePosition = (pVolumeDetails[0].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
+                                balancePosition = BALANCE_RIGHT - balancePosition;
+                            }
+                            else if (pVolumeDetails[1].dwValue < pVolumeDetails[0].dwValue)
+                            {
+                                balancePosition = (pVolumeDetails[1].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
+                                balancePosition = BALANCE_LEFT + balancePosition;
+                            }
+                        }
+                    }
 
-                    Step = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
-                    Position = (Details.dwValue - Control[Index].Bounds.dwMinimum) / Step;
+                    /* Update the volume control slider */
+                    UpdateDialogLineSliderControl(&Preferences, Line, IDC_LINE_SLIDER_VERT, VOLUME_MAX - volumePosition);
 
-                    /* update volume control slider */
-                    UpdateDialogLineSliderControl(&Preferences, Line, Control[Index].dwControlID, IDC_LINE_SLIDER_VERT, VOLUME_MAX - Position);
+                    /* Update the balance control slider */
+                    UpdateDialogLineSliderControl(&Preferences, Line, IDC_LINE_SLIDER_HORZ, balancePosition);
                 }
             }
             break;
         }
     }
 
+done:
+    /* Free the volume details */
+    if (pVolumeDetails)
+        HeapFree(GetProcessHeap(), 0, pVolumeDetails);
+
     /* free controls */
     HeapFree(GetProcessHeap(), 0, Control);
 
index a68cb37..cf20366 100644 (file)
@@ -18,6 +18,9 @@
 #define VOLUME_MAX         500
 #define VOLUME_TICKS         5
 #define VOLUME_PAGE_SIZE   100
+#define BALANCE_LEFT         0
+#define BALANCE_CENTER      32
+#define BALANCE_RIGHT       64
 #define BALANCE_STEPS       64
 #define BALANCE_TICKS        1
 #define BALANCE_PAGE_SIZE   12
@@ -104,14 +107,13 @@ typedef struct _PREFERENCES_CONTEXT
     DWORD tmp;
 } PREFERENCES_CONTEXT, *PPREFERENCES_CONTEXT;
 
-typedef struct
+typedef struct _SET_VOLUME_CONTEXT
 {
     WCHAR LineName[MIXER_LONG_NAME_CHARS];
     UINT SliderPos;
     BOOL bVertical;
     BOOL bSwitch;
-
-}SET_VOLUME_CONTEXT, *PSET_VOLUME_CONTEXT;
+} SET_VOLUME_CONTEXT, *PSET_VOLUME_CONTEXT;
 
 /* NOTE: do NOT modify SNDVOL_REG_LINESTATE for binary compatibility with XP! */
 typedef struct _SNDVOL_REG_LINESTATE
@@ -130,8 +132,8 @@ VOID SndMixerDestroy(PSND_MIXER Mixer);
 VOID SndMixerClose(PSND_MIXER Mixer);
 BOOL SndMixerSelect(PSND_MIXER Mixer, UINT MixerId);
 UINT SndMixerGetSelection(PSND_MIXER Mixer);
-INT SndMixerSetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cbDetails, LPVOID paDetails);
-INT SndMixerGetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cbDetails, LPVOID paDetails);
+INT SndMixerSetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cChannels, DWORD cbDetails, LPVOID paDetails);
+INT SndMixerGetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cChannels, DWORD cbDetails, LPVOID paDetails);
 INT SndMixerGetProductName(PSND_MIXER Mixer, LPTSTR lpBuffer, UINT uSize);
 INT SndMixerGetLineName(PSND_MIXER Mixer, DWORD LineID, LPTSTR lpBuffer, UINT uSize, BOOL LongName);
 BOOL SndMixerEnumProducts(PSND_MIXER Mixer, PFNSNDMIXENUMPRODUCTS EnumProc, PVOID Context);
@@ -145,7 +147,7 @@ BOOL SndMixerQueryControls(PSND_MIXER Mixer, PUINT DisplayControls, LPMIXERLINE
  * dialog.c
  */
 VOID LoadDialogCtrls(PPREFERENCES_CONTEXT PrefContext);
-VOID UpdateDialogLineSliderControl(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, DWORD dwControlID, DWORD DialogID, DWORD Position);
+VOID UpdateDialogLineSliderControl(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, DWORD DialogID, DWORD Position);
 VOID UpdateDialogLineSwitchControl(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, LONG fValue);
 
 /*