Index: /trunk/include/VBox/vmm/pdmaudioifs.h
===================================================================
--- /trunk/include/VBox/vmm/pdmaudioifs.h	(revision 55004)
+++ /trunk/include/VBox/vmm/pdmaudioifs.h	(revision 55005)
@@ -30,4 +30,5 @@
 #include <iprt/list.h>
 
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
 typedef struct
 {
@@ -36,4 +37,5 @@
     uint32_t l;
 } volume_t;
+#endif
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
@@ -137,4 +139,5 @@
     PDMAUDIOMIXERCTL_PCM,
     PDMAUDIOMIXERCTL_LINE_IN,
+    PDMAUDIOMIXERCTL_MIC_IN,
     /** Hack to blow the type up to 32-bit. */
     PDMAUDIOMIXERCTL_32BIT_HACK = 0x7fffffff
@@ -199,4 +202,17 @@
     bool        fSwapEndian;
 } PDMPCMPROPS, *PPDMPCMPROPS;
+
+/**
+ * Structure keeping an audio volume level.
+ */
+typedef struct PDMAUDIOVOLUME
+{
+    /** Set to @c true if this stream is muted, @c false if not. */
+    bool                   fMuted;
+    /** Left channel volume. */
+    uint32_t               uLeft;
+    /** Right channel volume. */
+    uint32_t               uRight;
+} PDMAUDIOVOLUME, *PPDMAUDIOVOLUME;
 
 /**
@@ -243,20 +259,21 @@
      *  in the samples buffer. */
     uint32_t               offReadWrite;
-    /** Total samples already mixed down to the
-     *  parent buffer (if any). Always starting at
-     *  the parent's offReadWrite position.
-     *  Note: Count always is specified in parent samples,
-     *        as the sample count can differ between parent
-     *        and child. */
+    /**
+     * Total samples already mixed down to the parent buffer (if any). Always starting at
+     * the parent's offReadWrite position.
+     *
+     * Note: Count always is specified in parent samples, as the sample count can differ between parent
+     *       and child.
+     */
     uint32_t               cMixed;
     uint32_t               cProcessed;
     /** Pointer to parent buffer (if any). */
     PPDMAUDIOMIXBUF        pParent;
-    /** List of children mix buffers to keep
-     *  in sync with (if being a parent buffer). */
+    /** List of children mix buffers to keep in sync with (if being a parent buffer). */
     RTLISTANCHOR           lstBuffers;
-    /** Intermediate structure for buffer
-     *  conversion tasks. */
+    /** Intermediate structure for buffer conversion tasks. */
     PPDMAUDIOSTRMRATE      pRate;
+    /** Current volume used for mixing. */
+    PDMAUDIOVOLUME         Volume;
     /** This buffer's audio format. */
     PDMAUDIOMIXBUFFMT      AudioFmt;
@@ -335,12 +352,6 @@
     /** Guest audio output stream has some samples or not. */
     bool                   fEmpty;
-    /** Set to @c true if this stream is muted, @c false if not. */
-    bool                   fMuted;
     /** Name of this stream. */
     char                  *pszName;
-    /** Left channel volume. */
-    uint32_t               uVolumeLeft;
-    /** Right channel volume. */
-    uint32_t               uVolumeRight;
 } PDMAUDIOGSTSTRMSTATE, *PPDMAUDIOGSTSTRMSTATE;
 
@@ -443,29 +454,4 @@
      */
     DECLR3CALLBACKMEMBER(int, pfnInitNull, (PPDMIAUDIOCONNECTOR pInterface));
-
-    /**
-     * Sets the audio volume of a specific guest output stream.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   pGstStrmOut     Pointer to guest output stream.
-     * @param   fMute           Whether to mute or not.
-     * @param   uVolLeft        Left audio stream volume.
-     * @param   uVolRight       Right audio stream volume.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnSetVolumeOut, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOGSTSTRMOUT pGstStrmOut,
-                                                bool fMute, uint8_t uVolLeft, uint8_t uVolRight));
-
-    /**
-     * Sets the overall audio volume.
-     *
-     * @returns VBox status code.
-     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
-     * @param   fMute           Whether to mute or not.
-     * @param   uVolLeft        Left audio stream volume.
-     * @param   uVolRight       Right audio stream volume.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnSetVolume, (PPDMIAUDIOCONNECTOR pInterface,
-                                             bool fMute, uint8_t uVolLeft, uint8_t uVolRight));
 
     /**
Index: /trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp	(revision 55004)
+++ /trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp	(revision 55005)
@@ -48,5 +48,5 @@
 #include "AudioMixBuffer.h"
 
-#if 0
+#if 1
 # define AUDMIXBUF_LOG(x) LogFlowFunc(x)
 #else
@@ -57,4 +57,18 @@
 # endif
 #endif
+
+/**
+ * Structure for holding sample conversion parameters for
+ * the audioMixBufConvFromXXX / audioMixBufConvToXXX macros.
+ */
+typedef struct AUDMIXBUF_CONVOPTS
+{
+    /** Number of audio samples to convert. */
+    uint32_t       cSamples;
+    /** Volume to apply during conversion. Pass 0
+     *  to convert the original values. May not apply to
+     *  all conversion functions. */
+    PDMAUDIOVOLUME Volume;
+} AUDMIXBUF_CONVOPTS, *PAUDMIXBUF_CONVOPTS;
 
 /*
@@ -76,8 +90,8 @@
 static inline void audioMixBufPrint(PPDMAUDIOMIXBUF pMixBuf);
 
-typedef uint32_t (AUDMIXBUF_FN_CONVFROM) (PPDMAUDIOSAMPLE paDst, const void *pvSrc, size_t cbSrc, uint32_t cSamples);
+typedef uint32_t (AUDMIXBUF_FN_CONVFROM) (PPDMAUDIOSAMPLE paDst, const void *pvSrc, size_t cbSrc, const PAUDMIXBUF_CONVOPTS pOpts);
 typedef AUDMIXBUF_FN_CONVFROM *PAUDMIXBUF_FN_CONVFROM;
 
-typedef void (AUDMIXBUF_FN_CONVTO) (void *pvDst, const PPDMAUDIOSAMPLE paSrc, uint32_t cSamples);
+typedef void (AUDMIXBUF_FN_CONVTO) (void *pvDst, const PPDMAUDIOSAMPLE paSrc, const PAUDMIXBUF_CONVOPTS pOpts);
 typedef AUDMIXBUF_FN_CONVTO *PAUDMIXBUF_FN_CONVTO;
 
@@ -186,4 +200,10 @@
     }
 
+    if (pMixBuf->pRate)
+    {
+        RTMemFree(pMixBuf->pRate);
+        pMixBuf->pRate = NULL;
+    }
+
     audioMixBufFreeBuf(pMixBuf);
 }
@@ -249,4 +269,7 @@
 /**
  * Macro for generating the conversion routines from/to different formats.
+ * Be careful what to pass in/out, as most of the macros are optimized for speed and
+ * thus don't do any bounds checking!
+ *
  * Note: Currently does not handle any endianess conversion yet!
  */
@@ -273,14 +296,15 @@
     } \
     \
-    AUDMIXBUF_MACRO_FN uint32_t audioMixBufConvFrom##_aName##Stereo(PPDMAUDIOSAMPLE paDst, const void *pvSrc, size_t cbSrc, uint32_t cSamples) \
+    AUDMIXBUF_MACRO_FN uint32_t audioMixBufConvFrom##_aName##Stereo(PPDMAUDIOSAMPLE paDst, const void *pvSrc, size_t cbSrc, \
+                                                                    const PAUDMIXBUF_CONVOPTS pOpts) \
     { \
         _aType *pSrc = (_aType *)pvSrc; \
-        cSamples = (uint32_t)RT_MIN(cSamples, cbSrc / sizeof(_aType)); \
-        AUDMIXBUF_MACRO_LOG(("cSamples=%RU32, sizeof(%zu)\n", cSamples, sizeof(_aType))); \
+        uint32_t cSamples = (uint32_t)RT_MIN(pOpts->cSamples, cbSrc / sizeof(_aType)); \
+        AUDMIXBUF_MACRO_LOG(("cSamples=%RU32, sizeof(%zu)\n", pOpts->cSamples, sizeof(_aType))); \
         for (uint32_t i = 0; i < cSamples; i++) \
         { \
             AUDMIXBUF_MACRO_LOG(("%p: l=%RI16, r=%RI16\n", paDst, *pSrc, *(pSrc + 1))); \
-            paDst->u64LSample = (ASMMult2xS32RetS64(audioMixBufClipFrom##_aName(*pSrc++), 0x5F000000 /* Volume */) >> 31); \
-            paDst->u64RSample = (ASMMult2xS32RetS64(audioMixBufClipFrom##_aName(*pSrc++), 0x5F000000 /* Volume */) >> 31); \
+            paDst->u64LSample = (ASMMult2xS32RetS64(audioMixBufClipFrom##_aName(*pSrc++), pOpts->Volume.uLeft ) >> 31); \
+            paDst->u64RSample = (ASMMult2xS32RetS64(audioMixBufClipFrom##_aName(*pSrc++), pOpts->Volume.uRight) >> 31); \
             AUDMIXBUF_MACRO_LOG(("\t-> l=%RI64, r=%RI64\n", paDst->u64LSample, paDst->u64RSample)); \
             paDst++; \
@@ -290,12 +314,13 @@
     } \
     \
-    AUDMIXBUF_MACRO_FN uint32_t audioMixBufConvFrom##_aName##Mono(PPDMAUDIOSAMPLE paDst, const void *pvSrc, size_t cbSrc, uint32_t cSamples) \
+    AUDMIXBUF_MACRO_FN uint32_t audioMixBufConvFrom##_aName##Mono(PPDMAUDIOSAMPLE paDst, const void *pvSrc, size_t cbSrc, \
+                                                                  const PAUDMIXBUF_CONVOPTS pOpts) \
     { \
         _aType *pSrc = (_aType *)pvSrc; \
-        cSamples = (uint32_t)RT_MIN(cSamples, cbSrc / sizeof(_aType)); \
+        uint32_t cSamples = (uint32_t)RT_MIN(pOpts->cSamples, cbSrc / sizeof(_aType)); \
         AUDMIXBUF_MACRO_LOG(("cSamples=%RU32, sizeof(%zu)\n", cSamples, sizeof(_aType))); \
         for (uint32_t i = 0; i < cSamples; i++) \
         { \
-            paDst->u64LSample = ASMMult2xS32RetS64(audioMixBufClipFrom##_aName(pSrc[0]), 0x5F000000 /* Volume */); \
+            paDst->u64LSample = ASMMult2xS32RetS64(audioMixBufClipFrom##_aName(pSrc[0]), pOpts->Volume.uLeft); \
             paDst->u64RSample = paDst->u64LSample; \
             pSrc++; \
@@ -306,10 +331,11 @@
     } \
     \
-    /* Note: Does no buffer size checking, so be careful what to do! */ \
-    AUDMIXBUF_MACRO_FN void audioMixBufConvTo##_aName##Stereo(void *pvDst, const PPDMAUDIOSAMPLE paSrc, uint32_t cSamples) \
+    AUDMIXBUF_MACRO_FN void audioMixBufConvTo##_aName##Stereo(void *pvDst, const PPDMAUDIOSAMPLE paSrc, \
+                                                              const PAUDMIXBUF_CONVOPTS pOpts) \
     { \
         PPDMAUDIOSAMPLE pSrc = paSrc; \
         _aType *pDst = (_aType *)pvDst; \
         _aType l, r; \
+        uint32_t cSamples = pOpts->cSamples; \
         while (cSamples--) \
         { \
@@ -324,9 +350,10 @@
     } \
     \
-    /* Note: Does no buffer size checking, so be careful what to do! */ \
-    AUDMIXBUF_MACRO_FN void audioMixBufConvTo##_aName##Mono(void *pvDst, const PPDMAUDIOSAMPLE paSrc, uint32_t cSamples) \
+    AUDMIXBUF_MACRO_FN void audioMixBufConvTo##_aName##Mono(void *pvDst, const PPDMAUDIOSAMPLE paSrc, \
+                                                            const PAUDMIXBUF_CONVOPTS pOpts) \
     { \
         PPDMAUDIOSAMPLE pSrc = paSrc; \
         _aType *pDst = (_aType *)pvDst; \
+        uint32_t cSamples = pOpts->cSamples; \
         while (cSamples--) \
         { \
@@ -458,4 +485,12 @@
 #undef AUDMIXBUF_MACRO_LOG
 
+/**
+ *
+ ** @todo Speed up the lookup by binding it to the actual stream state.
+ *
+ * @return  IPRT status code.
+ * @return  PAUDMIXBUF_FN_CONVFROM
+ * @param   enmFmt
+ */
 static inline PAUDMIXBUF_FN_CONVFROM audioMixBufConvFromLookup(PDMAUDIOMIXBUFFMT enmFmt)
 {
@@ -510,4 +545,11 @@
 }
 
+/**
+ *
+ ** @todo Speed up the lookup by binding it to the actual stream state.
+ *
+ * @return  PAUDMIXBUF_FN_CONVTO
+ * @param   enmFmt
+ */
 static inline PAUDMIXBUF_FN_CONVTO audioMixBufConvToLookup(PDMAUDIOMIXBUFFMT enmFmt)
 {
@@ -562,64 +604,4 @@
 }
 
-static inline int audioMixBufConvFrom(PPDMAUDIOSAMPLE paDst,
-                                      const void *pvSrc, size_t cbSrc,
-                                      uint32_t cSamples, PDMAUDIOMIXBUFFMT enmFmt,
-                                      uint32_t *pcWritten)
-{
-    AssertPtrReturn(paDst, VERR_INVALID_POINTER);
-    AssertPtrReturn(pvSrc, VERR_INVALID_POINTER);
-    AssertReturn(cbSrc, VERR_INVALID_PARAMETER);
-    /* pcbWritten is optional. */
-
-    int rc;
-
-    PAUDMIXBUF_FN_CONVFROM pConv = audioMixBufConvFromLookup(enmFmt);
-    if (pConv)
-    {
-        uint32_t cWritten = pConv(paDst, pvSrc, cbSrc, cSamples);
-
-        if (pcWritten)
-            *pcWritten = (uint32_t )cWritten;
-
-        rc = VINF_SUCCESS;
-    }
-    else
-        rc = VERR_INVALID_PARAMETER;
-
-    return rc;
-}
-
-/**
- * TODO
- *
- * Note: This routine does not do any bounds checking for speed
- *       reasons, so be careful what you do with it.
- *
- * @return  IPRT status code.
- * @param   pvDst
- * @param   paSrc
- * @param   cSamples
- * @param   pCfg
- */
-static inline int audioMixBufConvTo(void *pvDst, const PPDMAUDIOSAMPLE paSrc, uint32_t cSamples,
-                                    PDMAUDIOMIXBUFFMT enmFmt)
-{
-    AssertPtrReturn(pvDst, VERR_INVALID_POINTER);
-    AssertPtrReturn(paSrc, VERR_INVALID_POINTER);
-
-    int rc;
-
-    PAUDMIXBUF_FN_CONVTO pConv = audioMixBufConvToLookup(enmFmt);
-    if (pConv)
-    {
-        pConv(pvDst, paSrc, cSamples);
-        rc = VINF_SUCCESS;
-    }
-    else
-        rc = VERR_INVALID_PARAMETER;
-
-    return rc;
-}
-
 static void audioMixBufFreeBuf(PPDMAUDIOMIXBUF pMixBuf)
 {
@@ -636,10 +618,9 @@
 }
 
-int audioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName,
-                    PPDMPCMPROPS pProps, uint32_t cSamples)
+int audioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PPDMPCMPROPS pProps, uint32_t cSamples)
 {
     AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
     AssertPtrReturn(pszName, VERR_INVALID_POINTER);
-    AssertPtrReturn(pProps, VERR_INVALID_POINTER);
+    AssertPtrReturn(pProps,  VERR_INVALID_POINTER);
 
     pMixBuf->pParent = NULL;
@@ -652,4 +633,9 @@
     pMixBuf->cMixed       = 0;
     pMixBuf->cProcessed   = 0;
+
+    /* Set initial volume to max. */
+    pMixBuf->Volume.fMuted = false;
+    pMixBuf->Volume.uLeft  = UINT32_MAX;
+    pMixBuf->Volume.uRight = UINT32_MAX;
 
     /* Prevent division by zero.
@@ -974,6 +960,14 @@
     if (cToProcess)
     {
-        rc = audioMixBufConvTo(pvBuf, pMixBuf->pSamples + offSamples,
-                               cToProcess, enmFmt);
+        PAUDMIXBUF_FN_CONVTO pConv = audioMixBufConvToLookup(enmFmt);
+        if (pConv)
+        {
+            AUDMIXBUF_CONVOPTS convOpts = { cToProcess, pMixBuf->Volume };
+            pConv(pvBuf, pMixBuf->pSamples + offSamples, &convOpts);
+
+            rc = VINF_SUCCESS;
+        }
+        else
+            rc = VERR_INVALID_PARAMETER;
 
         audioMixBufPrint(pMixBuf);
@@ -982,6 +976,9 @@
         rc = VINF_SUCCESS;
 
-    if (pcbRead)
-        *pcbRead = AUDIOMIXBUF_S2B(pMixBuf, cToProcess);
+    if (RT_SUCCESS(rc))
+    {
+        if (pcbRead)
+            *pcbRead = AUDIOMIXBUF_S2B(pMixBuf, cToProcess);
+    }
 
     AUDMIXBUF_LOG(("cbRead=%RU32, rc=%Rrc\n", AUDIOMIXBUF_S2B(pMixBuf, cToProcess), rc));
@@ -1020,4 +1017,8 @@
         return VINF_SUCCESS;
     }
+
+    PAUDMIXBUF_FN_CONVTO pConv = audioMixBufConvToLookup(enmFmt);
+    if (!pConv) /* Audio format not supported. */
+        return VERR_NOT_SUPPORTED;
 
     PPDMAUDIOSAMPLE pSamplesSrc1 = pMixBuf->pSamples + pMixBuf->offReadWrite;
@@ -1047,10 +1048,15 @@
     }
 
+    AUDMIXBUF_CONVOPTS convOpts;
+    convOpts.Volume = pMixBuf->Volume;
+
     /* Anything to do at all? */
     int rc = VINF_SUCCESS;
     if (cLenSrc1)
     {
+        convOpts.cSamples = cLenSrc1;
+
         AUDMIXBUF_LOG(("P1: offRead=%RU32, cToRead=%RU32\n", pMixBuf->offReadWrite, cLenSrc1));
-        rc = audioMixBufConvTo(pvBuf, pSamplesSrc1, cLenSrc1, enmFmt);
+        pConv(pvBuf, pSamplesSrc1, &convOpts);
     }
 
@@ -1061,8 +1067,9 @@
         AssertPtr(pSamplesSrc2);
 
+        convOpts.cSamples = cLenSrc2;
+
         AUDMIXBUF_LOG(("P2: cToRead=%RU32, offWrite=%RU32 (%zu bytes)\n", cLenSrc2, cLenSrc1,
                        AUDIOMIXBUF_S2B(pMixBuf, cLenSrc1)));
-        rc = audioMixBufConvTo((uint8_t *)pvBuf + AUDIOMIXBUF_S2B(pMixBuf, cLenSrc1),
-                               pSamplesSrc2, cLenSrc2, enmFmt);
+        pConv((uint8_t *)pvBuf + AUDIOMIXBUF_S2B(pMixBuf, cLenSrc1), pSamplesSrc2, &convOpts);
     }
 
@@ -1079,6 +1086,6 @@
         }
 #endif
-        pMixBuf->offReadWrite = offRead % pMixBuf->cSamples;
-        pMixBuf->cProcessed -= RT_MIN(cLenSrc1 + cLenSrc2, pMixBuf->cProcessed);
+        pMixBuf->offReadWrite  = offRead % pMixBuf->cSamples;
+        pMixBuf->cProcessed   -= RT_MIN(cLenSrc1 + cLenSrc2, pMixBuf->cProcessed);
 
         if (pcRead)
@@ -1106,4 +1113,14 @@
     if (pMixBuf->cSamples)
         RT_BZERO(pMixBuf->pSamples, pMixBuf->cSamples * sizeof(PDMAUDIOSAMPLE));
+}
+
+void audioMixBufSetVolume(PPDMAUDIOMIXBUF pMixBuf, PPDMAUDIOVOLUME pVol)
+{
+    AssertPtrReturnVoid(pMixBuf);
+    AssertPtrReturnVoid(pVol);
+
+    AUDMIXBUF_LOG(("%s: lVol=%RU32, rVol=%RU32\n", pMixBuf->pszName, pVol->uLeft, pVol->uRight));
+
+    pMixBuf->Volume = *pVol;
 }
 
@@ -1210,4 +1227,8 @@
         return VERR_BUFFER_OVERFLOW;
 
+    PAUDMIXBUF_FN_CONVFROM pConv = audioMixBufConvFromLookup(enmFmt);
+    if (!pConv)
+        return VERR_NOT_SUPPORTED;
+
     int rc;
     uint32_t cWritten;
@@ -1226,8 +1247,10 @@
     if (cToProcess)
     {
-        rc = audioMixBufConvFrom(pMixBuf->pSamples + offSamples, pvBuf, cbBuf,
-                                 cToProcess, enmFmt, &cWritten);
-
+        AUDMIXBUF_CONVOPTS convOpts = { cToProcess, pMixBuf->Volume };
+
+        cWritten = pConv(pMixBuf->pSamples + offSamples, pvBuf, cbBuf, &convOpts);
         audioMixBufPrint(pMixBuf);
+
+        rc = cWritten ? VINF_SUCCESS : VERR_GENERAL_FAILURE; /** @todo Fudge! */
     }
     else
@@ -1285,4 +1308,8 @@
         return VINF_SUCCESS;
     }
+
+    PAUDMIXBUF_FN_CONVFROM pConv = audioMixBufConvFromLookup(enmFmt);
+    if (!pConv)
+        return VERR_NOT_SUPPORTED;
 
     int rc = VINF_SUCCESS;
@@ -1317,7 +1344,12 @@
     }
 
+    uint32_t cWrittenTotal = 0;
+
     /* Anything to do at all? */
     if (cLenDst1)
-        rc = audioMixBufConvFrom(pSamplesDst1, pvBuf, cbBuf, cLenDst1, enmFmt, NULL);
+    {
+        AUDMIXBUF_CONVOPTS convOpts = { cLenDst1, pMixBuf->Volume };
+        cWrittenTotal = pConv(pSamplesDst1, pvBuf, cbBuf, &convOpts);
+    }
 
     /* Second part present? */
@@ -1326,7 +1358,7 @@
     {
         AssertPtr(pSamplesDst2);
-        rc = audioMixBufConvFrom(pSamplesDst2,
-                                 (uint8_t *)pvBuf + AUDIOMIXBUF_S2B(pMixBuf, cLenDst1), cbBuf,
-                                 cLenDst2, enmFmt, NULL);
+
+        AUDMIXBUF_CONVOPTS convOpts = { cLenDst2, pMixBuf->Volume };
+        cWrittenTotal += pConv(pSamplesDst2, (uint8_t *)pvBuf + AUDIOMIXBUF_S2B(pMixBuf, cLenDst1), cbBuf, &convOpts);
     }
 
@@ -1358,3 +1390,2 @@
     return rc;
 }
-
Index: /trunk/src/VBox/Devices/Audio/AudioMixBuffer.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/AudioMixBuffer.h	(revision 55004)
+++ /trunk/src/VBox/Devices/Audio/AudioMixBuffer.h	(revision 55005)
@@ -67,4 +67,5 @@
 int audioMixBufReadCircEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt, void *pvBuf, size_t cbBuf, uint32_t *pcRead);
 void audioMixBufReset(PPDMAUDIOMIXBUF pMixBuf);
+void audioMixBufSetVolume(PPDMAUDIOMIXBUF pMixBuf, PPDMAUDIOVOLUME pVol);
 uint32_t audioMixBufSize(PPDMAUDIOMIXBUF pMixBuf);
 size_t audioMixBufSizeBytes(PPDMAUDIOMIXBUF pMixBuf);
Index: /trunk/src/VBox/Devices/Audio/AudioMixer.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/AudioMixer.cpp	(revision 55004)
+++ /trunk/src/VBox/Devices/Audio/AudioMixer.cpp	(revision 55005)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2014 Oracle Corporation
+ * Copyright (C) 2014-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -19,4 +19,5 @@
 
 #include "AudioMixer.h"
+#include "AudioMixBuffer.h"
 
 #include <VBox/vmm/pdm.h>
@@ -36,5 +37,5 @@
 #include <VBox/log.h>
 
-int audioMixerAddSink(PAUDIOMIXER pMixer, const char *pszName, PAUDMIXSINK *ppSink)
+int audioMixerAddSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PAUDMIXSINK *ppSink)
 {
     AssertPtrReturn(pMixer, VERR_INVALID_POINTER);
@@ -53,7 +54,13 @@
         if (RT_SUCCESS(rc))
         {
-            pSink->pParent = pMixer;
+            pSink->pParent  = pMixer;
             pSink->cStreams = 0;
+            pSink->enmDir   = enmDir;
             RTListInit(&pSink->lstStreams);
+
+            /* Set initial volume to max. */
+            pSink->Volume.fMuted = false;
+            pSink->Volume.uLeft  = UINT32_MAX;
+            pSink->Volume.uRight = UINT32_MAX;
 
             RTListAppend(&pMixer->lstSinks, &pSink->Node);
@@ -85,5 +92,5 @@
     int rc;
 
-    if (pSink->cStreams == INT8_MAX) /* 255 streams per sink max. */
+    if (pSink->cStreams == UINT8_MAX) /* 255 streams per sink max. */
         return VERR_TOO_MUCH_DATA;
 
@@ -93,5 +100,43 @@
     {
         pMixStream->pConn = pConnector;
-        pMixStream->pStrm = pStream;
+        pMixStream->pIn   = pStream;
+        /** @todo Process flags. */
+
+        RTListAppend(&pSink->lstStreams, &pMixStream->Node);
+        pSink->cStreams++;
+
+        LogFlowFunc(("pSink=%p, pStream=%p, cStreams=%RU8\n",
+                     pSink, pMixStream, pSink->cStreams));
+
+        if (ppStream)
+            *ppStream = pMixStream;
+
+        rc = VINF_SUCCESS;
+    }
+    else
+        rc = VERR_NO_MEMORY;
+
+    return rc;
+}
+
+int audioMixerAddStreamOut(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOGSTSTRMOUT pStream,
+                           uint32_t uFlags, PAUDMIXSTREAM *ppStream)
+{
+    AssertPtrReturn(pSink, VERR_INVALID_POINTER);
+    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
+    /** @todo Add flag validation. */
+    /* ppStream is optional. */
+
+    int rc;
+
+    if (pSink->cStreams == UINT8_MAX) /* 255 streams per sink max. */
+        return VERR_TOO_MUCH_DATA;
+
+    PAUDMIXSTREAM pMixStream
+        = (PAUDMIXSTREAM)RTMemAllocZ(sizeof(AUDMIXSTREAM));
+    if (pMixStream)
+    {
+        pMixStream->pConn = pConnector;
+        pMixStream->pOut  = pStream;
         /** @todo Process flags. */
 
@@ -137,4 +182,8 @@
             pMixer->cSinks = 0;
             RTListInit(&pMixer->lstSinks);
+
+            pMixer->VolMaster.fMuted = false;
+            pMixer->VolMaster.uLeft  = UINT32_MAX;
+            pMixer->VolMaster.uRight = UINT32_MAX;
 
             LogFlowFunc(("Created %p ...\n", pMixer));
@@ -213,5 +262,5 @@
 }
 
-int audioMixerProcessSinkIn(PAUDMIXSINK pSink, void *pvBuf, size_t cbBuf, uint32_t *pcbProcessed)
+int audioMixerProcessSinkIn(PAUDMIXSINK pSink, AUDMIXOP enmOp, void *pvBuf, size_t cbBuf, uint32_t *pcbProcessed)
 {
     AssertPtrReturn(pSink, VERR_INVALID_POINTER);
@@ -220,4 +269,6 @@
     /* pcbProcessed is optional. */
 
+    /** @todo Handle mixing operation enmOp! */
+
     uint8_t *pvMixBuf = (uint8_t *)RTMemAlloc(cbBuf);
     if (!pvMixBuf)
@@ -233,5 +284,5 @@
     {
         /** @todo Support output sinks as well! */
-        if (!pStream->pConn->pfnIsActiveIn(pStream->pConn, pStream->pStrm))
+        if (!pStream->pConn->pfnIsActiveIn(pStream->pConn, pStream->pIn))
             continue;
 
@@ -243,5 +294,5 @@
             uint32_t cbRead;
             AssertPtr(pStream->pConn);
-            rc = pStream->pConn->pfnRead(pStream->pConn, pStream->pStrm,
+            rc = pStream->pConn->pfnRead(pStream->pConn, pStream->pIn,
                                          (uint8_t *)pvMixBuf + cbTotalRead, cbToRead, &cbRead);
             if (   RT_FAILURE(rc)
@@ -274,4 +325,9 @@
 }
 
+int audioMixerProcessSinkOut(PAUDMIXSINK pSink, AUDMIXOP enmOp, const void *pvBuf, size_t cbBuf, uint32_t *pcbProcessed)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
 void audioMixerRemoveSink(PAUDIOMIXER pMixer, PAUDMIXSINK pSink)
 {
@@ -312,6 +368,6 @@
         return;
 
+    Assert(pSink->cStreams);
     RTListNodeRemove(&pStream->Node);
-    Assert(pSink->cStreams);
     pSink->cStreams--;
 
@@ -333,2 +389,75 @@
 }
 
+static PDMAUDIOVOLUME audioMixerTranslateVolume(const PPDMAUDIOVOLUME pVolMaster, PPDMAUDIOVOLUME pVol)
+{
+    PDMAUDIOVOLUME volMaster = *pVolMaster;
+
+    uint32_t u32VolumeLeft  = (uint32_t)pVol->uLeft;
+    uint32_t u32VolumeRight = (uint32_t)pVol->uRight;
+    /* 0x00..0xff => 0x01..0x100 */
+    if (u32VolumeLeft)
+        u32VolumeLeft++;
+    if (u32VolumeRight)
+        u32VolumeRight++;
+
+    volMaster.uLeft  = u32VolumeLeft  * 0x800000; /* Maximum is 0x80000000 */
+    volMaster.uRight = u32VolumeRight * 0x800000; /* Maximum is 0x80000000 */
+
+    PDMAUDIOVOLUME volOut;
+    volOut.fMuted = volMaster.fMuted || pVol->fMuted;
+    volOut.uLeft  = ASMMultU64ByU32DivByU32(volMaster.uLeft,  pVol->uLeft,  0x80000000U); /* Maximum is 0x80000000U */
+    volOut.uRight = ASMMultU64ByU32DivByU32(volMaster.uRight, pVol->uRight, 0x80000000U); /* Maximum is 0x80000000U */
+
+    LogFlowFunc(("pMaster=%p, lVol=%RU32, rVol=%RU32\n",
+                 pVolMaster, pVolMaster->uLeft, pVolMaster->uRight));
+    LogFlowFunc(("pVol=%p, lVol=%RU32, rVol=%RU32 => lVol=%RU32, rVol=%RU32\n",
+                 pVol, pVol->uLeft, pVol->uRight, volOut.uLeft, volOut.uRight));
+
+    return volOut;
+}
+
+int audioMixerSetMasterVolume(PAUDIOMIXER pMixer, PPDMAUDIOVOLUME pVol)
+{
+    AssertPtrReturn(pMixer, VERR_INVALID_POINTER);
+    AssertPtrReturn(pVol, VERR_INVALID_POINTER);
+
+    pMixer->VolMaster = audioMixerTranslateVolume(&pMixer->VolMaster,  pVol);
+#if 0
+        .uLeft  = pVol->uLeft  * 0x800000; /* maximum is 0x80000000 */
+    pMixer->VolMaster.uRight = pVol->uRight * 0x800000; /* maximum is 0x80000000 */
+#endif
+    LogFlowFunc(("%s: lVol=%RU32, rVol=%RU32 => lVol=%RU32, rVol=%RU32\n",
+                  pVol->uLeft, pVol->uRight, pMixer->VolMaster.uLeft, pMixer->VolMaster.uRight));
+
+    return VINF_SUCCESS;
+}
+
+int audioMixerSetSinkVolume(PAUDMIXSINK pSink, PPDMAUDIOVOLUME pVol)
+{
+    AssertPtrReturn(pSink, VERR_INVALID_POINTER);
+    AssertPtrReturn(pVol, VERR_INVALID_POINTER);
+
+    LogFlowFunc(("%s: lVol=%RU32, rVol=%RU32\n", pSink->pszName, pVol->uLeft, pVol->uRight));
+
+    pSink->Volume.uLeft  = pVol->uLeft  * 0x808080; /* Maximum is INT_MAX = 0x7fffffff */
+    pSink->Volume.uRight = pVol->uRight * 0x808080; /* Maximum is INT_MAX = 0x7fffffff */
+
+    /** @todo Apply the mixer's master volume to it. */
+
+    /** @todo Very crude implementation for now -- needs more work! */
+
+    bool fOut = pSink->enmDir == AUDMIXSINKDIR_OUTPUT;
+
+    /* Propagate new sink volume to all streams in the sink. */
+    PAUDMIXSTREAM pStream;
+    RTListForEach(&pSink->lstStreams, pStream, AUDMIXSTREAM, Node)
+    {
+        if (fOut)
+            audioMixBufSetVolume(&pStream->pOut->MixBuf, &pSink->Volume);
+        else
+            audioMixBufSetVolume(&pStream->pIn->MixBuf,  &pSink->Volume);
+    }
+
+    return VINF_SUCCESS;
+}
+
Index: /trunk/src/VBox/Devices/Audio/AudioMixer.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/AudioMixer.h	(revision 55004)
+++ /trunk/src/VBox/Devices/Audio/AudioMixer.h	(revision 55005)
@@ -32,4 +32,6 @@
      *  can work with it. */
     PDMAUDIOSTREAMCFG       devFmt;
+    /** The master volume of this mixer. */
+    PDMAUDIOVOLUME          VolMaster;
     /* List of audio mixer sinks. */
     RTLISTANCHOR            lstSinks;
@@ -42,6 +44,9 @@
     RTLISTNODE              Node;
     PPDMIAUDIOCONNECTOR     pConn;
-    /** @todo Add support for output streams. */
-    PPDMAUDIOGSTSTRMIN      pStrm;
+    union
+    {
+        PPDMAUDIOGSTSTRMIN  pIn;
+        PPDMAUDIOGSTSTRMOUT pOut;
+    };
 } AUDMIXSTREAM, *PAUDMIXSTREAM;
 
@@ -50,5 +55,7 @@
     AUDMIXSINKDIR_UNKNOWN = 0,
     AUDMIXSINKDIR_INPUT,
-    AUDMIXSINKDIR_OUTPUT
+    AUDMIXSINKDIR_OUTPUT,
+    /** The usual 32-bit hack. */
+    AUDMIXSINKDIR_32BIT_HACK = 0x7fffffff
 } AUDMIXSINKDIR;
 
@@ -70,4 +77,7 @@
     /** This sink's mixing buffer. */
     PDMAUDIOMIXBUF          MixBuf;
+    /** The volume of this sink. The volume always will
+     *  be combined with the mixer's master volume. */
+    PDMAUDIOVOLUME          Volume;
 } AUDMIXSINK, *PAUDMIXSINK;
 
@@ -76,20 +86,25 @@
     AUDMIXOP_NONE = 0,
     AUDMIXOP_COPY,
-    AUDMIXOP_BLEND
+    AUDMIXOP_BLEND,
+    /** The usual 32-bit hack. */
+    AUDMIXOP_32BIT_HACK = 0x7fffffff
 } AUDMIXOP;
 
 
-int audioMixerAddSink(PAUDIOMIXER pMixer, const char *pszName, PAUDMIXSINK *ppSink);
+int audioMixerAddSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PAUDMIXSINK *ppSink);
 int audioMixerAddStreamIn(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOGSTSTRMIN pStream, uint32_t uFlags, PAUDMIXSTREAM *ppStream);
-int audioMixerControlStream(AUDMIXSTREAM pHandle); /** @todo */
+int audioMixerAddStreamOut(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOGSTSTRMOUT pStream, uint32_t uFlags, PAUDMIXSTREAM *ppStream);
+int audioMixerControlStream(AUDMIXSTREAM pHandle); /** @todo Implement me. */
 int audioMixerCreate(const char *pszName, uint32_t uFlags, PAUDIOMIXER *ppMixer);
 void audioMixerDestroy(PAUDIOMIXER pMixer);
-int audioMixerProcessSamples(AUDMIXOP enmOp, PPDMAUDIOSAMPLE pDst, uint32_t cToWrite, PPDMAUDIOSAMPLE pSrc, uint32_t cToRead, uint32_t *pcRead, uint32_t *pcWritten);
-int audioMixerProcessSamplesEx(AUDMIXOP enmOp, void *pvParms, size_t cbParms, PPDMAUDIOSAMPLE pDst, uint32_t cToWrite, PPDMAUDIOSAMPLE pSrc, uint32_t cToRead, uint32_t *pcRead, uint32_t *pcWritten);
 uint32_t audioMixerGetStreamCount(PAUDIOMIXER pMixer);
-int audioMixerProcessSinkIn(PAUDMIXSINK pSink, void *pvBuf, size_t cbBuf, uint32_t *pcbProcessed);
+int audioMixerProcessSinkIn(PAUDMIXSINK pSink, AUDMIXOP enmOp, void *pvBuf, size_t cbBuf, uint32_t *pcbProcessed);
+int audioMixerProcessSinkOut(PAUDMIXSINK pSink, AUDMIXOP enmOp, const void *pvBuf, size_t cbBuf, uint32_t *pcbProcessed);
 void audioMixerRemoveSink(PAUDIOMIXER pMixer, PAUDMIXSINK pSink);
 void audioMixerRemoveStream(PAUDMIXSINK pMixer, PAUDMIXSTREAM pStream);
 int audioMixerSetDeviceFormat(PAUDIOMIXER pMixer, PPDMAUDIOSTREAMCFG pCfg);
+int audioMixerSetMasterVolume(PAUDIOMIXER pMixer, PPDMAUDIOVOLUME pVol);
+int audioMixerSetSinkVolume(PAUDMIXSINK pSink, PPDMAUDIOVOLUME pVol);
 
 #endif /* AUDIO_MIXER_H */
+
Index: /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 55004)
+++ /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 55005)
@@ -64,9 +64,14 @@
 #define AC97_SSM_VERSION 1
 
-#ifndef VBOX
-# define SOFT_VOLUME
+#ifdef VBOX
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+#  define SOFT_VOLUME /** @todo Get rid of this crap. */
+# else
+#  undef  SOFT_VOLUME
+# endif
 #else
-# undef  SOFT_VOLUME
+# define  SOFT_VOLUME
 #endif
+
 #define SR_FIFOE RT_BIT(4)          /* rwc, fifo error */
 #define SR_BCIS  RT_BIT(3)          /* rwc, buffer completion interrupt status */
@@ -151,5 +156,5 @@
     AC97_Reset                     = 0x00,
     AC97_Master_Volume_Mute        = 0x02,
-    AC97_Headphone_Volume_Mute     = 0x04,
+    AC97_Headphone_Volume_Mute     = 0x04, /** Also known as AUX, see table 16, section 5.7. */
     AC97_Master_Volume_Mono_Mute   = 0x06,
     AC97_Master_Tone_RL            = 0x08,
@@ -224,4 +229,6 @@
     /** PCM output stream. */
     R3PTRTYPE(PPDMAUDIOGSTSTRMOUT)     pStrmOut;
+    /** Mixer handle for output stream. */
+    R3PTRTYPE(PAUDMIXSTREAM)           phStrmOut;
 } AC97OUTPUTSTREAM, *PAC97OUTPUTSTREAM;
 
@@ -293,4 +300,6 @@
     /** The device' software mixer. */
     R3PTRTYPE(PAUDIOMIXER)  pMixer;
+    /** Audio sink for PCM output. */
+    R3PTRTYPE(PAUDMIXSINK)  pSinkOutput;
     /** Audio sink for line input. */
     R3PTRTYPE(PAUDMIXSINK)  pSinkLineIn;
@@ -603,4 +612,12 @@
                     rc = pDrv->pConnector->pfnOpenOut(pDrv->pConnector, pszDesc, &streamCfg, &pDrv->Out.pStrmOut);
                     LogFlowFunc(("LUN#%RU8: Opened output with rc=%Rrc\n", uLUN, rc));
+                    if (rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */
+                    {
+                        audioMixerRemoveStream(pThis->pSinkOutput, pDrv->Out.phStrmOut);
+                        rc = audioMixerAddStreamOut(pThis->pSinkOutput,
+                                                    pDrv->pConnector, pDrv->Out.pStrmOut,
+                                                    0 /* uFlags */,
+                                                    &pDrv->Out.phStrmOut);
+                    }
 
                     RTStrFree(pszDesc);
@@ -653,7 +670,7 @@
                 {
                     pDrv->pConnector->pfnCloseIn(pDrv->pConnector, pDrv->LineIn.pStrmIn);
-                    audioMixerRemoveStream(pThis->pSinkLineIn,pDrv->LineIn.phStrmIn);
-
-                    pDrv->LineIn.pStrmIn = NULL;
+                    audioMixerRemoveStream(pThis->pSinkLineIn, pDrv->LineIn.phStrmIn);
+
+                    pDrv->LineIn.pStrmIn  = NULL;
                     pDrv->LineIn.phStrmIn = NULL;
                 }
@@ -668,5 +685,8 @@
                 {
                     pDrv->pConnector->pfnCloseOut(pDrv->pConnector, pDrv->Out.pStrmOut);
-                    pDrv->Out.pStrmOut = NULL;
+                    audioMixerRemoveStream(pThis->pSinkOutput, pDrv->Out.phStrmOut);
+
+                    pDrv->Out.pStrmOut  = NULL;
+                    pDrv->Out.phStrmOut = NULL;
                 }
 
@@ -827,35 +847,43 @@
     lvol = 255 * lvol / VOL_MASK;
 
-#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-    PAC97DRIVER pDrv;
-#endif
+    LogFunc(("mt=%ld, val=%RU32\n", mt, val));
 
 #ifdef SOFT_VOLUME
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    if (pThis->pMixer) /* Device can be in reset state, so no mixer available. */
+    {
+        PDMAUDIOVOLUME vol = { RT_BOOL(mute), lvol, rvol };
+        PAC97DRIVER pDrv;
+        switch (mt)
+        {
+            case PDMAUDIOMIXERCTL_VOLUME:
+                audioMixerSetMasterVolume(pThis->pMixer, &vol);
+                break;
+
+            case PDMAUDIOMIXERCTL_PCM:
+                audioMixerSetSinkVolume(pThis->pSinkOutput, &vol);
+                break;
+
+            case PDMAUDIOMIXERCTL_MIC_IN:
+                audioMixerSetSinkVolume(pThis->pSinkMicIn, &vol);
+                break;
+
+            case PDMAUDIOMIXERCTL_LINE_IN:
+                audioMixerSetSinkVolume(pThis->pSinkLineIn, &vol);
+                break;
+
+            default:
+                break;
+        }
+    }
+# else /* !VBOX_WITH_PDM_AUDIO_DRIVER */
     if (index == AC97_Master_Volume_Mute)
-    {
-#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-        RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
-            pDrv->pConnector->pfnSetVolumeOut(pDrv->pConnector, pDrv->Out.pStrmOut, RT_BOOL(mute), lvol, rvol);
-#else
         AUD_set_volume_out(pThis->voice_po, mute, lvol, rvol);
-#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
-    }
-    /** @todo Handle AC97_Mic_Volume_Mute + AC97_Line_In_Volume_Mute. */
     else
-    {
-#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-        RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
-            pDrv->pConnector->pfnSetVolume(pDrv->pConnector, RT_BOOL(mute), lvol, rvol);
-#else
         AUD_set_volume(mt, &mute, &lvol, &rvol);
-#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
-    }
+# endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
+
 #else /* !SOFT_VOLUME */
-#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-    RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
-        pDrv->pConnector->pfnSetVolume(pDrv->pConnector, RT_BOOL(mute), lvol, rvol);
-#else
     AUD_set_volume(mt, &mute, &lvol, &rvol);
-#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
 #endif /* SOFT_VOLUME */
 
@@ -940,10 +968,12 @@
     RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
     {
+        pDrv->Out.phStrmOut   = NULL;
         pDrv->LineIn.phStrmIn = NULL;
         pDrv->MicIn.phStrmIn  = NULL;
     }
 
+    pThis->pSinkOutput = NULL;
     pThis->pSinkLineIn = NULL;
-    pThis->pSinkMicIn = NULL;
+    pThis->pSinkMicIn  = NULL;
 
     if (pThis->pMixer)
@@ -1000,10 +1030,10 @@
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-    int rc2 = audioMixerCreate("AC'97 Mixer", 0 /* uFlags */,
-                               &pThis->pMixer);
+    int rc2 = audioMixerCreate("AC'97 Mixer", 0 /* uFlags */, &pThis->pMixer);
     if (RT_SUCCESS(rc2))
     {
+        /* Set a default audio format for our mixer. */
         PDMAUDIOSTREAMCFG streamCfg;
-        streamCfg.uHz           = 48000;
+        streamCfg.uHz           = 41000;
         streamCfg.cChannels     = 2;
         streamCfg.enmFormat     = AUD_FMT_S16;
@@ -1014,10 +1044,14 @@
 
         /* Add all required audio sinks. */
+        rc2 = audioMixerAddSink(pThis->pMixer, "[Playback] PCM Output",
+                               AUDMIXSINKDIR_OUTPUT, &pThis->pSinkOutput);
+        AssertRC(rc2);
+
         rc2 = audioMixerAddSink(pThis->pMixer, "[Recording] Line In",
-                                &pThis->pSinkLineIn);
+                                AUDMIXSINKDIR_INPUT, &pThis->pSinkLineIn);
         AssertRC(rc2);
 
         rc2 = audioMixerAddSink(pThis->pMixer, "[Recording] Microphone In",
-                                &pThis->pSinkMicIn);
+                                AUDMIXSINKDIR_INPUT, &pThis->pSinkMicIn);
         AssertRC(rc2);
     }
@@ -1209,5 +1243,5 @@
     if (pvMixBuf)
     {
-        rc = audioMixerProcessSinkIn(pSink, pvMixBuf, cbToRead, &cbRead);
+        rc = audioMixerProcessSinkIn(pSink, AUDMIXOP_BLEND, pvMixBuf, cbToRead, &cbRead);
         if (   RT_SUCCESS(rc)
             && cbRead)
Index: /trunk/src/VBox/Devices/Audio/DevIchHda.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchHda.cpp	(revision 55004)
+++ /trunk/src/VBox/Devices/Audio/DevIchHda.cpp	(revision 55005)
@@ -678,4 +678,6 @@
     /** The device' software mixer. */
     R3PTRTYPE(PAUDIOMIXER)             pMixer;
+    /** Audio sink for PCM output. */
+    R3PTRTYPE(PAUDMIXSINK)             pSinkOutput;
     /** Audio mixer sink for line input. */
     R3PTRTYPE(PAUDMIXSINK)             pSinkLineIn;
@@ -2206,5 +2208,5 @@
     {
         uint32_t cbRead = 0;
-        rc = audioMixerProcessSinkIn(pSink, pBdle->au8HdaBuffer, cb2Copy, &cbRead);
+        rc = audioMixerProcessSinkIn(pSink, AUDMIXOP_BLEND, pBdle->au8HdaBuffer, cb2Copy, &cbRead);
         if (RT_SUCCESS(rc))
         {
@@ -2511,17 +2513,6 @@
     int rc = VINF_SUCCESS;
 
-    PHDADRIVER pDrv;
-    RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
-    {
-        int rc2 = pDrv->pConnector->pfnSetVolume(pDrv->pConnector,
-                                                 fMute, uVolLeft, uVolRight);
-        if (RT_FAILURE(rc2))
-        {
-            LogFunc(("Failed for LUN #%RU8, rc=%Rrc\n", pDrv->uLUN, rc2));
-            if (RT_SUCCESS(rc))
-                rc = rc2;
-            /* Keep going. */
-        }
-    }
+    PDMAUDIOVOLUME vol = { fMute, uVolLeft, uVolRight };
+    audioMixerSetMasterVolume(pThis->pMixer, &vol);
 
     LogFlowFuncLeaveRC(rc);
@@ -3837,10 +3828,10 @@
     if (RT_SUCCESS(rc))
     {
-        rc = audioMixerCreate("HDA Mixer", 0 /* uFlags */,
-                              &pThis->pMixer);
+        rc = audioMixerCreate("HDA Mixer", 0 /* uFlags */, &pThis->pMixer);
         if (RT_SUCCESS(rc))
         {
+            /* Set a default audio format for our mixer. */
             PDMAUDIOSTREAMCFG streamCfg;
-            streamCfg.uHz           = 48000;
+            streamCfg.uHz           = 41000;
             streamCfg.cChannels     = 2;
             streamCfg.enmFormat     = AUD_FMT_S16;
@@ -3851,10 +3842,14 @@
 
             /* Add all required audio sinks. */
+            rc = audioMixerAddSink(pThis->pMixer, "[Playback] PCM Output",
+                                   AUDMIXSINKDIR_OUTPUT, &pThis->pSinkOutput);
+            AssertRC(rc);
+
             rc = audioMixerAddSink(pThis->pMixer, "[Recording] Line In",
-                                   &pThis->pSinkLineIn);
+                                   AUDMIXSINKDIR_INPUT, &pThis->pSinkLineIn);
             AssertRC(rc);
 
             rc = audioMixerAddSink(pThis->pMixer, "[Recording] Microphone In",
-                                   &pThis->pSinkMicIn);
+                                   AUDMIXSINKDIR_INPUT, &pThis->pSinkMicIn);
             AssertRC(rc);
         }
Index: /trunk/src/VBox/Devices/Audio/DevSB16.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 55004)
+++ /trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 55005)
@@ -40,8 +40,10 @@
 #include "vl_vbox.h"
 
-#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
-extern "C" {
-#include "audio.h"
-}
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+# include "AudioMixer.h"
+#else
+ extern "C" {
+  #include "audio.h"
+ }
 #endif
 
@@ -84,12 +86,54 @@
 #endif /* !VBOX */
 
-typedef struct SB16State {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+typedef struct SB16OUTPUTSTREAM
+{
+    /** PCM output stream. */
+    R3PTRTYPE(PPDMAUDIOGSTSTRMOUT)     pStrmOut;
+    /** Mixer handle for output stream. */
+    R3PTRTYPE(PAUDMIXSTREAM)           phStrmOut;
+} SB16OUTPUTSTREAM, *PSB16OUTPUTSTREAM;
+
+/**
+ * Struct for maintaining a host backend driver.
+ */
+typedef struct SB16STATE *PSB16STATE;
+typedef struct SB16DRIVER
+{
+    union
+    {
+        /** Node for storing this driver in our device driver
+         *  list of AC97STATE. */
+        RTLISTNODE                     Node;
+        struct
+        {
+            R3PTRTYPE(void *)          dummy1;
+            R3PTRTYPE(void *)          dummy2;
+        } dummy;
+    };
+
+    /** Pointer to SB16 controller (state). */
+    R3PTRTYPE(PSB16STATE)              pSB16State;
+    /** Driver flags. */
+    PDMAUDIODRVFLAGS                   Flags;
+    uint32_t                           PaddingFlags;
+    /** LUN # to which this driver has been assigned. */
+    uint8_t                            uLUN;
+    uint8_t                            Padding[5];
+    /** Audio connector interface to the underlying
+     *  host backend. */
+    R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pConnector;
+    /** Stream for output. */
+    SB16OUTPUTSTREAM                   Out;
+} SB16DRIVER, *PSB16DRIVER;
+#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
+
+typedef struct SB16STATE
+{
 #ifdef VBOX
     /** Pointer to the device instance. */
-    PPDMDEVINSR3 pDevIns;
+    PPDMDEVINSR3        pDevIns;
     /** Pointer to the connector of the attached audio driver. */
-    PPDMIAUDIOCONNECTOR     pDrv;
-#endif
-#ifdef VBOX /* lazy bird */
+    PPDMIAUDIOCONNECTOR pDrv;
     int irqCfg;
     int dmaCfg;
@@ -152,5 +196,11 @@
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-    PPDMAUDIOGSTSTRMOUT pGstStrmOut;
+    R3PTRTYPE(PPDMAUDIOGSTSTRMOUT) pGstStrmOut;
+    /** List of associated LUN drivers. */
+    RTLISTANCHOR                   lstDrv;
+    /** The device' software mixer. */
+    R3PTRTYPE(PAUDIOMIXER)         pMixer;
+    /** Audio sink for PCM output. */
+    R3PTRTYPE(PAUDMIXSINK)         pSinkOutput;
 #else
     SWVoiceOut *voice;
@@ -165,5 +215,5 @@
     int mixer_nreg;
     uint8_t mixer_regs[256];
-} SB16State;
+} SB16STATE, *PSB16STATE;
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
@@ -222,44 +272,44 @@
 #endif
 
-static void speaker (SB16State *s, int on)
-{
-    s->speaker = on;
-    /* AUD_enable (s->voice, on); */
-}
-
-static void control (SB16State *s, int hold)
-{
-    int dma = s->use_hdma ? s->hdma : s->dma;
-    s->dma_running = hold;
-
-    LogFlowFunc(("hold %d high %d dma %d\n", hold, s->use_hdma, dma));
+static void speaker (PSB16STATE pThis, int on)
+{
+    pThis->speaker = on;
+    /* AUD_enable (pThis->voice, on); */
+}
+
+static void control (PSB16STATE pThis, int hold)
+{
+    int dma = pThis->use_hdma ? pThis->hdma : pThis->dma;
+    pThis->dma_running = hold;
+
+    LogFlowFunc(("hold %d high %d dma %d\n", hold, pThis->use_hdma, dma));
 
 #ifndef VBOX
     if (hold) {
         DMA_hold_DREQ (dma);
-        AUD_set_active_out (s->voice, 1);
+        AUD_set_active_out (pThis->voice, 1);
     }
     else {
         DMA_release_DREQ (dma);
-        AUD_set_active_out (s->voice, 0);
+        AUD_set_active_out (pThis->voice, 0);
     }
 #else  /* VBOX */
     if (hold)
     {
-        PDMDevHlpDMASetDREQ (s->pDevIns, dma, 1);
-        PDMDevHlpDMASchedule (s->pDevIns);
+        PDMDevHlpDMASetDREQ (pThis->pDevIns, dma, 1);
+        PDMDevHlpDMASchedule (pThis->pDevIns);
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-        s->pDrv->pfnEnableOut(s->pDrv, s->pGstStrmOut, true /* fEnable */);
-#else
-        AUD_set_active_out (s->voice, 1);
+        pThis->pDrv->pfnEnableOut(pThis->pDrv, pThis->pGstStrmOut, true /* fEnable */);
+#else
+        AUD_set_active_out (pThis->voice, 1);
 #endif
     }
     else
     {
-        PDMDevHlpDMASetDREQ (s->pDevIns, dma, 0);
+        PDMDevHlpDMASetDREQ (pThis->pDevIns, dma, 0);
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-        s->pDrv->pfnEnableOut(s->pDrv, s->pGstStrmOut, false /* fEnable */);
-#else
-        AUD_set_active_out (s->voice, 0);
+        pThis->pDrv->pfnEnableOut(pThis->pDrv, pThis->pGstStrmOut, false /* fEnable */);
+#else
+        AUD_set_active_out (pThis->voice, 0);
 #endif
     }
@@ -270,14 +320,14 @@
 static void aux_timer (void *opaque)
 {
-    SB16State *s = opaque;
-    s->can_write = 1;
-    qemu_irq_raise (s->pic[s->irq]);
+    PSB16STATE pThis = opaque;
+    pThis->can_write = 1;
+    qemu_irq_raise (pThis->pic[pThis->irq]);
 }
 #else  /* VBOX */
 static DECLCALLBACK(void) sb16Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvThis)
 {
-    SB16State *s = (SB16State *)pvThis;
-    s->can_write = 1;
-    PDMDevHlpISASetIrq(s->pDevIns, s->irq, 1);
+    PSB16STATE pThis = (SB16STATE *)pvThis;
+    pThis->can_write = 1;
+    PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
 }
 #endif /* VBOX */
@@ -286,30 +336,30 @@
 #define DMA8_HIGH 2
 
-static void continue_dma8 (SB16State *s)
-{
-    if (s->freq > 0)
+static void continue_dma8 (PSB16STATE pThis)
+{
+    if (pThis->freq > 0)
     {
-        s->audio_free = 0;
+        pThis->audio_free = 0;
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
         PDMAUDIOSTREAMCFG as;
-        as.uHz           = s->freq;
-        as.cChannels     = 1 << s->fmt_stereo;
-        as.enmFormat     = s->fmt;
+        as.uHz           = pThis->freq;
+        as.cChannels     = 1 << pThis->fmt_stereo;
+        as.enmFormat     = pThis->fmt;
         as.enmEndianness = PDMAUDIOHOSTENDIANESS;
 
-        int rc = s->pDrv->pfnOpenOut(s->pDrv, "sb16.out", &as, &s->pGstStrmOut);
+        int rc = pThis->pDrv->pfnOpenOut(pThis->pDrv, "sb16.out", &as, &pThis->pGstStrmOut);
         AssertRC(rc);
 #else
         audsettings_t as;
-        as.freq = s->freq;
-        as.nchannels = 1 << s->fmt_stereo;
-        as.fmt = s->fmt;
+        as.freq = pThis->freq;
+        as.nchannels = 1 << pThis->fmt_stereo;
+        as.fmt = pThis->fmt;
         as.endianness = 0;
-        s->voice = AUD_open_out (
-            &s->card,
-            s->voice,
+        pThis->voice = AUD_open_out (
+            &pThis->card,
+            pThis->voice,
             "sb16",
-            s,
+            pThis,
             sb16AudioCallback,
             &as
@@ -318,25 +368,25 @@
     }
 
-    control (s, 1);
-}
-
-static void dma_cmd8 (SB16State *s, int mask, int dma_len)
-{
-    s->fmt = AUD_FMT_U8;
-    s->use_hdma = 0;
-    s->fmt_bits = 8;
-    s->fmt_signed = 0;
-    s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
-    if (-1 == s->time_const) {
-        if (s->freq <= 0)
-            s->freq = 11025;
+    control(pThis, 1);
+}
+
+static void dma_cmd8 (PSB16STATE pThis, int mask, int dma_len)
+{
+    pThis->fmt = AUD_FMT_U8;
+    pThis->use_hdma = 0;
+    pThis->fmt_bits = 8;
+    pThis->fmt_signed = 0;
+    pThis->fmt_stereo = (pThis->mixer_regs[0x0e] & 2) != 0;
+    if (-1 == pThis->time_const) {
+        if (pThis->freq <= 0)
+            pThis->freq = 11025;
     }
     else {
-        int tmp = (256 - s->time_const);
-        s->freq = (1000000 + (tmp / 2)) / tmp;
+        int tmp = (256 - pThis->time_const);
+        pThis->freq = (1000000 + (tmp / 2)) / tmp;
     }
 
     if (dma_len != -1) {
-        s->block_size = dma_len << s->fmt_stereo;
+        pThis->block_size = dma_len << pThis->fmt_stereo;
     }
     else {
@@ -350,123 +400,123 @@
            Both use stereo, and Creatives own documentation states that
            0x48 sets block size in bytes less one.. go figure */
-        s->block_size &= ~s->fmt_stereo;
-    }
-
-    s->freq >>= s->fmt_stereo;
-    s->left_till_irq = s->block_size;
-    s->bytes_per_second = (s->freq << s->fmt_stereo);
-    /* s->highspeed = (mask & DMA8_HIGH) != 0; */
-    s->dma_auto = (mask & DMA8_AUTO) != 0;
-    s->align = (1 << s->fmt_stereo) - 1;
-
-    if (s->block_size & s->align) {
+        pThis->block_size &= ~pThis->fmt_stereo;
+    }
+
+    pThis->freq >>= pThis->fmt_stereo;
+    pThis->left_till_irq = pThis->block_size;
+    pThis->bytes_per_second = (pThis->freq << pThis->fmt_stereo);
+    /* pThis->highspeed = (mask & DMA8_HIGH) != 0; */
+    pThis->dma_auto = (mask & DMA8_AUTO) != 0;
+    pThis->align = (1 << pThis->fmt_stereo) - 1;
+
+    if (pThis->block_size & pThis->align) {
         LogFlowFunc(("warning: misaligned block size %d, alignment %d\n",
-               s->block_size, s->align + 1));
+               pThis->block_size, pThis->align + 1));
     }
 
     LogFlowFunc(("freq %d, stereo %d, sign %d, bits %d, "
             "dma %d, auto %d, fifo %d, high %d\n",
-            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
-            s->block_size, s->dma_auto, s->fifo, s->highspeed));
-
-    continue_dma8 (s);
-    speaker (s, 1);
-}
-
-static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
-{
-    s->use_hdma = cmd < 0xc0;
-    s->fifo = (cmd >> 1) & 1;
-    s->dma_auto = (cmd >> 2) & 1;
-    s->fmt_signed = (d0 >> 4) & 1;
-    s->fmt_stereo = (d0 >> 5) & 1;
+            pThis->freq, pThis->fmt_stereo, pThis->fmt_signed, pThis->fmt_bits,
+            pThis->block_size, pThis->dma_auto, pThis->fifo, pThis->highspeed));
+
+    continue_dma8 (pThis);
+    speaker (pThis, 1);
+}
+
+static void dma_cmd (PSB16STATE pThis, uint8_t cmd, uint8_t d0, int dma_len)
+{
+    pThis->use_hdma = cmd < 0xc0;
+    pThis->fifo = (cmd >> 1) & 1;
+    pThis->dma_auto = (cmd >> 2) & 1;
+    pThis->fmt_signed = (d0 >> 4) & 1;
+    pThis->fmt_stereo = (d0 >> 5) & 1;
 
     switch (cmd >> 4) {
     case 11:
-        s->fmt_bits = 16;
+        pThis->fmt_bits = 16;
         break;
 
     case 12:
-        s->fmt_bits = 8;
+        pThis->fmt_bits = 8;
         break;
     }
 
-    if (-1 != s->time_const) {
+    if (-1 != pThis->time_const) {
 #if 1
-        int tmp = 256 - s->time_const;
-        s->freq = (1000000 + (tmp / 2)) / tmp;
-#else
-        /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
-        s->freq = 1000000 / ((255 - s->time_const));
-#endif
-        s->time_const = -1;
-    }
-
-    s->block_size = dma_len + 1;
-    s->block_size <<= ((s->fmt_bits == 16) ? 1 : 0);
-    if (!s->dma_auto) {
+        int tmp = 256 - pThis->time_const;
+        pThis->freq = (1000000 + (tmp / 2)) / tmp;
+#else
+        /* pThis->freq = 1000000 / ((255 - pThis->time_const) << pThis->fmt_stereo); */
+        pThis->freq = 1000000 / ((255 - pThis->time_const));
+#endif
+        pThis->time_const = -1;
+    }
+
+    pThis->block_size = dma_len + 1;
+    pThis->block_size <<= ((pThis->fmt_bits == 16) ? 1 : 0);
+    if (!pThis->dma_auto) {
         /* It is clear that for DOOM and auto-init this value
            shouldn't take stereo into account, while Miles Sound Systems
            setsound.exe with single transfer mode wouldn't work without it
            wonders of SB16 yet again */
-        s->block_size <<= s->fmt_stereo;
+        pThis->block_size <<= pThis->fmt_stereo;
     }
 
     LogFlowFunc(("freq %d, stereo %d, sign %d, bits %d, "
             "dma %d, auto %d, fifo %d, high %d\n",
-            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
-            s->block_size, s->dma_auto, s->fifo, s->highspeed));
-
-    if (16 == s->fmt_bits) {
-        if (s->fmt_signed) {
-            s->fmt = AUD_FMT_S16;
+            pThis->freq, pThis->fmt_stereo, pThis->fmt_signed, pThis->fmt_bits,
+            pThis->block_size, pThis->dma_auto, pThis->fifo, pThis->highspeed));
+
+    if (16 == pThis->fmt_bits) {
+        if (pThis->fmt_signed) {
+            pThis->fmt = AUD_FMT_S16;
         }
         else {
-            s->fmt = AUD_FMT_U16;
+            pThis->fmt = AUD_FMT_U16;
         }
     }
     else {
-        if (s->fmt_signed) {
-            s->fmt = AUD_FMT_S8;
+        if (pThis->fmt_signed) {
+            pThis->fmt = AUD_FMT_S8;
         }
         else {
-            s->fmt = AUD_FMT_U8;
-        }
-    }
-
-    s->left_till_irq = s->block_size;
-
-    s->bytes_per_second = (s->freq << s->fmt_stereo) << ((s->fmt_bits == 16) ? 1 : 0);
-    s->highspeed = 0;
-    s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
-    if (s->block_size & s->align) {
+            pThis->fmt = AUD_FMT_U8;
+        }
+    }
+
+    pThis->left_till_irq = pThis->block_size;
+
+    pThis->bytes_per_second = (pThis->freq << pThis->fmt_stereo) << ((pThis->fmt_bits == 16) ? 1 : 0);
+    pThis->highspeed = 0;
+    pThis->align = (1 << (pThis->fmt_stereo + (pThis->fmt_bits == 16))) - 1;
+    if (pThis->block_size & pThis->align) {
         LogFlowFunc(("warning: misaligned block size %d, alignment %d\n",
-               s->block_size, s->align + 1));
-    }
-
-    if (s->freq)
+               pThis->block_size, pThis->align + 1));
+    }
+
+    if (pThis->freq)
     {
-        s->audio_free = 0;
+        pThis->audio_free = 0;
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
         PDMAUDIOSTREAMCFG as;
-        as.uHz           = s->freq;
-        as.cChannels     = 1 << s->fmt_stereo;
-        as.enmFormat     = s->fmt;
+        as.uHz           = pThis->freq;
+        as.cChannels     = 1 << pThis->fmt_stereo;
+        as.enmFormat     = pThis->fmt;
         as.enmEndianness = PDMAUDIOHOSTENDIANESS;
 
-        int rc = s->pDrv->pfnOpenOut(s->pDrv, "sb16.out", &as, &s->pGstStrmOut);
+        int rc = pThis->pDrv->pfnOpenOut(pThis->pDrv, "sb16.out", &as, &pThis->pGstStrmOut);
         AssertRC(rc);
 #else
         audsettings_t as;
-        as.freq = s->freq;
-        as.nchannels = 1 << s->fmt_stereo;
-        as.fmt = s->fmt;
+        as.freq = pThis->freq;
+        as.nchannels = 1 << pThis->fmt_stereo;
+        as.fmt = pThis->fmt;
         as.endianness = 0;
-        s->voice = AUD_open_out (
-            &s->card,
-            s->voice,
+        pThis->voice = AUD_open_out (
+            &pThis->card,
+            pThis->voice,
             "sb16",
-            s,
+            pThis,
             sb16AudioCallback,
             &as
@@ -475,20 +525,20 @@
     }
 
-    control (s, 1);
-    speaker (s, 1);
-}
-
-static inline void dsp_out_data (SB16State *s, uint8_t val)
+    control (pThis, 1);
+    speaker (pThis, 1);
+}
+
+static inline void dsp_out_data (PSB16STATE pThis, uint8_t val)
 {
     LogFlowFunc(("outdata %#x\n", val));
-    if ((size_t) s->out_data_len < sizeof (s->out_data)) {
-        s->out_data[s->out_data_len++] = val;
-    }
-}
-
-static inline uint8_t dsp_get_data (SB16State *s)
-{
-    if (s->in_index) {
-        return s->in2_data[--s->in_index];
+    if ((size_t) pThis->out_data_len < sizeof (pThis->out_data)) {
+        pThis->out_data[pThis->out_data_len++] = val;
+    }
+}
+
+static inline uint8_t dsp_get_data (PSB16STATE pThis)
+{
+    if (pThis->in_index) {
+        return pThis->in2_data[--pThis->in_index];
     }
     else {
@@ -498,5 +548,5 @@
 }
 
-static void command (SB16State *s, uint8_t cmd)
+static void command (PSB16STATE pThis, uint8_t cmd)
 {
     LogFlowFunc(("command %#x\n", cmd));
@@ -514,20 +564,20 @@
             LogFlowFunc(("%#x wrong bits\n", cmd));
         }
-        s->needed_bytes = 3;
+        pThis->needed_bytes = 3;
     }
     else {
-        s->needed_bytes = 0;
+        pThis->needed_bytes = 0;
 
         switch (cmd) {
         case 0x03:
-            dsp_out_data (s, 0x10); /* s->csp_param); */
+            dsp_out_data (pThis, 0x10); /* pThis->csp_param); */
             goto warn;
 
         case 0x04:
-            s->needed_bytes = 1;
+            pThis->needed_bytes = 1;
             goto warn;
 
         case 0x05:
-            s->needed_bytes = 2;
+            pThis->needed_bytes = 2;
             goto warn;
 
@@ -537,30 +587,30 @@
 
         case 0x0e:
-            s->needed_bytes = 2;
+            pThis->needed_bytes = 2;
             goto warn;
 
         case 0x09:
-            dsp_out_data (s, 0xf8);
+            dsp_out_data (pThis, 0xf8);
             goto warn;
 
         case 0x0f:
-            s->needed_bytes = 1;
+            pThis->needed_bytes = 1;
             goto warn;
 
         case 0x10:
-            s->needed_bytes = 1;
+            pThis->needed_bytes = 1;
             goto warn;
 
         case 0x14:
-            s->needed_bytes = 2;
-            s->block_size = 0;
+            pThis->needed_bytes = 2;
+            pThis->block_size = 0;
             break;
 
         case 0x1c:              /* Auto-Initialize DMA DAC, 8-bit */
-            dma_cmd8 (s, DMA8_AUTO, -1);
+            dma_cmd8 (pThis, DMA8_AUTO, -1);
             break;
 
         case 0x20:              /* Direct ADC, Juice/PL */
-            dsp_out_data (s, 0xff);
+            dsp_out_data (pThis, 0xff);
             goto warn;
 
@@ -570,23 +620,23 @@
 
         case 0x40:
-            s->freq = -1;
-            s->time_const = -1;
-            s->needed_bytes = 1;
+            pThis->freq = -1;
+            pThis->time_const = -1;
+            pThis->needed_bytes = 1;
             break;
 
         case 0x41:
-            s->freq = -1;
-            s->time_const = -1;
-            s->needed_bytes = 2;
+            pThis->freq = -1;
+            pThis->time_const = -1;
+            pThis->needed_bytes = 2;
             break;
 
         case 0x42:
-            s->freq = -1;
-            s->time_const = -1;
-            s->needed_bytes = 2;
+            pThis->freq = -1;
+            pThis->time_const = -1;
+            pThis->needed_bytes = 2;
             goto warn;
 
         case 0x45:
-            dsp_out_data (s, 0xaa);
+            dsp_out_data (pThis, 0xaa);
             goto warn;
 
@@ -595,24 +645,24 @@
 
         case 0x48:
-            s->needed_bytes = 2;
+            pThis->needed_bytes = 2;
             break;
 
         case 0x74:
-            s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
+            pThis->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
             LogFlowFunc(("0x75 - DMA DAC, 4-bit ADPCM not implemented\n"));
             break;
 
         case 0x75:              /* DMA DAC, 4-bit ADPCM Reference */
-            s->needed_bytes = 2;
+            pThis->needed_bytes = 2;
             LogFlowFunc(("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n"));
             break;
 
         case 0x76:              /* DMA DAC, 2.6-bit ADPCM */
-            s->needed_bytes = 2;
+            pThis->needed_bytes = 2;
             LogFlowFunc(("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n"));
             break;
 
         case 0x77:              /* DMA DAC, 2.6-bit ADPCM Reference */
-            s->needed_bytes = 2;
+            pThis->needed_bytes = 2;
             LogFlowFunc(("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n"));
             break;
@@ -629,22 +679,22 @@
 
         case 0x80:
-            s->needed_bytes = 2;
+            pThis->needed_bytes = 2;
             break;
 
         case 0x90:
         case 0x91:
-            dma_cmd8 (s, (((cmd & 1) == 0) ? 1 : 0) | DMA8_HIGH, -1);
+            dma_cmd8 (pThis, (((cmd & 1) == 0) ? 1 : 0) | DMA8_HIGH, -1);
             break;
 
         case 0xd0:              /* halt DMA operation. 8bit */
-            control (s, 0);
+            control (pThis, 0);
             break;
 
         case 0xd1:              /* speaker on */
-            speaker (s, 1);
+            speaker (pThis, 1);
             break;
 
         case 0xd3:              /* speaker off */
-            speaker (s, 0);
+            speaker (pThis, 0);
             break;
 
@@ -652,34 +702,34 @@
             /* KQ6 (or maybe Sierras audblst.drv in general) resets
                the frequency between halt/continue */
-            continue_dma8 (s);
+            continue_dma8 (pThis);
             break;
 
         case 0xd5:              /* halt DMA operation. 16bit */
-            control (s, 0);
+            control (pThis, 0);
             break;
 
         case 0xd6:              /* continue DMA operation. 16bit */
-            control (s, 1);
+            control (pThis, 1);
             break;
 
         case 0xd9:              /* exit auto-init DMA after this block. 16bit */
-            s->dma_auto = 0;
+            pThis->dma_auto = 0;
             break;
 
         case 0xda:              /* exit auto-init DMA after this block. 8bit */
-            s->dma_auto = 0;
+            pThis->dma_auto = 0;
             break;
 
         case 0xe0:              /* DSP identification */
-            s->needed_bytes = 1;
+            pThis->needed_bytes = 1;
             break;
 
         case 0xe1:
-            dsp_out_data (s, s->ver & 0xff);
-            dsp_out_data (s, s->ver >> 8);
+            dsp_out_data (pThis, pThis->ver & 0xff);
+            dsp_out_data (pThis, pThis->ver >> 8);
             break;
 
         case 0xe2:
-            s->needed_bytes = 1;
+            pThis->needed_bytes = 1;
             goto warn;
 
@@ -688,10 +738,10 @@
                 int i;
                 for (i = sizeof (e3) - 1; i >= 0; --i)
-                    dsp_out_data (s, e3[i]);
+                    dsp_out_data (pThis, e3[i]);
             }
             break;
 
         case 0xe4:              /* write test reg */
-            s->needed_bytes = 1;
+            pThis->needed_bytes = 1;
             break;
 
@@ -701,28 +751,28 @@
 
         case 0xe8:              /* read test reg */
-            dsp_out_data (s, s->test_reg);
+            dsp_out_data (pThis, pThis->test_reg);
             break;
 
         case 0xf2:
         case 0xf3:
-            dsp_out_data (s, 0xaa);
-            s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
+            dsp_out_data (pThis, 0xaa);
+            pThis->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
 #ifndef VBOX
-            qemu_irq_raise (s->pic[s->irq]);
-#else
-            PDMDevHlpISASetIrq(s->pDevIns, s->irq, 1);
+            qemu_irq_raise (pThis->pic[pThis->irq]);
+#else
+            PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
 #endif
             break;
 
         case 0xf9:
-            s->needed_bytes = 1;
+            pThis->needed_bytes = 1;
             goto warn;
 
         case 0xfa:
-            dsp_out_data (s, 0);
+            dsp_out_data (pThis, 0);
             goto warn;
 
         case 0xfc:              /* FIXME */
-            dsp_out_data (s, 0);
+            dsp_out_data (pThis, 0);
             goto warn;
 
@@ -733,14 +783,14 @@
     }
 
-    if (!s->needed_bytes) {
+    if (!pThis->needed_bytes) {
         LogFlow(("\n"));
     }
 
  exit:
-    if (!s->needed_bytes) {
-        s->cmd = -1;
+    if (!pThis->needed_bytes) {
+        pThis->cmd = -1;
     }
     else {
-        s->cmd = cmd;
+        pThis->cmd = cmd;
     }
     return;
@@ -748,103 +798,103 @@
  warn:
     LogFlowFunc(("warning: command %#x,%d is not truly understood yet\n",
-           cmd, s->needed_bytes));
+           cmd, pThis->needed_bytes));
     goto exit;
 
 }
 
-static uint16_t dsp_get_lohi (SB16State *s)
-{
-    uint8_t hi = dsp_get_data (s);
-    uint8_t lo = dsp_get_data (s);
+static uint16_t dsp_get_lohi (PSB16STATE pThis)
+{
+    uint8_t hi = dsp_get_data (pThis);
+    uint8_t lo = dsp_get_data (pThis);
     return (hi << 8) | lo;
 }
 
-static uint16_t dsp_get_hilo (SB16State *s)
-{
-    uint8_t lo = dsp_get_data (s);
-    uint8_t hi = dsp_get_data (s);
+static uint16_t dsp_get_hilo (PSB16STATE pThis)
+{
+    uint8_t lo = dsp_get_data (pThis);
+    uint8_t hi = dsp_get_data (pThis);
     return (hi << 8) | lo;
 }
 
-static void complete (SB16State *s)
+static void complete (PSB16STATE pThis)
 {
     int d0, d1, d2;
     LogFlowFunc(("complete command %#x, in_index %d, needed_bytes %d\n",
-            s->cmd, s->in_index, s->needed_bytes));
-
-    if (s->cmd > 0xaf && s->cmd < 0xd0) {
-        d2 = dsp_get_data (s);
-        d1 = dsp_get_data (s);
-        d0 = dsp_get_data (s);
-
-        if (s->cmd & 8) {
+            pThis->cmd, pThis->in_index, pThis->needed_bytes));
+
+    if (pThis->cmd > 0xaf && pThis->cmd < 0xd0) {
+        d2 = dsp_get_data (pThis);
+        d1 = dsp_get_data (pThis);
+        d0 = dsp_get_data (pThis);
+
+        if (pThis->cmd & 8) {
             LogFlowFunc(("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
-                   s->cmd, d0, d1, d2));
+                   pThis->cmd, d0, d1, d2));
         }
         else {
             LogFlowFunc(("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
-                    s->cmd, d0, d1, d2));
-            dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
+                    pThis->cmd, d0, d1, d2));
+            dma_cmd (pThis, pThis->cmd, d0, d1 + (d2 << 8));
         }
     }
     else {
-        switch (s->cmd) {
+        switch (pThis->cmd) {
         case 0x04:
-            s->csp_mode = dsp_get_data (s);
-            s->csp_reg83r = 0;
-            s->csp_reg83w = 0;
-            LogFlowFunc(("CSP command 0x04: mode=%#x\n", s->csp_mode));
+            pThis->csp_mode = dsp_get_data (pThis);
+            pThis->csp_reg83r = 0;
+            pThis->csp_reg83w = 0;
+            LogFlowFunc(("CSP command 0x04: mode=%#x\n", pThis->csp_mode));
             break;
 
         case 0x05:
-            s->csp_param = dsp_get_data (s);
-            s->csp_value = dsp_get_data (s);
+            pThis->csp_param = dsp_get_data (pThis);
+            pThis->csp_value = dsp_get_data (pThis);
             LogFlowFunc(("CSP command 0x05: param=%#x value=%#x\n",
-                    s->csp_param,
-                    s->csp_value));
+                    pThis->csp_param,
+                    pThis->csp_value));
             break;
 
         case 0x0e:
-            d0 = dsp_get_data (s);
-            d1 = dsp_get_data (s);
+            d0 = dsp_get_data (pThis);
+            d1 = dsp_get_data (pThis);
             LogFlowFunc(("write CSP register %d <- %#x\n", d1, d0));
             if (d1 == 0x83) {
-                LogFlowFunc(("0x83[%d] <- %#x\n", s->csp_reg83r, d0));
-                s->csp_reg83[s->csp_reg83r % 4] = d0;
-                s->csp_reg83r += 1;
+                LogFlowFunc(("0x83[%d] <- %#x\n", pThis->csp_reg83r, d0));
+                pThis->csp_reg83[pThis->csp_reg83r % 4] = d0;
+                pThis->csp_reg83r += 1;
             }
             else {
-                s->csp_regs[d1] = d0;
+                pThis->csp_regs[d1] = d0;
             }
             break;
 
         case 0x0f:
-            d0 = dsp_get_data (s);
+            d0 = dsp_get_data (pThis);
             LogFlowFunc(("read CSP register %#x -> %#x, mode=%#x\n",
-                    d0, s->csp_regs[d0], s->csp_mode));
+                    d0, pThis->csp_regs[d0], pThis->csp_mode));
             if (d0 == 0x83) {
                 LogFlowFunc(("0x83[%d] -> %#x\n",
-                        s->csp_reg83w,
-                        s->csp_reg83[s->csp_reg83w % 4]));
-                dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
-                s->csp_reg83w += 1;
+                        pThis->csp_reg83w,
+                        pThis->csp_reg83[pThis->csp_reg83w % 4]));
+                dsp_out_data (pThis, pThis->csp_reg83[pThis->csp_reg83w % 4]);
+                pThis->csp_reg83w += 1;
             }
             else {
-                dsp_out_data (s, s->csp_regs[d0]);
+                dsp_out_data (pThis, pThis->csp_regs[d0]);
             }
             break;
 
         case 0x10:
-            d0 = dsp_get_data (s);
+            d0 = dsp_get_data (pThis);
             LogFlowFunc(("cmd 0x10 d0=%#x\n", d0));
             break;
 
         case 0x14:
-            dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
+            dma_cmd8 (pThis, 0, dsp_get_lohi (pThis) + 1);
             break;
 
         case 0x40:
-            s->time_const = dsp_get_data (s);
-            LogFlowFunc(("set time const %d\n", s->time_const));
+            pThis->time_const = dsp_get_data (pThis);
+            LogFlowFunc(("set time const %d\n", pThis->time_const));
             break;
 
@@ -854,11 +904,11 @@
 #endif
         case 0x41:
-            s->freq = dsp_get_hilo (s);
-            LogFlowFunc(("set freq %d\n", s->freq));
+            pThis->freq = dsp_get_hilo (pThis);
+            LogFlowFunc(("set freq %d\n", pThis->freq));
             break;
 
         case 0x48:
-            s->block_size = dsp_get_lohi (s) + 1;
-            LogFlowFunc(("set dma block len %d\n", s->block_size));
+            pThis->block_size = dsp_get_lohi (pThis) + 1;
+            LogFlowFunc(("set dma block len %d\n", pThis->block_size));
             break;
 
@@ -875,16 +925,16 @@
                 uint64_t ticks;
 
-                freq = s->freq > 0 ? s->freq : 11025;
-                samples = dsp_get_lohi (s) + 1;
-                bytes = samples << s->fmt_stereo << ((s->fmt_bits == 16) ? 1 : 0);
+                freq = pThis->freq > 0 ? pThis->freq : 11025;
+                samples = dsp_get_lohi (pThis) + 1;
+                bytes = samples << pThis->fmt_stereo << ((pThis->fmt_bits == 16) ? 1 : 0);
 #ifndef VBOX
                 ticks = (bytes * ticks_per_sec) / freq;
                 if (ticks < ticks_per_sec / 1024) {
-                    qemu_irq_raise (s->pic[s->irq]);
+                    qemu_irq_raise (pThis->pic[pThis->irq]);
                 }
                 else {
-                    if (s->aux_ts) {
+                    if (pThis->aux_ts) {
                         qemu_mod_timer (
-                            s->aux_ts,
+                            pThis->aux_ts,
                             qemu_get_clock (vm_clock) + ticks
                             );
@@ -893,9 +943,9 @@
                 LogFlowFunc(("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks));
 #else  /* VBOX */
-                ticks = (bytes * TMTimerGetFreq(s->pTimer)) / freq;
-                if (ticks < TMTimerGetFreq(s->pTimer) / 1024)
-                    PDMDevHlpISASetIrq(s->pDevIns, s->irq, 1);
+                ticks = (bytes * TMTimerGetFreq(pThis->pTimer)) / freq;
+                if (ticks < TMTimerGetFreq(pThis->pTimer) / 1024)
+                    PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
                 else
-                    TMTimerSet(s->pTimer, TMTimerGet(s->pTimer) + ticks);
+                    TMTimerSet(pThis->pTimer, TMTimerGet(pThis->pTimer) + ticks);
                 LogFlowFunc(("mix silence %d %d % %RU64\n", samples, bytes, ticks));
 #endif /* VBOX */
@@ -904,37 +954,37 @@
 
         case 0xe0:
-            d0 = dsp_get_data (s);
-            s->out_data_len = 0;
+            d0 = dsp_get_data (pThis);
+            pThis->out_data_len = 0;
             LogFlowFunc(("E0 data = %#x\n", d0));
-            dsp_out_data (s, ~d0);
+            dsp_out_data (pThis, ~d0);
             break;
 
         case 0xe2:
-            d0 = dsp_get_data (s);
+            d0 = dsp_get_data (pThis);
             LogFlow(("SB16:E2 = %#x\n", d0));
             break;
 
         case 0xe4:
-            s->test_reg = dsp_get_data (s);
+            pThis->test_reg = dsp_get_data (pThis);
             break;
 
         case 0xf9:
-            d0 = dsp_get_data (s);
+            d0 = dsp_get_data (pThis);
             LogFlowFunc(("command 0xf9 with %#x\n", d0));
             switch (d0) {
             case 0x0e:
-                dsp_out_data (s, 0xff);
+                dsp_out_data (pThis, 0xff);
                 break;
 
             case 0x0f:
-                dsp_out_data (s, 0x07);
+                dsp_out_data (pThis, 0x07);
                 break;
 
             case 0x37:
-                dsp_out_data (s, 0x38);
+                dsp_out_data (pThis, 0x38);
                 break;
 
             default:
-                dsp_out_data (s, 0x00);
+                dsp_out_data (pThis, 0x00);
                 break;
             }
@@ -942,5 +992,5 @@
 
         default:
-            LogFlowFunc(("complete: unrecognized command %#x\n", s->cmd));
+            LogFlowFunc(("complete: unrecognized command %#x\n", pThis->cmd));
             return;
         }
@@ -948,35 +998,35 @@
 
     LogFlow(("\n"));
-    s->cmd = -1;
+    pThis->cmd = -1;
     return;
 }
 
-static void legacy_reset (SB16State *s)
-{
-    s->freq = 11025;
-    s->fmt_signed = 0;
-    s->fmt_bits = 8;
-    s->fmt_stereo = 0;
+static void legacy_reset (PSB16STATE pThis)
+{
+    pThis->freq = 11025;
+    pThis->fmt_signed = 0;
+    pThis->fmt_bits = 8;
+    pThis->fmt_stereo = 0;
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     PDMAUDIOSTREAMCFG as;
-    as.uHz           = s->freq;
+    as.uHz           = pThis->freq;
     as.cChannels     = 1;
     as.enmFormat     = AUD_FMT_U8;
     as.enmEndianness = PDMAUDIOHOSTENDIANESS;
 
-    int rc = s->pDrv->pfnOpenOut(s->pDrv, "sb16.out", &as, &s->pGstStrmOut);
+    int rc = pThis->pDrv->pfnOpenOut(pThis->pDrv, "sb16.out", &as, &pThis->pGstStrmOut);
     AssertRC(rc);
 #else
     audsettings_t as;
-    as.freq = s->freq;
+    as.freq = pThis->freq;
     as.nchannels = 1;
     as.fmt = AUD_FMT_U8;
     as.endianness = 0;
-    s->voice = AUD_open_out (
-        &s->card,
-        s->voice,
+    pThis->voice = AUD_open_out (
+        &pThis->card,
+        pThis->voice,
         "sb16",
-        s,
+        pThis,
         sb16AudioCallback,
         &as
@@ -985,45 +1035,45 @@
 
     /* Not sure about that... */
-    /* AUD_set_active_out (s->voice, 1); */
-}
-
-static void reset (SB16State *s)
+    /* AUD_set_active_out (pThis->voice, 1); */
+}
+
+static void reset (PSB16STATE pThis)
 {
 #ifndef VBOX
-    qemu_irq_lower (s->pic[s->irq]);
-    if (s->dma_auto) {
-        qemu_irq_raise (s->pic[s->irq]);
-        qemu_irq_lower (s->pic[s->irq]);
+    qemu_irq_lower (pThis->pic[pThis->irq]);
+    if (pThis->dma_auto) {
+        qemu_irq_raise (pThis->pic[pThis->irq]);
+        qemu_irq_lower (pThis->pic[pThis->irq]);
     }
 #else  /* VBOX */
-    PDMDevHlpISASetIrq(s->pDevIns, s->irq, 0);
-    if (s->dma_auto) {
-        PDMDevHlpISASetIrq(s->pDevIns, s->irq, 1);
-        PDMDevHlpISASetIrq(s->pDevIns, s->irq, 0);
+    PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
+    if (pThis->dma_auto) {
+        PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
+        PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
     }
 #endif /* VBOX */
 
-    s->mixer_regs[0x82] = 0;
-    s->dma_auto = 0;
-    s->in_index = 0;
-    s->out_data_len = 0;
-    s->left_till_irq = 0;
-    s->needed_bytes = 0;
-    s->block_size = -1;
-    s->nzero = 0;
-    s->highspeed = 0;
-    s->v2x6 = 0;
-    s->cmd = -1;
-
-    dsp_out_data(s, 0xaa);
-    speaker (s, 0);
-    control (s, 0);
-    legacy_reset (s);
+    pThis->mixer_regs[0x82] = 0;
+    pThis->dma_auto = 0;
+    pThis->in_index = 0;
+    pThis->out_data_len = 0;
+    pThis->left_till_irq = 0;
+    pThis->needed_bytes = 0;
+    pThis->block_size = -1;
+    pThis->nzero = 0;
+    pThis->highspeed = 0;
+    pThis->v2x6 = 0;
+    pThis->cmd = -1;
+
+    dsp_out_data(pThis, 0xaa);
+    speaker (pThis, 0);
+    control (pThis, 0);
+    legacy_reset (pThis);
 }
 
 static IO_WRITE_PROTO (dsp_write)
 {
-    SB16State *s = (SB16State*)opaque;
-    int iport = nport - s->port;
+    PSB16STATE pThis = (SB16STATE*)opaque;
+    int iport = nport - pThis->port;
 
     LogFlowFunc(("write %#x <- %#x\n", nport, val));
@@ -1032,42 +1082,42 @@
         switch (val) {
         case 0x00:
-            if (s->v2x6 == 1) {
-                if (0 && s->highspeed) {
-                    s->highspeed = 0;
+            if (pThis->v2x6 == 1) {
+                if (0 && pThis->highspeed) {
+                    pThis->highspeed = 0;
 #ifndef VBOX
-                    qemu_irq_lower (s->pic[s->irq]);
-#else
-                    PDMDevHlpISASetIrq(s->pDevIns, s->irq, 0);
-#endif
-                    control (s, 0);
+                    qemu_irq_lower (pThis->pic[pThis->irq]);
+#else
+                    PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
+#endif
+                    control (pThis, 0);
                 }
                 else {
-                    reset (s);
+                    reset (pThis);
                 }
             }
-            s->v2x6 = 0;
+            pThis->v2x6 = 0;
             break;
 
         case 0x01:
         case 0x03:              /* FreeBSD kludge */
-            s->v2x6 = 1;
+            pThis->v2x6 = 1;
             break;
 
         case 0xc6:
-            s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
+            pThis->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
             break;
 
         case 0xb8:              /* Panic */
-            reset (s);
+            reset (pThis);
             break;
 
         case 0x39:
-            dsp_out_data (s, 0x38);
-            reset (s);
-            s->v2x6 = 0x39;
+            dsp_out_data (pThis, 0x38);
+            reset (pThis);
+            pThis->v2x6 = 0x39;
             break;
 
         default:
-            s->v2x6 = val;
+            pThis->v2x6 = val;
             break;
         }
@@ -1075,26 +1125,26 @@
 
     case 0x0c:                  /* write data or command | write status */
-/*         if (s->highspeed) */
+/*         if (pThis->highspeed) */
 /*             break; */
 
-        if (0 == s->needed_bytes) {
-            command (s, val);
+        if (0 == pThis->needed_bytes) {
+            command (pThis, val);
 #if 0
-            if (0 == s->needed_bytes) {
-                log_dsp (s);
+            if (0 == pThis->needed_bytes) {
+                log_dsp (pThis);
             }
 #endif
         }
         else {
-            if (s->in_index == sizeof (s->in2_data)) {
+            if (pThis->in_index == sizeof (pThis->in2_data)) {
                 LogFlowFunc(("in data overrun\n"));
             }
             else {
-                s->in2_data[s->in_index++] = val;
-                if (s->in_index == s->needed_bytes) {
-                    s->needed_bytes = 0;
-                    complete (s);
+                pThis->in2_data[pThis->in_index++] = val;
+                if (pThis->in_index == pThis->needed_bytes) {
+                    pThis->needed_bytes = 0;
+                    complete (pThis);
 #if 0
-                    log_dsp (s);
+                    log_dsp (pThis);
 #endif
                 }
@@ -1115,8 +1165,8 @@
 static IO_READ_PROTO (dsp_read)
 {
-    SB16State *s = (SB16State*)opaque;
+    PSB16STATE pThis = (SB16STATE*)opaque;
     int iport, retval, ack = 0;
 
-    iport = nport - s->port;
+    iport = nport - pThis->port;
 #ifdef VBOX
     /** @todo reject non-byte access?
@@ -1130,14 +1180,14 @@
 
     case 0x0a:                  /* read data */
-        if (s->out_data_len) {
-            retval = s->out_data[--s->out_data_len];
-            s->last_read_byte = retval;
+        if (pThis->out_data_len) {
+            retval = pThis->out_data[--pThis->out_data_len];
+            pThis->last_read_byte = retval;
         }
         else {
-            if (s->cmd != -1) {
+            if (pThis->cmd != -1) {
                 LogFlowFunc(("empty output buffer for command %#x\n",
-                       s->cmd));
+                       pThis->cmd));
             }
-            retval = s->last_read_byte;
+            retval = pThis->last_read_byte;
             /* goto error; */
         }
@@ -1145,5 +1195,5 @@
 
     case 0x0c:                  /* 0 can write */
-        retval = s->can_write ? 0 : 0x80;
+        retval = pThis->can_write ? 0 : 0x80;
         break;
 
@@ -1154,12 +1204,12 @@
 
     case 0x0e:                  /* data available status | irq 8 ack */
-        retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
-        if (s->mixer_regs[0x82] & 1) {
+        retval = (!pThis->out_data_len || pThis->highspeed) ? 0 : 0x80;
+        if (pThis->mixer_regs[0x82] & 1) {
             ack = 1;
-            s->mixer_regs[0x82] &= ~1;
+            pThis->mixer_regs[0x82] &= ~1;
 #ifndef VBOX
-            qemu_irq_lower (s->pic[s->irq]);
-#else
-            PDMDevHlpISASetIrq(s->pDevIns, s->irq, 0);
+            qemu_irq_lower (pThis->pic[pThis->irq]);
+#else
+            PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
 #endif
         }
@@ -1168,11 +1218,11 @@
     case 0x0f:                  /* irq 16 ack */
         retval = 0xff;
-        if (s->mixer_regs[0x82] & 2) {
+        if (pThis->mixer_regs[0x82] & 2) {
             ack = 1;
-            s->mixer_regs[0x82] &= ~2;
+            pThis->mixer_regs[0x82] &= ~2;
 #ifndef VBOX
-            qemu_irq_lower (s->pic[s->irq]);
-#else
-            PDMDevHlpISASetIrq(s->pDevIns, s->irq, 0);
+            qemu_irq_lower (pThis->pic[pThis->irq]);
+#else
+            PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
 #endif
         }
@@ -1203,31 +1253,31 @@
 }
 
-static void reset_mixer (SB16State *s)
+static void reset_mixer (PSB16STATE pThis)
 {
     int i;
 
-    memset (s->mixer_regs, 0xff, 0x7f);
-    memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
-
-    s->mixer_regs[0x02] = 4;    /* master volume 3bits */
-    s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
-    s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
-    s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
+    memset (pThis->mixer_regs, 0xff, 0x7f);
+    memset (pThis->mixer_regs + 0x83, 0xff, sizeof (pThis->mixer_regs) - 0x83);
+
+    pThis->mixer_regs[0x02] = 4;    /* master volume 3bits */
+    pThis->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
+    pThis->mixer_regs[0x08] = 0;    /* CD volume 3bits */
+    pThis->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
 
     /* d5=input filt, d3=lowpass filt, d1,d2=input source */
-    s->mixer_regs[0x0c] = 0;
+    pThis->mixer_regs[0x0c] = 0;
 
     /* d5=output filt, d1=stereo switch */
-    s->mixer_regs[0x0e] = 0;
+    pThis->mixer_regs[0x0e] = 0;
 
     /* voice volume L d5,d7, R d1,d3 */
-    s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
+    pThis->mixer_regs[0x04] = (4 << 5) | (4 << 1);
     /* master ... */
-    s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
+    pThis->mixer_regs[0x22] = (4 << 5) | (4 << 1);
     /* MIDI ... */
-    s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
+    pThis->mixer_regs[0x26] = (4 << 5) | (4 << 1);
 
     for (i = 0x30; i < 0x48; i++) {
-        s->mixer_regs[i] = 0x20;
+        pThis->mixer_regs[i] = 0x20;
     }
 }
@@ -1235,7 +1285,7 @@
 static IO_WRITE_PROTO(mixer_write_indexb)
 {
-    SB16State *s = (SB16State*)opaque;
+    PSB16STATE pThis = (SB16STATE*)opaque;
     (void) nport;
-    s->mixer_nreg = val;
+    pThis->mixer_nreg = val;
 
 #ifdef VBOX
@@ -1263,68 +1313,68 @@
 static IO_WRITE_PROTO(mixer_write_datab)
 {
-    SB16State   *s = (SB16State*)opaque;
-    bool        update_master = false;
-    bool        update_voice  = false;
+    PSB16STATE  pThis = (PSB16STATE)opaque;
+    bool        fUpdateMaster = false;
+    bool        fUpdateStream = false;
 
     (void) nport;
-    LogFlowFunc(("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val));
-
-    switch (s->mixer_nreg) {
-    case 0x00:
-        reset_mixer(s);
-        /* And update the actual volume, too. */
-        update_master = true;
-        update_voice  = true;
-        break;
-
-    case 0x04:
-        /* Translate from old style voice volume (L/R). */
-        s->mixer_regs[0x32] = val & 0xff;
-        s->mixer_regs[0x33] = val << 4;
-        update_voice = true;
-        break;
-
-    case 0x22:
-        /* Translate from old style master volume (L/R). */
-        s->mixer_regs[0x30] = val & 0xff;
-        s->mixer_regs[0x31] = val << 4;
-        update_master = true;
-        break;
-
-    case 0x30:
-        /* Translate to old style master volume (L). */
-        s->mixer_regs[0x22] = (s->mixer_regs[0x22] & 0x0f) | val;
-        update_master = true;
-        break;
-
-    case 0x31:
-        /* Translate to old style master volume (R). */
-        s->mixer_regs[0x22] = (s->mixer_regs[0x22] & 0xf0) | (val >> 4);
-        update_master = true;
-        break;
-
-    case 0x32:
-        /* Translate to old style voice volume (L). */
-        s->mixer_regs[0x04] = (s->mixer_regs[0x04] & 0x0f) | val;
-        update_voice = true;
-        break;
-
-    case 0x33:
-        /* Translate to old style voice volume (R). */
-        s->mixer_regs[0x04] = (s->mixer_regs[0x04] & 0xf0) | (val >> 4);
-        update_voice = true;
-        break;
-
-    case 0x80:
+    LogFlowFunc(("mixer_write [%#x] <- %#x\n", pThis->mixer_nreg, val));
+
+    switch (pThis->mixer_nreg)
+    {
+        case 0x00:
+            reset_mixer(pThis);
+            /* And update the actual volume, too. */
+            fUpdateMaster = true;
+            fUpdateStream  = true;
+            break;
+
+        case 0x04:
+            /* Translate from old style stream volume (L/R). */
+            pThis->mixer_regs[0x32] = val & 0xff;
+            pThis->mixer_regs[0x33] = val << 4;
+            fUpdateStream = true;
+            break;
+
+        case 0x22:
+            /* Translate from old style master volume (L/R). */
+            pThis->mixer_regs[0x30] = val & 0xff;
+            pThis->mixer_regs[0x31] = val << 4;
+            fUpdateMaster = true;
+            break;
+
+        case 0x30:
+            /* Translate to old style master volume (L). */
+            pThis->mixer_regs[0x22] = (pThis->mixer_regs[0x22] & 0x0f) | val;
+            fUpdateMaster = true;
+            break;
+
+        case 0x31:
+            /* Translate to old style master volume (R). */
+            pThis->mixer_regs[0x22] = (pThis->mixer_regs[0x22] & 0xf0) | (val >> 4);
+            fUpdateMaster = true;
+            break;
+
+        case 0x32:
+            /* Translate to old style stream volume (L). */
+            pThis->mixer_regs[0x04] = (pThis->mixer_regs[0x04] & 0x0f) | val;
+            fUpdateStream = true;
+            break;
+
+        case 0x33:
+            /* Translate to old style stream volume (R). */
+            pThis->mixer_regs[0x04] = (pThis->mixer_regs[0x04] & 0xf0) | (val >> 4);
+            fUpdateStream = true;
+            break;
+
+        case 0x80:
         {
-            int irq = irq_of_magic (val);
+            int irq = irq_of_magic(val);
             LogFlowFunc(("setting irq to %d (val=%#x)\n", irq, val));
-            if (irq > 0) {
-                s->irq = irq;
-            }
-        }
-        break;
-
-    case 0x81:
+            if (irq > 0)
+                pThis->irq = irq;
+            break;
+        }
+
+        case 0x81:
         {
             int dma, hdma;
@@ -1332,56 +1382,54 @@
             dma = lsbindex (val & 0xf);
             hdma = lsbindex (val & 0xf0);
-            if (dma != s->dma || hdma != s->hdma) {
-                LogFlow((
-                    "SB16: attempt to change DMA "
-                    "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
-                    dma, s->dma, hdma, s->hdma, val));
-            }
+            if (dma != pThis->dma || hdma != pThis->hdma)
+                LogFlow(("SB16: attempt to change DMA 8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
+                         dma, pThis->dma, hdma, pThis->hdma, val));
 #if 0
-            s->dma = dma;
-            s->hdma = hdma;
-#endif
-        }
-        break;
-
-    case 0x82:
-        LogFlowFunc(("attempt to write into IRQ status register (val=%#x)\n",
-               val));
+            pThis->dma = dma;
+            pThis->hdma = hdma;
+#endif
+            break;
+        }
+
+        case 0x82:
+            LogFlowFunc(("attempt to write into IRQ status register (val=%#x)\n", val));
 #ifdef VBOX
-        return VINF_SUCCESS;
-#endif
-
-    default:
-        if (s->mixer_nreg >= 0x80) {
-            LogFlowFunc(("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val));
-        }
-        break;
-    }
-
-    s->mixer_regs[s->mixer_nreg] = val;
+            return VINF_SUCCESS;
+#endif
+
+        default:
+            if (pThis->mixer_nreg >= 0x80)
+                LogFlowFunc(("attempt to write mixer[%#x] <- %#x\n", pThis->mixer_nreg, val));
+            break;
+    }
+
+    pThis->mixer_regs[pThis->mixer_nreg] = val;
 
 #ifdef VBOX
     /* Update the master (mixer) volume. */
-    if (update_master)
+    if (fUpdateMaster)
     {
-        int     mute = 0;
-        uint8_t lvol = s->mixer_regs[0x30];
-        uint8_t rvol = s->mixer_regs[0x31];
+        int     mute = 0; /** @todo Handle (un)muting. */
+        uint8_t lvol = pThis->mixer_regs[0x30];
+        uint8_t rvol = pThis->mixer_regs[0x31];
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-        s->pDrv->pfnSetVolume(s->pDrv, RT_BOOL(mute), lvol, rvol);
+        PDMAUDIOVOLUME vol = { RT_BOOL(mute), lvol, rvol };
+        audioMixerSetMasterVolume(pThis->pMixer, &vol);
 #else
         AUD_set_volume(AUD_MIXER_VOLUME, &mute, &lvol, &rvol);
 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     }
-    /* Update the voice (PCM) volume. */
-    if (update_voice)
+
+    /* Update the stream (PCM) volume. */
+    if (fUpdateStream)
     {
-        int     mute = 0;
-        uint8_t lvol = s->mixer_regs[0x32];
-        uint8_t rvol = s->mixer_regs[0x33];
+        int     mute = 0; /** @todo Handle (un)muting. */
+        uint8_t lvol = pThis->mixer_regs[0x32];
+        uint8_t rvol = pThis->mixer_regs[0x33];
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-        s->pDrv->pfnSetVolume(s->pDrv, RT_BOOL(mute), lvol, rvol);
+        PDMAUDIOVOLUME vol = { RT_BOOL(mute), lvol, rvol };
+        audioMixerSetSinkVolume(pThis->pSinkOutput, &vol);
 #else
         AUD_set_volume(AUD_MIXER_PCM, &mute, &lvol, &rvol);
@@ -1401,6 +1449,6 @@
     mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
 #else  /* VBOX */
-    SB16State *s = (SB16State*)opaque;
-    int iport = nport - s->port;
+    PSB16STATE pThis = (SB16STATE*)opaque;
+    int iport = nport - pThis->port;
     switch (cb)
     {
@@ -1430,25 +1478,25 @@
 static IO_READ_PROTO(mixer_read)
 {
-    SB16State *s = (SB16State*)opaque;
+    PSB16STATE pThis = (SB16STATE*)opaque;
 
     (void) nport;
 #ifndef DEBUG_SB16_MOST
-    if (s->mixer_nreg != 0x82) {
+    if (pThis->mixer_nreg != 0x82) {
         LogFlowFunc(("mixer_read[%#x] -> %#x\n",
-                s->mixer_nreg, s->mixer_regs[s->mixer_nreg]));
+                pThis->mixer_nreg, pThis->mixer_regs[pThis->mixer_nreg]));
     }
 #else
     LogFlowFunc(("mixer_read[%#x] -> %#x\n",
-            s->mixer_nreg, s->mixer_regs[s->mixer_nreg]));
+            pThis->mixer_nreg, pThis->mixer_regs[pThis->mixer_nreg]));
 #endif
 #ifndef VBOX
-    return s->mixer_regs[s->mixer_nreg];
-#else
-    *pu32 = s->mixer_regs[s->mixer_nreg];
+    return pThis->mixer_regs[pThis->mixer_nreg];
+#else
+    *pu32 = pThis->mixer_regs[pThis->mixer_nreg];
     return VINF_SUCCESS;
 #endif
 }
 
-static int write_audio (SB16State *s, int nchan, int dma_pos,
+static int write_audio (PSB16STATE pThis, int nchan, int dma_pos,
                         int dma_len, int len)
 {
@@ -1477,5 +1525,5 @@
         copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
 #else
-        int rc = PDMDevHlpDMAReadMemory(s->pDevIns, nchan, tmpbuf, dma_pos,
+        int rc = PDMDevHlpDMAReadMemory(pThis->pDevIns, nchan, tmpbuf, dma_pos,
                                         to_copy, &copied);
         AssertMsgRC (rc, ("DMAReadMemory -> %Rrc\n", rc));
@@ -1483,9 +1531,9 @@
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-        rc = s->pDrv->pfnWrite(s->pDrv, s->pGstStrmOut, tmpbuf, to_copy, &copied);
+        rc = pThis->pDrv->pfnWrite(pThis->pDrv, pThis->pGstStrmOut, tmpbuf, to_copy, &copied);
         if (RT_FAILURE(rc))
             break;
 #else
-        copied = AUD_write (s->voice, tmpbuf, copied);
+        copied = AUD_write (pThis->voice, tmpbuf, copied);
 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
 
@@ -1507,23 +1555,23 @@
 #endif
 {
-    SB16State *s = (SB16State*)opaque;
+    PSB16STATE pThis = (SB16STATE*)opaque;
     int till, copy, written, free;
 
-    if (s->block_size <= 0) {
+    if (pThis->block_size <= 0) {
         LogFlowFunc(("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
-               s->block_size, nchan, dma_pos, dma_len));
+               pThis->block_size, nchan, dma_pos, dma_len));
         return dma_pos;
     }
 
-    if (s->left_till_irq < 0) {
-        s->left_till_irq = s->block_size;
+    if (pThis->left_till_irq < 0) {
+        pThis->left_till_irq = pThis->block_size;
     }
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-    if (s->pGstStrmOut) {
-#else
-    if (s->voice) {
+    if (pThis->pGstStrmOut) {
+#else
+    if (pThis->voice) {
 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
-        free = s->audio_free & ~s->align;
+        free = pThis->audio_free & ~pThis->align;
         if ((free <= 0) || !dma_len) {
             return dma_pos;
@@ -1535,5 +1583,5 @@
 
     copy = free;
-    till = s->left_till_irq;
+    till = pThis->left_till_irq;
 
 #ifdef DEBUG_SB16_MOST
@@ -1543,8 +1591,8 @@
 
     if (copy >= till) {
-        if (0 == s->dma_auto) {
+        if (0 == pThis->dma_auto) {
             copy = till;
         } else {
-            if( copy >= till + s->block_size ) {
+            if( copy >= till + pThis->block_size ) {
                 copy = till;    /* Make sure we won't skip IRQs. */
             }
@@ -1552,18 +1600,18 @@
     }
 
-    written = write_audio (s, nchan, dma_pos, dma_len, copy);
+    written = write_audio (pThis, nchan, dma_pos, dma_len, copy);
     dma_pos = (dma_pos + written) % dma_len;
-    s->left_till_irq -= written;
-
-    if (s->left_till_irq <= 0) {
-        s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
+    pThis->left_till_irq -= written;
+
+    if (pThis->left_till_irq <= 0) {
+        pThis->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
 #ifndef VBOX
-        qemu_irq_raise (s->pic[s->irq]);
-#else
-        PDMDevHlpISASetIrq(s->pDevIns, s->irq, 1);
-#endif
-        if (0 == s->dma_auto) {
-            control (s, 0);
-            speaker (s, 0);
+        qemu_irq_raise (pThis->pic[pThis->irq]);
+#else
+        PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
+#endif
+        if (0 == pThis->dma_auto) {
+            control (pThis, 0);
+            speaker (pThis, 0);
         }
     }
@@ -1571,10 +1619,10 @@
 #ifdef DEBUG_SB16_MOST
     LogFlowFunc(("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
-            dma_pos, free, dma_len, s->left_till_irq, copy, written,
-            s->block_size));
-#endif
-
-    while (s->left_till_irq <= 0) {
-        s->left_till_irq = s->block_size + s->left_till_irq;
+            dma_pos, free, dma_len, pThis->left_till_irq, copy, written,
+            pThis->block_size));
+#endif
+
+    while (pThis->left_till_irq <= 0) {
+        pThis->left_till_irq = pThis->block_size + pThis->left_till_irq;
     }
 
@@ -1588,5 +1636,5 @@
 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
 {
-    SB16State *pState = (SB16State*)pvContext;
+    SB16STATE *pState = (SB16STATE*)pvContext;
     AssertPtrReturnVoid(pState);
     pState->audio_free = cbFree;
@@ -1600,56 +1648,56 @@
 {
 #ifndef VBOX
-    SB16State *s = opaque;
-#else
-    SB16State *s = (SB16State *)opaque;
-#endif
-
-    qemu_put_be32 (f, s->irq);
-    qemu_put_be32 (f, s->dma);
-    qemu_put_be32 (f, s->hdma);
-    qemu_put_be32 (f, s->port);
-    qemu_put_be32 (f, s->ver);
-    qemu_put_be32 (f, s->in_index);
-    qemu_put_be32 (f, s->out_data_len);
-    qemu_put_be32 (f, s->fmt_stereo);
-    qemu_put_be32 (f, s->fmt_signed);
-    qemu_put_be32 (f, s->fmt_bits);
-    qemu_put_be32s (f, &s->fmt);
-    qemu_put_be32 (f, s->dma_auto);
-    qemu_put_be32 (f, s->block_size);
-    qemu_put_be32 (f, s->fifo);
-    qemu_put_be32 (f, s->freq);
-    qemu_put_be32 (f, s->time_const);
-    qemu_put_be32 (f, s->speaker);
-    qemu_put_be32 (f, s->needed_bytes);
-    qemu_put_be32 (f, s->cmd);
-    qemu_put_be32 (f, s->use_hdma);
-    qemu_put_be32 (f, s->highspeed);
-    qemu_put_be32 (f, s->can_write);
-    qemu_put_be32 (f, s->v2x6);
-
-    qemu_put_8s (f, &s->csp_param);
-    qemu_put_8s (f, &s->csp_value);
-    qemu_put_8s (f, &s->csp_mode);
-    qemu_put_8s (f, &s->csp_param);
-    qemu_put_buffer (f, s->csp_regs, 256);
-    qemu_put_8s (f, &s->csp_index);
-    qemu_put_buffer (f, s->csp_reg83, 4);
-    qemu_put_be32 (f, s->csp_reg83r);
-    qemu_put_be32 (f, s->csp_reg83w);
-
-    qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
-    qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
-    qemu_put_8s (f, &s->test_reg);
-    qemu_put_8s (f, &s->last_read_byte);
-
-    qemu_put_be32 (f, s->nzero);
-    qemu_put_be32 (f, s->left_till_irq);
-    qemu_put_be32 (f, s->dma_running);
-    qemu_put_be32 (f, s->bytes_per_second);
-    qemu_put_be32 (f, s->align);
-
-    qemu_put_be32 (f, s->mixer_nreg);
-    qemu_put_buffer (f, s->mixer_regs, 256);
+    PSB16STATE pThis = opaque;
+#else
+    PSB16STATE pThis = (SB16STATE *)opaque;
+#endif
+
+    qemu_put_be32 (f, pThis->irq);
+    qemu_put_be32 (f, pThis->dma);
+    qemu_put_be32 (f, pThis->hdma);
+    qemu_put_be32 (f, pThis->port);
+    qemu_put_be32 (f, pThis->ver);
+    qemu_put_be32 (f, pThis->in_index);
+    qemu_put_be32 (f, pThis->out_data_len);
+    qemu_put_be32 (f, pThis->fmt_stereo);
+    qemu_put_be32 (f, pThis->fmt_signed);
+    qemu_put_be32 (f, pThis->fmt_bits);
+    qemu_put_be32s (f, &pThis->fmt);
+    qemu_put_be32 (f, pThis->dma_auto);
+    qemu_put_be32 (f, pThis->block_size);
+    qemu_put_be32 (f, pThis->fifo);
+    qemu_put_be32 (f, pThis->freq);
+    qemu_put_be32 (f, pThis->time_const);
+    qemu_put_be32 (f, pThis->speaker);
+    qemu_put_be32 (f, pThis->needed_bytes);
+    qemu_put_be32 (f, pThis->cmd);
+    qemu_put_be32 (f, pThis->use_hdma);
+    qemu_put_be32 (f, pThis->highspeed);
+    qemu_put_be32 (f, pThis->can_write);
+    qemu_put_be32 (f, pThis->v2x6);
+
+    qemu_put_8s (f, &pThis->csp_param);
+    qemu_put_8s (f, &pThis->csp_value);
+    qemu_put_8s (f, &pThis->csp_mode);
+    qemu_put_8s (f, &pThis->csp_param);
+    qemu_put_buffer (f, pThis->csp_regs, 256);
+    qemu_put_8s (f, &pThis->csp_index);
+    qemu_put_buffer (f, pThis->csp_reg83, 4);
+    qemu_put_be32 (f, pThis->csp_reg83r);
+    qemu_put_be32 (f, pThis->csp_reg83w);
+
+    qemu_put_buffer (f, pThis->in2_data, sizeof (pThis->in2_data));
+    qemu_put_buffer (f, pThis->out_data, sizeof (pThis->out_data));
+    qemu_put_8s (f, &pThis->test_reg);
+    qemu_put_8s (f, &pThis->last_read_byte);
+
+    qemu_put_be32 (f, pThis->nzero);
+    qemu_put_be32 (f, pThis->left_till_irq);
+    qemu_put_be32 (f, pThis->dma_running);
+    qemu_put_be32 (f, pThis->bytes_per_second);
+    qemu_put_be32 (f, pThis->align);
+
+    qemu_put_be32 (f, pThis->mixer_nreg);
+    qemu_put_buffer (f, pThis->mixer_regs, 256);
 }
 
@@ -1657,5 +1705,5 @@
 {
 #ifndef VBOX
-    SB16State *s = opaque;
+    PSB16STATE pThis = opaque;
 
     if (version_id != 1) {
@@ -1663,92 +1711,92 @@
     }
 #else
-    SB16State *s = (SB16State *)opaque;
-#endif
-
-    s->irq=qemu_get_be32 (f);
-    s->dma=qemu_get_be32 (f);
-    s->hdma=qemu_get_be32 (f);
-    s->port=qemu_get_be32 (f);
-    s->ver=qemu_get_be32 (f);
-    s->in_index=qemu_get_be32 (f);
-    s->out_data_len=qemu_get_be32 (f);
-    s->fmt_stereo=qemu_get_be32 (f);
-    s->fmt_signed=qemu_get_be32 (f);
-    s->fmt_bits=qemu_get_be32 (f);
-    qemu_get_be32s (f, (uint32_t*)&s->fmt);
-    s->dma_auto=qemu_get_be32 (f);
-    s->block_size=qemu_get_be32 (f);
-    s->fifo=qemu_get_be32 (f);
-    s->freq=qemu_get_be32 (f);
-    s->time_const=qemu_get_be32 (f);
-    s->speaker=qemu_get_be32 (f);
-    s->needed_bytes=qemu_get_be32 (f);
-    s->cmd=qemu_get_be32 (f);
-    s->use_hdma=qemu_get_be32 (f);
-    s->highspeed=qemu_get_be32 (f);
-    s->can_write=qemu_get_be32 (f);
-    s->v2x6=qemu_get_be32 (f);
-
-    qemu_get_8s (f, &s->csp_param);
-    qemu_get_8s (f, &s->csp_value);
-    qemu_get_8s (f, &s->csp_mode);
-    qemu_get_8s (f, &s->csp_param);
-    qemu_get_buffer (f, s->csp_regs, 256);
-    qemu_get_8s (f, &s->csp_index);
-    qemu_get_buffer (f, s->csp_reg83, 4);
-    s->csp_reg83r=qemu_get_be32 (f);
-    s->csp_reg83w=qemu_get_be32 (f);
-
-    qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
-    qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
-    qemu_get_8s (f, &s->test_reg);
-    qemu_get_8s (f, &s->last_read_byte);
-
-    s->nzero=qemu_get_be32 (f);
-    s->left_till_irq=qemu_get_be32 (f);
-    s->dma_running=qemu_get_be32 (f);
-    s->bytes_per_second=qemu_get_be32 (f);
-    s->align=qemu_get_be32 (f);
-
-    s->mixer_nreg=qemu_get_be32 (f);
-    qemu_get_buffer (f, s->mixer_regs, 256);
+    PSB16STATE pThis = (SB16STATE *)opaque;
+#endif
+
+    pThis->irq=qemu_get_be32 (f);
+    pThis->dma=qemu_get_be32 (f);
+    pThis->hdma=qemu_get_be32 (f);
+    pThis->port=qemu_get_be32 (f);
+    pThis->ver=qemu_get_be32 (f);
+    pThis->in_index=qemu_get_be32 (f);
+    pThis->out_data_len=qemu_get_be32 (f);
+    pThis->fmt_stereo=qemu_get_be32 (f);
+    pThis->fmt_signed=qemu_get_be32 (f);
+    pThis->fmt_bits=qemu_get_be32 (f);
+    qemu_get_be32s (f, (uint32_t*)&pThis->fmt);
+    pThis->dma_auto=qemu_get_be32 (f);
+    pThis->block_size=qemu_get_be32 (f);
+    pThis->fifo=qemu_get_be32 (f);
+    pThis->freq=qemu_get_be32 (f);
+    pThis->time_const=qemu_get_be32 (f);
+    pThis->speaker=qemu_get_be32 (f);
+    pThis->needed_bytes=qemu_get_be32 (f);
+    pThis->cmd=qemu_get_be32 (f);
+    pThis->use_hdma=qemu_get_be32 (f);
+    pThis->highspeed=qemu_get_be32 (f);
+    pThis->can_write=qemu_get_be32 (f);
+    pThis->v2x6=qemu_get_be32 (f);
+
+    qemu_get_8s (f, &pThis->csp_param);
+    qemu_get_8s (f, &pThis->csp_value);
+    qemu_get_8s (f, &pThis->csp_mode);
+    qemu_get_8s (f, &pThis->csp_param);
+    qemu_get_buffer (f, pThis->csp_regs, 256);
+    qemu_get_8s (f, &pThis->csp_index);
+    qemu_get_buffer (f, pThis->csp_reg83, 4);
+    pThis->csp_reg83r=qemu_get_be32 (f);
+    pThis->csp_reg83w=qemu_get_be32 (f);
+
+    qemu_get_buffer (f, pThis->in2_data, sizeof (pThis->in2_data));
+    qemu_get_buffer (f, pThis->out_data, sizeof (pThis->out_data));
+    qemu_get_8s (f, &pThis->test_reg);
+    qemu_get_8s (f, &pThis->last_read_byte);
+
+    pThis->nzero=qemu_get_be32 (f);
+    pThis->left_till_irq=qemu_get_be32 (f);
+    pThis->dma_running=qemu_get_be32 (f);
+    pThis->bytes_per_second=qemu_get_be32 (f);
+    pThis->align=qemu_get_be32 (f);
+
+    pThis->mixer_nreg=qemu_get_be32 (f);
+    qemu_get_buffer (f, pThis->mixer_regs, 256);
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-    if (s->pGstStrmOut)
+    if (pThis->pGstStrmOut)
     {
-        s->pDrv->pfnCloseOut(s->pDrv, s->pGstStrmOut);
-        s->pGstStrmOut = NULL;
-    }
-#else
-    AUD_close_out (&s->card, s->voice);
-    s->voice = NULL;
+        pThis->pDrv->pfnCloseOut(pThis->pDrv, pThis->pGstStrmOut);
+        pThis->pGstStrmOut = NULL;
+    }
+#else
+    AUD_close_out (&pThis->card, pThis->voice);
+    pThis->voice = NULL;
 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
 
-    if (s->dma_running)
+    if (pThis->dma_running)
     {
-        if (s->freq)
+        if (pThis->freq)
         {
-            s->audio_free = 0;
+            pThis->audio_free = 0;
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
             PDMAUDIOSTREAMCFG streamCfg;
-            streamCfg.uHz           = s->freq;
-            streamCfg.cChannels     = 1 << s->fmt_stereo;
-            streamCfg.enmFormat     = s->fmt;
+            streamCfg.uHz           = pThis->freq;
+            streamCfg.cChannels     = 1 << pThis->fmt_stereo;
+            streamCfg.enmFormat     = pThis->fmt;
             streamCfg.enmEndianness = PDMAUDIOHOSTENDIANESS;
 
-            int rc = s->pDrv->pfnOpenOut(s->pDrv, "sb16.out", &streamCfg, &s->pGstStrmOut);
+            int rc = pThis->pDrv->pfnOpenOut(pThis->pDrv, "sb16.out", &streamCfg, &pThis->pGstStrmOut);
             AssertRC(rc);
 #else
             audsettings_t as;
-            as.freq = s->freq;
-            as.nchannels = 1 << s->fmt_stereo;
-            as.fmt = s->fmt;
+            as.freq = pThis->freq;
+            as.nchannels = 1 << pThis->fmt_stereo;
+            as.fmt = pThis->fmt;
             as.endianness = 0;
-            s->voice = AUD_open_out (
-                &s->card,
-                s->voice,
+            pThis->voice = AUD_open_out (
+                &pThis->card,
+                pThis->voice,
                 "sb16",
-                s,
+                pThis,
                 sb16AudioCallback,
                 &as
@@ -1757,6 +1805,6 @@
         }
 
-        control(s, 1);
-        speaker(s, s->speaker);
+        control(pThis, 1);
+        speaker(pThis, pThis->speaker);
     }
 
@@ -1769,5 +1817,5 @@
 int SB16_init (AudioState *audio, qemu_irq *pic)
 {
-    SB16State *s;
+    PSB16STATE pThis;
     int i;
     static const uint8_t dsp_write_ports[] = {0x6, 0xc};
@@ -1786,44 +1834,44 @@
     }
 
-    s->cmd = -1;
-    s->pic = pic;
-    s->irq = conf.irq;
-    s->dma = conf.dma;
-    s->hdma = conf.hdma;
-    s->port = conf.port;
-    s->ver = conf.ver_lo | (conf.ver_hi << 8);
-
-    s->mixer_regs[0x80] = magic_of_irq (s->irq);
-    s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
-    s->mixer_regs[0x82] = 2 << 5;
-
-    s->csp_regs[5] = 1;
-    s->csp_regs[9] = 0xf8;
-
-    reset_mixer (s);
-    s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
-    if (!s->aux_ts) {
+    pThis->cmd = -1;
+    pThis->pic = pic;
+    pThis->irq = conf.irq;
+    pThis->dma = conf.dma;
+    pThis->hdma = conf.hdma;
+    pThis->port = conf.port;
+    pThis->ver = conf.ver_lo | (conf.ver_hi << 8);
+
+    pThis->mixer_regs[0x80] = magic_of_irq (pThis->irq);
+    pThis->mixer_regs[0x81] = (1 << pThis->dma) | (1 << pThis->hdma);
+    pThis->mixer_regs[0x82] = 2 << 5;
+
+    pThis->csp_regs[5] = 1;
+    pThis->csp_regs[9] = 0xf8;
+
+    reset_mixer (pThis);
+    pThis->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
+    if (!pThis->aux_ts) {
         LogFlowFunc(("warning: Could not create auxiliary timer\n"));
     }
 
     for (i = 0; i < LENOFA (dsp_write_ports); i++) {
-        register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
+        register_ioport_write (pThis->port + dsp_write_ports[i], 1, 1, dsp_write, s);
     }
 
     for (i = 0; i < LENOFA (dsp_read_ports); i++) {
-        register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
-    }
-
-    register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
-    register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
-    register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
-    register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
-
-    DMA_register_channel (s->hdma, SB_read_DMA, s);
-    DMA_register_channel (s->dma, SB_read_DMA, s);
-    s->can_write = 1;
+        register_ioport_read (pThis->port + dsp_read_ports[i], 1, 1, dsp_read, s);
+    }
+
+    register_ioport_write (pThis->port + 0x4, 1, 1, mixer_write_indexb, s);
+    register_ioport_write (pThis->port + 0x4, 1, 2, mixer_write_indexw, s);
+    register_ioport_read (pThis->port + 0x5, 1, 1, mixer_read, s);
+    register_ioport_write (pThis->port + 0x5, 1, 1, mixer_write_datab, s);
+
+    DMA_register_channel (pThis->hdma, SB_read_DMA, s);
+    DMA_register_channel (pThis->dma, SB_read_DMA, s);
+    pThis->can_write = 1;
 
     register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
-    AUD_register_card (audio, "sb16", &s->card);
+    AUD_register_card (audio, "sb16", &pThis->card);
     return 0;
 }
@@ -1834,5 +1882,5 @@
 static DECLCALLBACK(int) sb16LiveExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
 {
-    SB16State *pThis = PDMINS_2_DATA (pDevIns, SB16State *);
+    PSB16STATE pThis = PDMINS_2_DATA (pDevIns, PSB16STATE);
 
     SSMR3PutS32(pSSM, pThis->irqCfg);
@@ -1846,5 +1894,5 @@
 static DECLCALLBACK(int) sb16SaveExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
 {
-    SB16State *pThis = PDMINS_2_DATA (pDevIns, SB16State *);
+    PSB16STATE pThis = PDMINS_2_DATA (pDevIns, PSB16STATE);
 
     sb16LiveExec (pDevIns, pSSM, 0);
@@ -1856,5 +1904,5 @@
                                        uint32_t uVersion, uint32_t uPass)
 {
-    SB16State *pThis = PDMINS_2_DATA (pDevIns, SB16State *);
+    PSB16STATE pThis = PDMINS_2_DATA (pDevIns, PSB16STATE);
 
     AssertMsgReturn(    uVersion == SB16_SAVE_STATE_VERSION
@@ -1902,5 +1950,5 @@
                                                 const char *pszIID)
 {
-    SB16State *pThis = RT_FROM_MEMBER(pInterface, SB16State, IBase);
+    PSB16STATE pThis = RT_FROM_MEMBER(pInterface, SB16STATE, IBase);
     Assert(&pThis->IBase == pInterface);
 
@@ -1914,5 +1962,20 @@
 static DECLCALLBACK(int) sb16Destruct(PPDMDEVINS pDevIns)
 {
-    SB16State *pThis = PDMINS_2_DATA(pDevIns, SB16State *);
+    PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE);
+
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    PSB16DRIVER pDrv;
+
+    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
+        pDrv->Out.phStrmOut = NULL;
+
+    pThis->pSinkOutput = NULL;
+
+    if (pThis->pMixer)
+    {
+        audioMixerDestroy(pThis->pMixer);
+        pThis->pMixer = NULL;
+    }
+#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
 
     return VINF_SUCCESS;
@@ -1921,5 +1984,5 @@
 static DECLCALLBACK(int) sb16Construct (PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
 {
-    SB16State *s = PDMINS_2_DATA(pDevIns, SB16State *);
+    PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE);
     int rc;
 
@@ -1941,21 +2004,21 @@
      * Read config data.
      */
-    rc = CFGMR3QuerySIntDef(pCfgHandle, "IRQ", &s->irq, 5);
+    rc = CFGMR3QuerySIntDef(pCfgHandle, "IRQ", &pThis->irq, 5);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Configuration error: Failed to get the \"IRQ\" value"));
-    s->irqCfg  = s->irq;
-
-    rc = CFGMR3QuerySIntDef(pCfgHandle, "DMA", &s->dma, 1);
+    pThis->irqCfg  = pThis->irq;
+
+    rc = CFGMR3QuerySIntDef(pCfgHandle, "DMA", &pThis->dma, 1);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Configuration error: Failed to get the \"DMA\" value"));
-    s->dmaCfg  = s->dma;
-
-    rc = CFGMR3QuerySIntDef(pCfgHandle, "DMA16", &s->hdma, 5);
+    pThis->dmaCfg  = pThis->dma;
+
+    rc = CFGMR3QuerySIntDef(pCfgHandle, "DMA16", &pThis->hdma, 5);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Configuration error: Failed to get the \"DMA16\" value"));
-    s->hdmaCfg = s->hdma;
+    pThis->hdmaCfg = pThis->hdma;
 
     RTIOPORT Port;
@@ -1964,6 +2027,6 @@
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Configuration error: Failed to get the \"Port\" value"));
-    s->port    = Port;
-    s->portCfg = Port;
+    pThis->port    = Port;
+    pThis->portCfg = Port;
 
     uint16_t u16Version;
@@ -1972,59 +2035,59 @@
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Configuration error: Failed to get the \"Version\" value"));
-    s->ver     = u16Version;
-    s->verCfg  = u16Version;
+    pThis->ver     = u16Version;
+    pThis->verCfg  = u16Version;
 
     /*
      * Init instance data.
      */
-    s->pDevIns                 = pDevIns;
-    s->IBase.pfnQueryInterface = sb16QueryInterface;
-    s->cmd                     = -1;
-
-    s->mixer_regs[0x80]        = magic_of_irq (s->irq);
-    s->mixer_regs[0x81]        = (1 << s->dma) | (1 << s->hdma);
-    s->mixer_regs[0x82]        = 2 << 5;
-
-    s->csp_regs[5]             = 1;
-    s->csp_regs[9]             = 0xf8;
-
-    reset_mixer(s);
+    pThis->pDevIns                 = pDevIns;
+    pThis->IBase.pfnQueryInterface = sb16QueryInterface;
+    pThis->cmd                     = -1;
+
+    pThis->mixer_regs[0x80]        = magic_of_irq (pThis->irq);
+    pThis->mixer_regs[0x81]        = (1 << pThis->dma) | (1 << pThis->hdma);
+    pThis->mixer_regs[0x82]        = 2 << 5;
+
+    pThis->csp_regs[5]             = 1;
+    pThis->csp_regs[9]             = 0xf8;
+
+    reset_mixer(pThis);
 
     /*
      * Create timer, register & attach stuff.
      */
-    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, sb16Timer, s,
-                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "SB16 timer", &s->pTimer);
+    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, sb16Timer, pThis,
+                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "SB16 timer", &pThis->pTimer);
     if (RT_FAILURE(rc))
         AssertMsgFailedReturn(("pfnTMTimerCreate -> %Rrc\n", rc), rc);
 
-    rc = PDMDevHlpIOPortRegister(pDevIns, s->port + 0x04,  2, s,
+    rc = PDMDevHlpIOPortRegister(pDevIns, pThis->port + 0x04,  2, pThis,
                                  mixer_write, mixer_read, NULL, NULL, "SB16");
     if (RT_FAILURE(rc))
         return rc;
-    rc = PDMDevHlpIOPortRegister(pDevIns, s->port + 0x06, 10, s,
+    rc = PDMDevHlpIOPortRegister(pDevIns, pThis->port + 0x06, 10, pThis,
                                  dsp_write, dsp_read, NULL, NULL, "SB16");
     if (RT_FAILURE(rc))
         return rc;
 
-    rc = PDMDevHlpDMARegister(pDevIns, s->hdma, SB_read_DMA, s);
+    rc = PDMDevHlpDMARegister(pDevIns, pThis->hdma, SB_read_DMA, pThis);
     if (RT_FAILURE(rc))
         return rc;
-    rc = PDMDevHlpDMARegister(pDevIns, s->dma, SB_read_DMA, s);
+    rc = PDMDevHlpDMARegister(pDevIns, pThis->dma, SB_read_DMA, pThis);
     if (RT_FAILURE(rc))
         return rc;
 
-    s->can_write = 1;
-
-    rc = PDMDevHlpSSMRegister3(pDevIns, SB16_SAVE_STATE_VERSION, sizeof(*s), sb16LiveExec, sb16SaveExec, sb16LoadExec);
+    pThis->can_write = 1;
+
+    rc = PDMDevHlpSSMRegister3(pDevIns, SB16_SAVE_STATE_VERSION, sizeof(SB16STATE), sb16LiveExec, sb16SaveExec, sb16LoadExec);
     if (RT_FAILURE(rc))
         return rc;
 
-    rc = PDMDevHlpDriverAttach(pDevIns, 0, &s->IBase, &s->pDrvBase, "Audio Driver Port");
+    rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port");
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     if(RT_SUCCESS(rc))
     {
-        s->pDrv = PDMIBASE_QUERY_INTERFACE(s->pDrvBase, PDMIAUDIOCONNECTOR);
-        AssertMsgReturn(s->pDrv,
+        pThis->pDrv = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
+        AssertMsgReturn(pThis->pDrv,
                         ("Configuration error: instance %d has no host audio interface!\n", iInstance),
                         VERR_PDM_MISSING_INTERFACE);
@@ -2042,13 +2105,13 @@
 
 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
-    legacy_reset(s);
-
-    if (!s->pDrv->pfnIsOutputOK(s->pDrv,s->pGstStrmOut))
+    legacy_reset(pThis);
+
+    if (!pThis->pDrv->pfnIsOutputOK(pThis->pDrv,pThis->pGstStrmOut))
     {
         LogRel(("SB16: WARNING: Unable to open PCM OUT!\n"));
-        s->pDrv->pfnCloseOut(s->pDrv, s->pGstStrmOut );
-        s->pGstStrmOut = NULL;
-
-        s->pDrv->pfnInitNull(s->pDrv);
+        pThis->pDrv->pfnCloseOut(pThis->pDrv, pThis->pGstStrmOut );
+        pThis->pGstStrmOut = NULL;
+
+        pThis->pDrv->pfnInitNull(pThis->pDrv);
 
         PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
@@ -2057,12 +2120,12 @@
     }
 #else
-    AUD_register_card("sb16", &s->card);
-    legacy_reset(s);
-
-    if (!AUD_is_host_voice_out_ok(s->voice))
+    AUD_register_card("sb16", &pThis->card);
+    legacy_reset(pThis);
+
+    if (!AUD_is_host_voice_out_ok(pThis->voice))
     {
         LogRel (("SB16: WARNING: Unable to open PCM OUT!\n"));
-        AUD_close_out (&s->card, s->voice);
-        s->voice = NULL;
+        AUD_close_out (&pThis->card, pThis->voice);
+        pThis->voice = NULL;
 
         AUD_init_null();
@@ -2096,5 +2159,5 @@
     1,
     /* cbInstance */
-    sizeof(SB16State),
+    sizeof(SB16STATE),
     /* pfnConstruct */
     sb16Construct,
Index: /trunk/src/VBox/Devices/Audio/DrvAudio.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 55004)
+++ /trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 55005)
@@ -76,25 +76,4 @@
 static int drvAudioDestroyHstIn(PDRVAUDIO pThis, PPDMAUDIOHSTSTRMIN pHstStrmIn);
 
-volume_t nominal_volume =
-{
-    0,
-    INT_MAX,
-    INT_MAX
-};
-
-volume_t sum_out_volume =
-{
-    0,
-    INT_MAX,
-    INT_MAX
-};
-
-volume_t pcm_in_volume =
-{
-    0,
-    INT_MAX,
-    INT_MAX
-};
-
 int drvAudioAddHstOut(PDRVAUDIO pThis, const char *pszName, PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOHSTSTRMOUT *ppHstStrmOut)
 {
@@ -498,4 +477,9 @@
                        const char *pszName, PPDMAUDIOSTREAMCFG pCfg)
 {
+    AssertPtrReturn(pGstStrmOut,  VERR_INVALID_POINTER);
+    AssertPtrReturn(pHostStrmOut, VERR_INVALID_POINTER);
+    AssertPtrReturn(pszName,      VERR_INVALID_POINTER);
+    AssertPtrReturn(pCfg,         VERR_INVALID_POINTER);
+
     int rc = drvAudioStreamCfgToProps(pCfg, &pGstStrmOut->Props);
     if (RT_SUCCESS(rc))
@@ -505,6 +489,5 @@
             return VERR_NO_MEMORY;
 
-        rc = audioMixBufInit(&pGstStrmOut->MixBuf, pszTemp, &pGstStrmOut->Props,
-                             audioMixBufSize(&pHostStrmOut->MixBuf));
+        rc = audioMixBufInit(&pGstStrmOut->MixBuf, pszTemp, &pGstStrmOut->Props, audioMixBufSize(&pHostStrmOut->MixBuf));
         if (RT_SUCCESS(rc))
             rc = audioMixBufLinkTo(&pGstStrmOut->MixBuf, &pHostStrmOut->MixBuf);
@@ -758,6 +741,5 @@
             return VERR_NO_MEMORY;
 
-        rc = audioMixBufInit(&pGstStrmIn->MixBuf, pszTemp, &pGstStrmIn->Props,
-                             audioMixBufSize(&pHstStrmIn->MixBuf));
+        rc = audioMixBufInit(&pGstStrmIn->MixBuf, pszTemp, &pGstStrmIn->Props, audioMixBufSize(&pHstStrmIn->MixBuf));
         if (RT_SUCCESS(rc))
             rc = audioMixBufLinkTo(&pHstStrmIn->MixBuf, &pGstStrmIn->MixBuf);
@@ -1456,50 +1438,4 @@
                  cRead, AUDIOMIXBUF_S2B(&pGstStrmIn->MixBuf, cRead), rc));
     return rc;
-}
-
-static DECLCALLBACK(int) drvAudioIsSetOutVolume(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOGSTSTRMOUT pGstStrmOut,
-                                                bool fMute, uint8_t uVolLeft, uint8_t uVolRight)
-{
-    LogFlowFunc(("[%s] fMute=%RTbool, uVolLeft=%RU8, uVolRight=%RU8\n",
-                 pGstStrmOut->MixBuf.pszName, fMute, uVolLeft, uVolRight));
-
-    if (pGstStrmOut)
-    {
-        pGstStrmOut->State.fMuted       = fMute;
-        pGstStrmOut->State.uVolumeLeft  = (uint32_t)uVolLeft * 0x808080; /* maximum is INT_MAX = 0x7fffffff */
-        pGstStrmOut->State.uVolumeRight = (uint32_t)uVolRight * 0x808080; /* maximum is INT_MAX = 0x7fffffff */
-    }
-
-    return VINF_SUCCESS;
-}
-
-/** @todo Handle more channels than stereo ... */
-static DECLCALLBACK(int) drvAudioSetVolume(PPDMIAUDIOCONNECTOR pInterface,
-                                           bool fMute, uint8_t uVolLeft, uint8_t uVolRight)
-{
-    LogFlowFunc(("fMute=%RTbool, uVolLeft=%RU8, uVolRight=%RU8\n",
-                 fMute, uVolLeft, uVolRight));
-
-    volume_t vol;
-
-    uint32_t u32VolumeLeft  = uVolLeft;
-    uint32_t u32VolumeRight = uVolRight;
-
-    /* 0x00..0xff => 0x01..0x100 */
-    if (u32VolumeLeft)
-        u32VolumeLeft++;
-    if (u32VolumeRight)
-        u32VolumeRight++;
-    vol.mute  = fMute ? 1 : 0;
-    vol.l     = u32VolumeLeft  * 0x800000; /* maximum is 0x80000000 */
-    vol.r     = u32VolumeRight * 0x800000; /* maximum is 0x80000000 */
-
-    sum_out_volume.mute = 0;
-    sum_out_volume.l    = ASMMultU64ByU32DivByU32(INT_MAX, INT_MAX, 0x80000000U);
-    sum_out_volume.r    = ASMMultU64ByU32DivByU32(INT_MAX, INT_MAX, 0x80000000U);
-
-    LogFlowFunc(("sum_out l=%RU32, r=%RU32\n", sum_out_volume.l, sum_out_volume.r));
-
-    return VINF_SUCCESS;
 }
 
@@ -1677,11 +1613,5 @@
 
     if (pGstStrmIn)
-    {
-        pGstStrmIn->State.uVolumeLeft = nominal_volume.l;
-        pGstStrmIn->State.uVolumeRight = nominal_volume.r;
-        pGstStrmIn->State.fMuted = RT_BOOL(nominal_volume.mute);
-
         *ppGstStrmIn = pGstStrmIn;
-    }
 
     LogFlowFuncLeaveRC(rc);
@@ -1763,8 +1693,4 @@
     {
         AssertPtr(pGstStrmOut);
-        pGstStrmOut->State.uVolumeLeft  = nominal_volume.l;
-        pGstStrmOut->State.uVolumeRight = nominal_volume.r;
-        pGstStrmOut->State.fMuted       = RT_BOOL(nominal_volume.mute);
-
         *ppGstStrmOut = pGstStrmOut;
 #if 0
@@ -1902,6 +1828,4 @@
     pThis->IAudioConnector.pfnIsOutputOK             = drvAudioIsOutputOK;
     pThis->IAudioConnector.pfnInitNull               = drvAudioInitNull;
-    pThis->IAudioConnector.pfnSetVolumeOut           = drvAudioIsSetOutVolume;
-    pThis->IAudioConnector.pfnSetVolume              = drvAudioSetVolume;
     pThis->IAudioConnector.pfnEnableOut              = drvAudioEnableOut;
     pThis->IAudioConnector.pfnEnableIn               = drvAudioEnableIn;
Index: unk/src/VBox/Devices/Audio/DrvAudio.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvAudio.h	(revision 55004)
+++ 	(revision )
@@ -1,204 +1,0 @@
-/* $Id$ */
-/** @file
- * Intermediate audio driver header.
- */
-
-/*
- * Copyright (C) 2006-2014 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- * --------------------------------------------------------------------
- *
- * This code is based on: audio.h
- *
- * QEMU Audio subsystem header
- *
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef DRV_AUDIO_H
-#define DRV_AUDIO_H
-
-#include <limits.h>
-
-#include <iprt/circbuf.h>
-
-#include <VBox/vmm/pdmdev.h>
-#include <VBox/vmm/pdm.h>
-#include <VBox/vmm/pdmaudioifs.h>
-
-typedef enum
-{
-    AUD_OPT_INT,
-    AUD_OPT_FMT,
-    AUD_OPT_STR,
-    AUD_OPT_BOOL
-} audio_option_tag_e;
-
-typedef struct audio_option
-{
-    const char *name;
-    audio_option_tag_e tag;
-    void *valp;
-    const char *descr;
-    int *overridenp;
-    int overriden;
-} audio_option;
-
-/**
- * Audio driver instance data.
- *
- * @implements PDMIAUDIOCONNECTOR
- */
-typedef struct DRVAUDIO
-{
-    /** Input/output processing thread. */
-    RTTHREAD                hThread;
-    /** Event for input/ouput processing. */
-    RTSEMEVENT              hEvent;
-    /** Shutdown indicator. */
-    bool                    fTerminate;
-    /** The audio interface presented to the device/driver above us. */
-    PDMIAUDIOCONNECTOR      IAudioConnector;
-    /** Pointer to the driver instance. */
-    PPDMDRVINS              pDrvIns;
-    /** Pointer to audio driver below us. */
-    PPDMIHOSTAUDIO          pHostDrvAudio;
-    RTLISTANCHOR            lstHstStrmIn;
-    RTLISTANCHOR            lstHstStrmOut;
-    /** Max. number of free input streams. */
-    uint8_t                 cFreeInputStreams;
-    /** Max. number of free output streams. */
-    uint8_t                 cFreeOutputStreams;
-    /** Audio configuration settings retrieved
-     *  from the backend. */
-    PDMAUDIOBACKENDCFG      BackendCfg;
-
-} DRVAUDIO, *PDRVAUDIO;
-
-/** Makes a PDRVBLOCK out of a PPDMIBLOCK. */
-#define PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface) \
-    ( (PDRVAUDIO)((uintptr_t)pInterface - RT_OFFSETOF(DRVAUDIO, IAudioConnector)) )
-
-//const char *drvAudioHlpFormatToString(PDMAUDIOFMT fmt);
-const char *drvAudioRecSourceToString(PDMAUDIORECSOURCE enmRecSource);
-PDMAUDIOFMT drvAudioHlpStringToFormat(const char *pszFormat);
-
-bool drvAudioPCMPropsAreEqual(PPDMPCMPROPS info, PPDMAUDIOSTREAMCFG pCfg);
-int drvAudioStreamCfgToProps(PPDMAUDIOSTREAMCFG pCfg, PPDMPCMPROPS pProps);
-void drvAudioStreamCfgPrint(PPDMAUDIOSTREAMCFG pCfg);
-
-/* AUDIO IN function declarations. */
-void drvAudioHlpPcmSwFreeResourcesIn(PPDMAUDIOGSTSTRMIN pGstStrmIn);
-void drvAudioGstInFreeRes(PPDMAUDIOGSTSTRMIN pGstStrmIn);
-void drvAudioGstInRemove(PPDMAUDIOGSTSTRMIN pGstStrmIn);
-uint32_t drvAudioHstInFindMinCaptured(PPDMAUDIOHSTSTRMIN pHstStrmIn);
-void drvAudioHstInFreeRes(PPDMAUDIOHSTSTRMIN pHstStrmIn);
-uint32_t drvAudioHstInGetFree(PPDMAUDIOHSTSTRMIN pHstStrmIn);
-uint32_t drvAudioHstInGetLive(PPDMAUDIOHSTSTRMIN pHstStrmIn);
-void drvAudioGstInRemove(PPDMAUDIOGSTSTRMIN pGstStrmIn);
-int  drvAudioGstInInit(PPDMAUDIOGSTSTRMIN pGstStrmIn, PPDMAUDIOHSTSTRMIN pHstStrmIn, const char *pszName, PPDMAUDIOSTREAMCFG pCfg);
-
-PPDMAUDIOHSTSTRMIN drvAudioFindNextHstIn(PDRVAUDIO pDrvAudio, PPDMAUDIOHSTSTRMIN pHstStrmIn);
-PPDMAUDIOHSTSTRMIN drvAudioFindNextEnabledHstIn(PDRVAUDIO pDrvAudio, PPDMAUDIOHSTSTRMIN pHstStrmIn);
-PPDMAUDIOHSTSTRMIN drvAudioFindNextEqHstIn(PDRVAUDIO pDrvAudio, PPDMAUDIOHSTSTRMIN pHstStrmIn, PPDMAUDIOSTREAMCFG pCfg);
-
-/* AUDIO OUT function declarations. */
-int  drvAudioGstOutAlloc(PPDMAUDIOGSTSTRMOUT pGstStrmOut);
-void drvAudioGstOutFreeRes(PPDMAUDIOGSTSTRMOUT pGstStrmOut);
-void drvAudioHstOutFreeRes(PPDMAUDIOHSTSTRMOUT pHstStrmOut);
-int  drvAudioDestroyGstOut(PDRVAUDIO pDrvAudio, PPDMAUDIOGSTSTRMOUT pGstStrmOut);
-void drvAudioDestroyHstOut(PDRVAUDIO pDrvAudio, PDMAUDIOHSTSTRMOUT pHstStrmOut);
-int  drvAudioGstOutInit(PPDMAUDIOGSTSTRMOUT pGstStrmOut, PPDMAUDIOHSTSTRMOUT pHstStrmOut, const char *pszName, PPDMAUDIOSTREAMCFG pCfg);
-
-PPDMAUDIOHSTSTRMOUT drvAudioFindAnyHstOut(PDRVAUDIO pDrvAudio, PPDMAUDIOHSTSTRMOUT pHstStrmOut);
-PPDMAUDIOHSTSTRMOUT drvAudioHstFindAnyEnabledOut(PDRVAUDIO pDrvAudio, PPDMAUDIOHSTSTRMOUT pHstStrmOut);
-PPDMAUDIOHSTSTRMOUT drvAudioFindSpecificOut(PDRVAUDIO pDrvAudio, PPDMAUDIOHSTSTRMOUT pHstStrmOut, PPDMAUDIOSTREAMCFG pCfg);
-int drvAudioAllocHstOut(PDRVAUDIO pDrvAudio, const char *pszName, PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOHSTSTRMOUT *ppHstStrmOut);
-int drvAudioHlpPcmHwAddOut(PDRVAUDIO pDrvAudio, PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOHSTSTRMOUT *ppHstStrmOut);
-int drvAudioHlpPcmCreateVoicePairOut(PDRVAUDIO pDrvAudio, const char *pszName, PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOGSTSTRMOUT *ppGstStrmOut);
-
-/* Common functions between DrvAudio and backends (host audio drivers). */
-int  drvAudioAttachCapture(PDRVAUDIO pDrvAudio, PPDMAUDIOHSTSTRMOUT pHstStrmOut);
-void drvAudioDetachCapture(PPDMAUDIOHSTSTRMOUT pHstStrmOut);
-uint32_t drvAudioHstOutSamplesLive(PPDMAUDIOHSTSTRMOUT pHstStrmOut, uint32_t *pcStreamsLive);
-
-void audio_pcm_info_clear_buf(PPDMPCMPROPS pPCMInfo, void *pvBuf, int len);
-
-/* Externals. */
-extern volume_t nominal_volume;
-extern volume_t pcm_in_volume;
-
-typedef struct fixed_settings
-{
-    int enabled;
-    int cStreams;
-    int greedy;
-    PDMAUDIOSTREAMCFG settings;
-} fixed_settings;
-
-static struct {
-    struct fixed_settings fixed_out;
-    struct fixed_settings fixed_in;
-    union {
-        int hz;
-        int64_t ticks;
-    } period;
-    int plive;
-} conf = {
-
-    /* Fixed output settings. */
-    {                           /* DAC fixed settings */
-        1,                      /* enabled */
-        1,                      /* cStreams */
-        1,                      /* greedy */
-        {
-            44100,              /* freq */
-            2,                  /* nchannels */
-            AUD_FMT_S16,        /* fmt */
-            PDMAUDIOHOSTENDIANESS
-        }
-    },
-
-    /* Fixed input settings. */
-    {                           /* ADC fixed settings */
-        1,                      /* enabled */
-        1,                      /* cStreams */
-        1,                      /* greedy */
-        {
-            44100,              /* freq */
-            2,                  /* nchannels */
-            AUD_FMT_S16,        /* fmt */
-            PDMAUDIOHOSTENDIANESS
-        }
-    },
-
-    { 200 },                    /* frequency (in Hz) */
-    0,                          /* plive */ /** @todo Disable pending live? */
-};
-#endif /* DRV_AUDIO_H */
-
