Index: trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp	(revision 89765)
+++ trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp	(revision 89768)
@@ -2082,5 +2082,6 @@
     AssertPtrReturnVoid(pVol);
 
-    LogFlowFunc(("%s: lVol=%RU8, rVol=%RU8, fMuted=%RTbool\n", pMixBuf->pszName, pVol->uLeft, pVol->uRight, pVol->fMuted));
+    LogFlowFunc(("%s: fMuted=%RTbool auChannels=%.*Rhxs\n",
+                 pMixBuf->pszName, pVol->fMuted, sizeof(pVol->auChannels), pVol->auChannels));
 
     /*
@@ -2091,9 +2092,7 @@
         pMixBuf->Volume.fMuted  = false;
 
-        AssertCompileSize(pVol->uLeft, sizeof(uint8_t));
-        pMixBuf->Volume.auChannels[0] = s_aVolumeConv[pVol->uLeft ] * (AUDIOMIXBUF_VOL_0DB >> 16);
-        pMixBuf->Volume.auChannels[1] = s_aVolumeConv[pVol->uRight] * (AUDIOMIXBUF_VOL_0DB >> 16);
+        AssertCompileSize(pVol->auChannels[0], sizeof(uint8_t));
         for (uintptr_t i = 2; i < pMixBuf->cChannels; i++)
-            pMixBuf->Volume.auChannels[i] = pMixBuf->Volume.auChannels[1];
+            pMixBuf->Volume.auChannels[i] = s_aVolumeConv[pVol->auChannels[i]] * (AUDIOMIXBUF_VOL_0DB >> 16);
 
         pMixBuf->Volume.fAllMax = true;
Index: trunk/src/VBox/Devices/Audio/AudioMixer.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/AudioMixer.cpp	(revision 89765)
+++ trunk/src/VBox/Devices/Audio/AudioMixer.cpp	(revision 89768)
@@ -193,7 +193,5 @@
 
             /* Set master volume to the max. */
-            pMixer->VolMaster.fMuted = false;
-            pMixer->VolMaster.uLeft  = PDMAUDIO_VOLUME_MAX;
-            pMixer->VolMaster.uRight = PDMAUDIO_VOLUME_MAX;
+            PDMAudioVolumeInitMax(&pMixer->VolMaster);
 
             LogFlowFunc(("Created mixer '%s'\n", pMixer->pszName));
@@ -262,6 +260,6 @@
     AssertRCReturnVoid(rc2);
 
-    pHlp->pfnPrintf(pHlp, "[Master] %s: lVol=%u, rVol=%u, fMuted=%RTbool\n", pMixer->pszName,
-                    pMixer->VolMaster.uLeft, pMixer->VolMaster.uRight, pMixer->VolMaster.fMuted);
+    pHlp->pfnPrintf(pHlp, "[Master] %s: fMuted=%RTbool auChannels=%.*Rhxs\n",
+                    pMixer->pszName, pMixer->VolMaster.fMuted, sizeof(pMixer->VolMaster.auChannels), pMixer->VolMaster.auChannels);
 
     PAUDMIXSINK pSink;
@@ -269,6 +267,6 @@
     RTListForEach(&pMixer->lstSinks, pSink, AUDMIXSINK, Node)
     {
-        pHlp->pfnPrintf(pHlp, "[Sink %u] %s: lVol=%u, rVol=%u, fMuted=%RTbool\n", iSink, pSink->pszName,
-                        pSink->Volume.uLeft, pSink->Volume.uRight, pSink->Volume.fMuted);
+        pHlp->pfnPrintf(pHlp, "[Sink %u] %s: fMuted=%RTbool auChannels=%.*Rhxs\n",
+                        iSink, pSink->pszName, pSink->Volume.fMuted, sizeof(pSink->Volume.auChannels), pSink->Volume.auChannels);
         ++iSink;
     }
@@ -298,8 +296,8 @@
      * Make a copy.
      */
+    LogFlowFunc(("[%s] fMuted=%RTbool auChannels=%.*Rhxs => fMuted=%RTbool auChannels=%.*Rhxs\n", pMixer->pszName,
+                 pMixer->VolMaster.fMuted, sizeof(pMixer->VolMaster.auChannels), pMixer->VolMaster.auChannels,
+                 pVol->fMuted, sizeof(pVol->auChannels), pVol->auChannels ));
     memcpy(&pMixer->VolMaster, pVol, sizeof(PDMAUDIOVOLUME));
-    LogFlowFunc(("[%s] lVol=%RU32, rVol=%RU32 => fMuted=%RTbool, lVol=%RU32, rVol=%RU32\n",
-                 pMixer->pszName, pVol->uLeft, pVol->uRight,
-                 pMixer->VolMaster.fMuted, pMixer->VolMaster.uLeft, pMixer->VolMaster.uRight));
 
     /*
@@ -395,12 +393,8 @@
 
             /* Set initial volume to max. */
-            pSink->Volume.fMuted = false;
-            pSink->Volume.uLeft  = PDMAUDIO_VOLUME_MAX;
-            pSink->Volume.uRight = PDMAUDIO_VOLUME_MAX;
+            PDMAudioVolumeInitMax(&pSink->Volume);
 
             /* Ditto for the combined volume. */
-            pSink->VolumeCombined.fMuted = false;
-            pSink->VolumeCombined.uLeft  = PDMAUDIO_VOLUME_MAX;
-            pSink->VolumeCombined.uRight = PDMAUDIO_VOLUME_MAX;
+            PDMAudioVolumeInitMax(&pSink->VolumeCombined);
 
             /* AIO */
@@ -1062,15 +1056,12 @@
     Assert(pSink->uMagic == AUDMIXSINK_MAGIC);
     AssertPtr(pVolMaster);
-    LogFlowFunc(("[%s] Master fMuted=%RTbool, lVol=%RU32, rVol=%RU32\n",
-                  pSink->pszName, pVolMaster->fMuted, pVolMaster->uLeft, pVolMaster->uRight));
-
-    pSink->VolumeCombined.fMuted = pVolMaster->fMuted || pSink->Volume.fMuted;
-    /** @todo Very crude implementation for now -- needs more work! */
-    pSink->VolumeCombined.uLeft  = (uint32_t)RT_MAX(pSink->Volume.uLeft, 1)  * RT_MAX(pVolMaster->uLeft, 1)  / PDMAUDIO_VOLUME_MAX;
-    pSink->VolumeCombined.uRight = (uint32_t)RT_MAX(pSink->Volume.uRight, 1) * RT_MAX(pVolMaster->uRight, 1) / PDMAUDIO_VOLUME_MAX;
-
-    LogFlowFunc(("[%s] fMuted=%RTbool, lVol=%RU32, rVol=%RU32 -> fMuted=%RTbool, lVol=%RU32, rVol=%RU32\n",
-                 pSink->pszName, pSink->Volume.fMuted, pSink->Volume.uLeft, pSink->Volume.uRight,
-                 pSink->VolumeCombined.fMuted, pSink->VolumeCombined.uLeft, pSink->VolumeCombined.uRight));
+    LogFlowFunc(("[%s] Master fMuted=%RTbool auChannels=%.*Rhxs\n",
+                  pSink->pszName, pVolMaster->fMuted, sizeof(pVolMaster->auChannels), pVolMaster->auChannels));
+
+    PDMAudioVolumeCombine(&pSink->VolumeCombined, &pSink->Volume, pVolMaster);
+
+    LogFlowFunc(("[%s] fMuted=%RTbool auChannels=%.*Rhxs -> fMuted=%RTbool auChannels=%.*Rhxs\n", pSink->pszName,
+                 pSink->Volume.fMuted, sizeof(pSink->Volume.auChannels), pSink->Volume.auChannels,
+                 pSink->VolumeCombined.fMuted, sizeof(pSink->VolumeCombined.auChannels), pSink->VolumeCombined.auChannels ));
 
     AudioMixBufSetVolume(&pSink->MixBuf, &pSink->VolumeCombined);
@@ -1097,6 +1088,6 @@
     memcpy(&pSink->Volume, pVol, sizeof(PDMAUDIOVOLUME));
 
-    LogRel2(("Audio Mixer: Setting volume of sink '%s' to %RU8/%RU8 (%s)\n",
-             pSink->pszName, pVol->uLeft, pVol->uRight, pVol->fMuted ? "Muted" : "Unmuted"));
+    LogRel2(("Audio Mixer: Setting volume of sink '%s' to fMuted=%RTbool auChannels=%.*Rhxs\n",
+              pSink->pszName, pVol->fMuted, sizeof(pVol->auChannels), pVol->auChannels));
 
     Assert(pSink->pParent);
Index: trunk/src/VBox/Devices/Audio/DevHda.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevHda.cpp	(revision 89765)
+++ trunk/src/VBox/Devices/Audio/DevHda.cpp	(revision 89768)
@@ -2585,6 +2585,6 @@
         && pSink->pMixSink)
     {
-        LogRel2(("HDA: Setting volume for mixer sink '%s' to %RU8/%RU8 (%s)\n",
-                 pSink->pMixSink->pszName, pVol->uLeft, pVol->uRight, pVol->fMuted ? "Muted" : "Unmuted"));
+        LogRel2(("HDA: Setting volume for mixer sink '%s' to fMuted=%RTbool auChannels=%.*Rhxs\n",
+                 pSink->pMixSink->pszName, pVol->fMuted, sizeof(pVol->auChannels), pVol->auChannels));
 
         /* Set the volume.
@@ -4921,6 +4921,6 @@
 
     /* There is no master volume control. Set the master to max. */
-    PDMAUDIOVOLUME vol = { false, 255, 255 };
-    rc = AudioMixerSetMasterVolume(pThisCC->pMixer, &vol);
+    PDMAUDIOVOLUME Vol = PDMAUDIOVOLUME_INITIALIZER_MAX;
+    rc = AudioMixerSetMasterVolume(pThisCC->pMixer, &Vol);
     AssertRCReturn(rc, rc);
 
Index: trunk/src/VBox/Devices/Audio/DevHdaCodec.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevHdaCodec.cpp	(revision 89765)
+++ trunk/src/VBox/Devices/Audio/DevHdaCodec.cpp	(revision 89768)
@@ -896,6 +896,6 @@
     iMute &= 0x1;
 
-    uint8_t lVol = AMPLIFIER_REGISTER(*pAmp, iDir, AMPLIFIER_LEFT,  0) & 0x7f;
-    uint8_t rVol = AMPLIFIER_REGISTER(*pAmp, iDir, AMPLIFIER_RIGHT, 0) & 0x7f;
+    uint8_t bLeft = AMPLIFIER_REGISTER(*pAmp, iDir, AMPLIFIER_LEFT,  0) & 0x7f;
+    uint8_t bRight = AMPLIFIER_REGISTER(*pAmp, iDir, AMPLIFIER_RIGHT, 0) & 0x7f;
 
     /*
@@ -905,14 +905,13 @@
      * to 1 (rather than zero) internally.
      */
-    lVol = (lVol + 1) * (2 * 255) / 256;
-    rVol = (rVol + 1) * (2 * 255) / 256;
-
-    PDMAUDIOVOLUME Vol = { RT_BOOL(iMute), lVol, rVol };
-
-    LogFunc(("[NID0x%02x] %RU8/%RU8 (%s)\n",
-             pNode->node.uID, lVol, rVol, RT_BOOL(iMute) ? "Muted" : "Unmuted"));
-
-    LogRel2(("HDA: Setting volume for mixer control '%s' to %RU8/%RU8 (%s)\n",
-             PDMAudioMixerCtlGetName(enmMixerCtl), lVol, rVol, RT_BOOL(iMute) ? "Muted" : "Unmuted"));
+    bLeft = (bLeft + 1) * (2 * 255) / 256;
+    bRight = (bRight + 1) * (2 * 255) / 256;
+
+    PDMAUDIOVOLUME Vol;
+    PDMAudioVolumeInitFromStereo(&Vol, RT_BOOL(iMute), bLeft, bRight);
+
+    LogFunc(("[NID0x%02x] %RU8/%RU8%s\n", pNode->node.uID, bLeft, bRight, Vol.fMuted ? "- Muted!" : ""));
+    LogRel2(("HDA: Setting volume for mixer control '%s' to %RU8/%RU8%s\n",
+             PDMAudioMixerCtlGetName(enmMixerCtl), bLeft, bRight, Vol.fMuted ? "- Muted!" : ""));
 
     return pThisCC->pfnCbMixerSetVolume(pThisCC->pDevIns, enmMixerCtl, &Vol);
Index: trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 89765)
+++ trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 89768)
@@ -1276,5 +1276,5 @@
         {
             STAM_REL_COUNTER_INC(&pStreamCC->State.StatDmaFlowProblems);
-            Log(("ichac97R3StreamUpdateDma: Warning! Stream #%u has insufficient space free: %u bytes, need %u.  Will try move data out of the buffer...\n",
+            LogFunc(("Warning! Stream #%u has insufficient space free: %u bytes, need %u.  Will try move data out of the buffer...\n",
                  pStreamCC->u8SD, cbStreamFree, cbPeriod));
             int rc = AudioMixerSinkTryLock(pSink);
@@ -1287,5 +1287,5 @@
             else
                 RTThreadYield();
-            Log(("ichac97R3StreamUpdateDma: Gained %u bytes.\n", ichac97R3StreamGetFree(pStreamCC) - cbStreamFree));
+            LogFunc(("Gained %u bytes.\n", ichac97R3StreamGetFree(pStreamCC) - cbStreamFree));
 
             cbStreamFree = ichac97R3StreamGetFree(pStreamCC);
@@ -1356,5 +1356,5 @@
             if (cbStreamUsed < cbPreBuffer)
             {
-                Log3(("hdaR3StreamUpdateDma: Pre-buffering (got %#x out of %#x bytes)...\n", cbStreamUsed, cbPreBuffer));
+                Log3Func(("Pre-buffering (got %#x out of %#x bytes)...\n", cbStreamUsed, cbPreBuffer));
                 fWriteSilence = true;
                 cbStreamUsed  = cbPeriod;
@@ -1362,5 +1362,5 @@
             else
             {
-                Log3(("hdaR3StreamUpdateDma: Completed pre-buffering (got %#x, needed %#x bytes).\n", cbStreamUsed, cbPreBuffer));
+                Log3Func(("Completed pre-buffering (got %#x, needed %#x bytes).\n", cbStreamUsed, cbPreBuffer));
                 pStreamCC->State.fInputPreBuffered = true;
                 fWriteSilence = ichac97R3StreamGetFree(pStreamCC) >= cbPreBuffer + cbPreBuffer / 2;
@@ -1376,5 +1376,5 @@
         {
             STAM_REL_COUNTER_INC(&pStreamCC->State.StatDmaFlowProblems);
-            Log(("ichac97R3StreamUpdateDma: Warning! Stream #%u has insufficient data available: %u bytes, need %u.  Will try move pull more data into the buffer...\n",
+            LogFunc(("Warning! Stream #%u has insufficient data available: %u bytes, need %u.  Will try move pull more data into the buffer...\n",
                  pStreamCC->u8SD, cbStreamUsed, cbPeriod));
             int rc = AudioMixerSinkTryLock(pSink);
@@ -1387,5 +1387,5 @@
             else
                 RTThreadYield();
-            Log(("ichac97R3StreamUpdateDma: Gained %u bytes.\n", ichac97R3StreamGetUsed(pStreamCC) - cbStreamUsed));
+            LogFunc(("Gained %u bytes.\n", ichac97R3StreamGetUsed(pStreamCC) - cbStreamUsed));
             cbStreamUsed = ichac97R3StreamGetUsed(pStreamCC);
             if (cbStreamUsed < cbPeriod)
@@ -3034,7 +3034,8 @@
     if (pThisCC->pMixer) /* Device can be in reset state, so no mixer available. */
     {
-        PDMAUDIOVOLUME Vol   = { fCtlMuted, lVol, rVol };
-        PAUDMIXSINK    pSink = NULL;
-
+        PDMAUDIOVOLUME Vol;
+        PDMAudioVolumeInitFromStereo(&Vol, fCtlMuted, lVol, rVol);
+
+        PAUDMIXSINK pSink = NULL;
         switch (enmMixerCtl)
         {
@@ -3118,7 +3119,8 @@
     if (pThisCC->pMixer) /* Device can be in reset state, so no mixer available. */
     {
-        PDMAUDIOVOLUME Vol   = { fCtlMuted, lVol, rVol };
+        PDMAUDIOVOLUME Vol;
+        PDMAudioVolumeInitFromStereo(&Vol, fCtlMuted, lVol, rVol);
+
         PAUDMIXSINK    pSink = NULL;
-
         switch (enmMixerCtl)
         {
@@ -3137,5 +3139,6 @@
         }
 
-        if (pSink) {
+        if (pSink)
+        {
             rc = AudioMixerSinkSetVolume(pSink, &Vol);
             /* There is only one AC'97 recording gain control. If line in
@@ -3144,5 +3147,5 @@
              * NB: The codecs we support do not have the dedicated microphone control.
              */
-            if ((pSink == pThisCC->pSinkLineIn) && pThisCC->pSinkMicIn)
+            if (pSink == pThisCC->pSinkLineIn && pThisCC->pSinkMicIn)
                 rc = AudioMixerSinkSetVolume(pSink, &Vol);
         }
Index: trunk/src/VBox/Devices/Audio/DevSB16.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 89765)
+++ trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 89768)
@@ -1183,13 +1183,8 @@
  * @param   pVol                Where to store the master volume information.
  */
-static void sb16GetMasterVolume(PSB16STATE pThis, PPDMAUDIOVOLUME pVol)
+DECLINLINE(void) sb16GetMasterVolume(PSB16STATE pThis, PPDMAUDIOVOLUME pVol)
 {
     /* There's no mute switch, only volume controls. */
-    uint8_t lvol = sb16MixRegToVol(pThis, 0x30);
-    uint8_t rvol = sb16MixRegToVol(pThis, 0x31);
-
-    pVol->fMuted = false;
-    pVol->uLeft  = lvol;
-    pVol->uRight = rvol;
+    PDMAudioVolumeInitFromStereo(pVol, false /*fMuted*/, sb16MixRegToVol(pThis, 0x30), sb16MixRegToVol(pThis, 0x31));
 }
 
@@ -1200,13 +1195,8 @@
  * @param   pVol                Where to store the output stream volume information.
  */
-static void sb16GetPcmOutVolume(PSB16STATE pThis, PPDMAUDIOVOLUME pVol)
+DECLINLINE(void) sb16GetPcmOutVolume(PSB16STATE pThis, PPDMAUDIOVOLUME pVol)
 {
     /* There's no mute switch, only volume controls. */
-    uint8_t lvol = sb16MixRegToVol(pThis, 0x32);
-    uint8_t rvol = sb16MixRegToVol(pThis, 0x33);
-
-    pVol->fMuted = false;
-    pVol->uLeft  = lvol;
-    pVol->uRight = rvol;
+    PDMAudioVolumeInitFromStereo(pVol, false /*fMuted*/, sb16MixRegToVol(pThis, 0x32), sb16MixRegToVol(pThis, 0x33));
 }
 
@@ -1221,15 +1211,5 @@
     /* Combine the master + output stream volume. */
     PDMAUDIOVOLUME VolCombined;
-    RT_ZERO(VolCombined);
-
-    VolCombined.fMuted = VolMaster.fMuted || VolOut.fMuted;
-    if (!VolCombined.fMuted)
-    {
-        VolCombined.uLeft  = (   (VolOut.uLeft    ? VolOut.uLeft     : 1)
-                               * (VolMaster.uLeft ? VolMaster.uLeft  : 1)) / PDMAUDIO_VOLUME_MAX;
-
-        VolCombined.uRight = (  (VolOut.uRight    ? VolOut.uRight    : 1)
-                              * (VolMaster.uRight ? VolMaster.uRight : 1)) / PDMAUDIO_VOLUME_MAX;
-    }
+    PDMAudioVolumeCombine(&VolCombined, &VolMaster, &VolOut);
 
     int rc2 = AudioMixerSinkSetVolume(pThis->pSinkOut, &VolCombined);
Index: trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp	(revision 89765)
+++ trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp	(revision 89768)
@@ -794,8 +794,5 @@
      * 1) Full volume/0dB attenuation (255).
      */
-    PDMAUDIOVOLUME Vol;
-    Vol.fMuted = false;
-    Vol.uLeft  = 255;
-    Vol.uRight = 255;
+    PDMAUDIOVOLUME Vol = PDMAUDIOVOLUME_INITIALIZER_MAX;
     AudioMixBufSetVolume(&MixBuf, &Vol);
 
@@ -826,6 +823,5 @@
      * 2) Half volume/-6dB attenuation (16 steps down).
      */
-    Vol.uLeft  = 255 - 16;
-    Vol.uRight = 255 - 16;
+    PDMAudioVolumeInitFromStereo(&Vol, false, 255 - 16, 255 - 16);
     AudioMixBufSetVolume(&MixBuf, &Vol);
 
