Index: /trunk/include/VBox/vmm/pdmaudioifs.h
===================================================================
--- /trunk/include/VBox/vmm/pdmaudioifs.h	(revision 88306)
+++ /trunk/include/VBox/vmm/pdmaudioifs.h	(revision 88307)
@@ -1034,7 +1034,6 @@
      *       differ between parent and child.  */
     uint32_t                    cMixed;
-    /** How much audio frames are currently being used
-     *  in this buffer.
-     *  Note: This also is known as the distance in ring buffer terms. */
+    /** How much audio frames are currently being used in this buffer.
+     * @note This also is known as the distance in ring buffer terms. */
     uint32_t                    cUsed;
     /** Number of children mix buffers kept in lstChildren. */
@@ -1240,4 +1239,6 @@
         STAMCOUNTER     AvgFramesWritten;
         STAMCOUNTER     TotalTimesWritten;
+        uint32_t        cbBackendWritableBefore;
+        uint32_t        cbBackendWritableAfter;
     } Stats;
     /** Hack alert: Max writable amount reported by the backend.
@@ -1524,4 +1525,6 @@
      * @param   pCfgGuest       Stream configuration for guest side.
      * @param   ppStream        Pointer where to return the created audio stream on success.
+     * @todo r=bird: It is not documented how pCfgHost and pCfgGuest can be
+     *       modified the DrvAudio...
      */
     DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAMCFG pCfgHost,
Index: /trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp	(revision 88306)
+++ /trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp	(revision 88307)
@@ -1964,10 +1964,7 @@
 
         PDMAUDMIXBUFCONVOPTS convOpts;
-        RT_ZERO(convOpts);
-
         convOpts.From.Volume.fMuted = pMixBuf->Volume.fMuted;
         convOpts.From.Volume.uLeft  = pMixBuf->Volume.uLeft;
         convOpts.From.Volume.uRight = pMixBuf->Volume.uRight;
-
         convOpts.cFrames = cToWrite;
 
Index: /trunk/src/VBox/Devices/Audio/AudioMixBuffer.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/AudioMixBuffer.h	(revision 88306)
+++ /trunk/src/VBox/Devices/Audio/AudioMixBuffer.h	(revision 88307)
@@ -54,11 +54,10 @@
 
 
-inline uint32_t AudioMixBufBytesToSamples(PPDMAUDIOMIXBUF pMixBuf);
+int     AudioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PCPDMAUDIOPCMPROPS pProps, uint32_t cFrames);
+void    AudioMixBufDestroy(PPDMAUDIOMIXBUF pMixBuf);
 void AudioMixBufClear(PPDMAUDIOMIXBUF pMixBuf);
-void AudioMixBufDestroy(PPDMAUDIOMIXBUF pMixBuf);
 void AudioMixBufFinish(PPDMAUDIOMIXBUF pMixBuf, uint32_t cFramesToClear);
 uint32_t AudioMixBufFree(PPDMAUDIOMIXBUF pMixBuf);
 uint32_t AudioMixBufFreeBytes(PPDMAUDIOMIXBUF pMixBuf);
-int AudioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PCPDMAUDIOPCMPROPS pProps, uint32_t cFrames);
 bool AudioMixBufIsEmpty(PPDMAUDIOMIXBUF pMixBuf);
 int AudioMixBufLinkTo(PPDMAUDIOMIXBUF pMixBuf, PPDMAUDIOMIXBUF pParent);
Index: /trunk/src/VBox/Devices/Audio/AudioMixer.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/AudioMixer.cpp	(revision 88306)
+++ /trunk/src/VBox/Devices/Audio/AudioMixer.cpp	(revision 88307)
@@ -98,5 +98,5 @@
 
 static int audioMixerSinkInit(PAUDMIXSINK pSink, PAUDIOMIXER pMixer, const char *pcszName, AUDMIXSINKDIR enmDir);
-static void audioMixerSinkDestroyInternal(PAUDMIXSINK pSink);
+static void audioMixerSinkDestroyInternal(PAUDMIXSINK pSink, PPDMDEVINS pDevIns);
 static int audioMixerSinkUpdateVolume(PAUDMIXSINK pSink, const PPDMAUDIOVOLUME pVolMaster);
 static void audioMixerSinkRemoveAllStreamsInternal(PAUDMIXSINK pSink);
@@ -110,5 +110,5 @@
 
 static int audioMixerStreamCtlInternal(PAUDMIXSTREAM pMixStream, PDMAUDIOSTREAMCMD enmCmd, uint32_t fCtl);
-static void audioMixerStreamDestroyInternal(PAUDMIXSTREAM pStream);
+static void audioMixerStreamDestroyInternal(PAUDMIXSTREAM pStream, PPDMDEVINS pDevIns);
 static int audioMixerStreamUpdateStatus(PAUDMIXSTREAM pMixStream);
 
@@ -161,10 +161,11 @@
  *
  * @returns VBox status code.
- * @param   pMixer              Mixer to attach created sink to.
- * @param   pszName             Name of the sink to create.
- * @param   enmDir              Direction of the sink to create.
- * @param   ppSink              Pointer which returns the created sink on success.
- */
-int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PAUDMIXSINK *ppSink)
+ * @param   pMixer      Mixer to attach created sink to.
+ * @param   pszName     Name of the sink to create.
+ * @param   enmDir      Direction of the sink to create.
+ * @param   pDevIns     The device instance to register statistics under.
+ * @param   ppSink      Pointer which returns the created sink on success.
+ */
+int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PPDMDEVINS pDevIns, PAUDMIXSINK *ppSink)
 {
     AssertPtrReturn(pMixer, VERR_INVALID_POINTER);
@@ -173,6 +174,5 @@
 
     int rc = RTCritSectEnter(&pMixer->CritSect);
-    if (RT_FAILURE(rc))
-        return rc;
+    AssertRCReturn(rc, rc);
 
     PAUDMIXSINK pSink = (PAUDMIXSINK)RTMemAllocZ(sizeof(AUDMIXSINK));
@@ -185,23 +185,21 @@
             if (RT_SUCCESS(rc))
             {
+                RTCritSectLeave(&pMixer->CritSect);
+
                 if (ppSink)
                     *ppSink = pSink;
+                return VINF_SUCCESS;
             }
         }
 
-        if (RT_FAILURE(rc))
-        {
-            audioMixerSinkDestroyInternal(pSink);
-
-            RTMemFree(pSink);
-            pSink = NULL;
-        }
+        audioMixerSinkDestroyInternal(pSink, pDevIns);
+
+        RTMemFree(pSink);
+        pSink = NULL;
     }
     else
         rc = VERR_NO_MEMORY;
 
-    int rc2 = RTCritSectLeave(&pMixer->CritSect);
-    AssertRC(rc2);
-
+    RTCritSectLeave(&pMixer->CritSect);
     return rc;
 }
@@ -297,7 +295,8 @@
  * Destroys an audio mixer.
  *
- * @param   pMixer              Audio mixer to destroy.
- */
-void AudioMixerDestroy(PAUDIOMIXER pMixer)
+ * @param   pMixer      Audio mixer to destroy.
+ * @param   pDevIns     The device instance the statistics are associated with.
+ */
+void AudioMixerDestroy(PAUDIOMIXER pMixer, PPDMDEVINS pDevIns)
 {
     if (!pMixer)
@@ -312,21 +311,13 @@
     RTListForEachSafe(&pMixer->lstSinks, pSink, pSinkNext, AUDMIXSINK, Node)
     {
-        /* Save a pointer to the sink to remove, as pSink
-         * will not be valid anymore after calling audioMixerRemoveSinkInternal(). */
-        PAUDMIXSINK pSinkToRemove = pSink;
-
-        audioMixerSinkDestroyInternal(pSinkToRemove);
-        audioMixerRemoveSinkInternal(pMixer, pSinkToRemove);
-
-        RTMemFree(pSinkToRemove);
+        audioMixerSinkDestroyInternal(pSink, pDevIns);
+        audioMixerRemoveSinkInternal(pMixer, pSink);
+        RTMemFree(pSink);
     }
 
     Assert(pMixer->cSinks == 0);
 
-    if (pMixer->pszName)
-    {
-        RTStrFree(pMixer->pszName);
-        pMixer->pszName = NULL;
-    }
+    RTStrFree(pMixer->pszName);
+    pMixer->pszName = NULL;
 
     rc2 = RTCritSectLeave(&pMixer->CritSect);
@@ -558,12 +549,15 @@
  *
  * @returns VBox status code.
- * @param   pSink               Sink to use for creating the stream.
- * @param   pConn               Audio connector interface to use.
- * @param   pCfg                Audio stream configuration to use.
- * @param   fFlags              Stream flags. Currently unused, set to 0.
- * @param   ppStream            Pointer which receives the newly created audio stream.
- */
-int AudioMixerSinkCreateStream(PAUDMIXSINK pSink,
-                               PPDMIAUDIOCONNECTOR pConn, PPDMAUDIOSTREAMCFG pCfg, AUDMIXSTREAMFLAGS fFlags, PAUDMIXSTREAM *ppStream)
+ * @param   pSink       Sink to use for creating the stream.
+ * @param   pConn       Audio connector interface to use.
+ * @param   pCfg        Audio stream configuration to use.  This may be modified
+ *                      in some unspecified way (see
+ *                      PDMIAUDIOCONNECTOR::pfnStreamCreate).
+ * @param   fFlags      Stream flags. Currently unused, set to 0.
+ * @param   pDevIns     The device instance to register statistics with.
+ * @param   ppStream    Pointer which receives the newly created audio stream.
+ */
+int AudioMixerSinkCreateStream(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConn, PPDMAUDIOSTREAMCFG pCfg,
+                               AUDMIXSTREAMFLAGS fFlags, PPDMDEVINS pDevIns, PAUDMIXSTREAM *ppStream)
 {
     AssertPtrReturn(pSink, VERR_INVALID_POINTER);
@@ -573,110 +567,124 @@
     /* ppStream is optional. */
 
+    /*
+     * Check status and get the host driver config.
+     */
     if (pConn->pfnGetStatus(pConn, PDMAUDIODIR_DUPLEX) == PDMAUDIOBACKENDSTS_NOT_ATTACHED)
         return VERR_AUDIO_BACKEND_NOT_ATTACHED;
-
-    PAUDMIXSTREAM pMixStream = (PAUDMIXSTREAM)RTMemAllocZ(sizeof(AUDMIXSTREAM));
-    if (!pMixStream)
-        return VERR_NO_MEMORY;
 
     PDMAUDIOBACKENDCFG BackendCfg;
     int rc = pConn->pfnGetConfig(pConn, &BackendCfg);
     if (RT_FAILURE(rc))
-    {
-        RTMemFree(pMixStream);
         return rc;
-    }
+
+    /*
+     * Allocate the instance.
+     */
+    PAUDMIXSTREAM pMixStream = (PAUDMIXSTREAM)RTMemAllocZ(sizeof(AUDMIXSTREAM));
+    AssertReturn(pMixStream, VERR_NO_MEMORY);
+
+    pMixStream->fFlags = fFlags;
 
     /* Assign the backend's name to the mixer stream's name for easier identification in the (release) log. */
     pMixStream->pszName = RTStrAPrintf2("[%s] %s", pCfg->szName, BackendCfg.szName);
-    if (!pMixStream->pszName)
-    {
-        RTMemFree(pMixStream);
-        return VERR_NO_MEMORY;
-    }
-
-    rc = RTCritSectEnter(&pSink->CritSect);
-    if (RT_FAILURE(rc))
-        return rc;
-
-    LogFlowFunc(("[%s] fFlags=0x%x (enmDir=%ld, %u bits, %RU8 channels, %RU32Hz)\n", pSink->pszName, fFlags, pCfg->enmDir,
-                 PDMAudioPropsSampleBits(&pCfg->Props), PDMAudioPropsChannels(&pCfg->Props), pCfg->Props.uHz));
-
-    /*
-     * Initialize the host-side configuration for the stream to be created.
-     * Always use the sink's PCM audio format as the host side when creating a stream for it.
-     */
-    AssertMsg(AudioHlpPcmPropsAreValid(&pSink->PCMProps),
-              ("%s: Does not (yet) have a format set when it must\n", pSink->pszName));
-
-    PDMAUDIOSTREAMCFG CfgHost;
-    rc = PDMAudioStrmCfgInitWithProps(&CfgHost, &pSink->PCMProps);
-    AssertRCReturn(rc, rc);
-
-    /* Apply the sink's direction for the configuration to use to
-     * create the stream. */
-    if (pSink->enmDir == AUDMIXSINKDIR_INPUT)
-    {
-        CfgHost.enmDir      = PDMAUDIODIR_IN;
-        CfgHost.u.enmSrc    = pCfg->u.enmSrc;
-        CfgHost.enmLayout   = pCfg->enmLayout;
+    pMixStream->pszStatPrefix = RTStrAPrintf2("Mix-%s/[%s] %s/", pSink->pszName, pCfg->szName, BackendCfg.szName);
+    if (pMixStream->pszName && pMixStream->pszStatPrefix)
+    {
+        rc = RTCritSectInit(&pMixStream->CritSect);
+        if (RT_SUCCESS(rc))
+        {
+            rc = RTCircBufCreate(&pMixStream->pCircBuf, PDMAudioPropsMilliToBytes(&pSink->PCMProps, 100 /*ms*/)); /** @todo Make this configurable. */
+            if (RT_SUCCESS(rc))
+            {
+                pMixStream->StatsCircBufSize = RTCircBufSize(pMixStream->pCircBuf);
+                pMixStream->StatsCircBufUsed = RTCircBufUsed(pMixStream->pCircBuf);
+
+                /*
+                 * Lock the sink so we can safely get it's properties and call
+                 * down into the audio driver to create that end of the stream.
+                 */
+                rc = RTCritSectEnter(&pSink->CritSect);
+                AssertRC(rc);
+                if (RT_SUCCESS(rc))
+                {
+                    LogFlowFunc(("[%s] fFlags=0x%x (enmDir=%ld, %u bits, %RU8 channels, %RU32Hz)\n", pSink->pszName, fFlags, pCfg->enmDir,
+                                 PDMAudioPropsSampleBits(&pCfg->Props), PDMAudioPropsChannels(&pCfg->Props), pCfg->Props.uHz));
+
+                    /*
+                     * Initialize the host-side configuration for the stream to be created.
+                     * Always use the sink's PCM audio format as the host side when creating a stream for it.
+                     */
+                    AssertMsg(AudioHlpPcmPropsAreValid(&pSink->PCMProps),
+                              ("%s: Does not (yet) have a format set when it must\n", pSink->pszName));
+
+                    PDMAUDIOSTREAMCFG CfgHost;
+                    rc = PDMAudioStrmCfgInitWithProps(&CfgHost, &pSink->PCMProps);
+                    AssertRC(rc); /* cannot fail */
+
+                    /* Apply the sink's direction for the configuration to use to create the stream. */
+                    if (pSink->enmDir == AUDMIXSINKDIR_INPUT)
+                    {
+                        CfgHost.enmDir      = PDMAUDIODIR_IN;
+                        CfgHost.u.enmSrc    = pCfg->u.enmSrc;
+                        CfgHost.enmLayout   = pCfg->enmLayout;
+                    }
+                    else
+                    {
+                        CfgHost.enmDir      = PDMAUDIODIR_OUT;
+                        CfgHost.u.enmDst    = pCfg->u.enmDst;
+                        CfgHost.enmLayout   = pCfg->enmLayout;
+                    }
+
+                    RTStrCopy(CfgHost.szName, sizeof(CfgHost.szName), pCfg->szName);
+
+                    /*
+                     * Create the stream.
+                     */
+                    PPDMAUDIOSTREAM pStream;
+                    rc = pConn->pfnStreamCreate(pConn, &CfgHost, pCfg, &pStream);
+                    if (RT_SUCCESS(rc))
+                    {
+                        /* Save the audio stream pointer to this mixing stream. */
+                        pMixStream->pStream = pStream;
+
+                        /* Increase the stream's reference count to let others know
+                         * we're reyling on it to be around now. */
+                        pConn->pfnStreamRetain(pConn, pStream);
+                        pMixStream->pConn = pConn;
+
+                        RTCritSectLeave(&pSink->CritSect);
+
+                        /*
+                         * Register statistics before we return.
+                         */
+                        PDMDevHlpSTAMRegisterF(pDevIns, &pMixStream->StatsCircBufSize, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES,
+                                               "Circular buffer size", "%sCircBufSize", pMixStream->pszStatPrefix);
+                        PDMDevHlpSTAMRegisterF(pDevIns, &pMixStream->StatsCircBufUsed, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES,
+                                               "Circular buffer fill size", "%sCircBufUsed", pMixStream->pszStatPrefix);
+
+                        if (ppStream)
+                            *ppStream = pMixStream;
+                        return VINF_SUCCESS;
+                    }
+
+                    /*
+                     * Failed.  Tear down the stream.
+                     */
+                    int rc2 = RTCritSectLeave(&pSink->CritSect);
+                    AssertRC(rc2);
+                }
+                RTCircBufDestroy(pMixStream->pCircBuf);
+            }
+            RTCritSectDelete(&pMixStream->CritSect);
+        }
     }
     else
-    {
-        CfgHost.enmDir      = PDMAUDIODIR_OUT;
-        CfgHost.u.enmDst    = pCfg->u.enmDst;
-        CfgHost.enmLayout   = pCfg->enmLayout;
-    }
-
-    RTStrPrintf(CfgHost.szName, sizeof(CfgHost.szName), "%s", pCfg->szName);
-
-    rc = RTCritSectInit(&pMixStream->CritSect);
-    if (RT_SUCCESS(rc))
-    {
-        PPDMAUDIOSTREAM pStream;
-        rc = pConn->pfnStreamCreate(pConn, &CfgHost, pCfg, &pStream);
-        if (RT_SUCCESS(rc))
-        {
-            /* Save the audio stream pointer to this mixing stream. */
-            pMixStream->pStream = pStream;
-
-            /* Increase the stream's reference count to let others know
-             * we're reyling on it to be around now. */
-            pConn->pfnStreamRetain(pConn, pStream);
-        }
-    }
-
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTCircBufCreate(&pMixStream->pCircBuf, PDMAudioPropsMilliToBytes(&pSink->PCMProps, 100 /*ms*/)); /** @todo Make this configurable. */
-        AssertRC(rc);
-    }
-
-    if (RT_SUCCESS(rc))
-    {
-        pMixStream->fFlags = fFlags;
-        pMixStream->pConn  = pConn;
-
-        if (ppStream)
-            *ppStream = pMixStream;
-    }
-    else if (pMixStream)
-    {
-        int rc2 = RTCritSectDelete(&pMixStream->CritSect);
-        AssertRC(rc2);
-
-        if (pMixStream->pszName)
-        {
-            RTStrFree(pMixStream->pszName);
-            pMixStream->pszName = NULL;
-        }
-
-        RTMemFree(pMixStream);
-        pMixStream = NULL;
-    }
-
-    int rc2 = RTCritSectLeave(&pSink->CritSect);
-    AssertRC(rc2);
-
+        rc = VERR_NO_STR_MEMORY;
+
+    RTStrFree(pMixStream->pszStatPrefix);
+    pMixStream->pszStatPrefix = NULL;
+    RTStrFree(pMixStream->pszName);
+    pMixStream->pszName = NULL;
+    RTMemFree(pMixStream);
     return rc;
 }
@@ -859,7 +867,8 @@
  * Destroys a mixer sink and removes it from the attached mixer (if any).
  *
- * @param   pSink               Mixer sink to destroy.
- */
-void AudioMixerSinkDestroy(PAUDMIXSINK pSink)
+ * @param   pSink       Mixer sink to destroy.
+ * @param   pDevIns     The device instance that statistics are registered with.
+ */
+void AudioMixerSinkDestroy(PAUDMIXSINK pSink, PPDMDEVINS pDevIns)
 {
     if (!pSink)
@@ -882,5 +891,5 @@
     AssertRC(rc2);
 
-    audioMixerSinkDestroyInternal(pSink);
+    audioMixerSinkDestroyInternal(pSink, pDevIns);
 
     RTMemFree(pSink);
@@ -891,7 +900,8 @@
  * Destroys a mixer sink.
  *
- * @param   pSink               Mixer sink to destroy.
- */
-static void audioMixerSinkDestroyInternal(PAUDMIXSINK pSink)
+ * @param   pSink       Mixer sink to destroy.
+ * @param   pDevIns     The device instance statistics are registered with.
+ */
+static void audioMixerSinkDestroyInternal(PAUDMIXSINK pSink, PPDMDEVINS pDevIns)
 {
     AssertPtrReturnVoid(pSink);
@@ -902,10 +912,6 @@
     RTListForEachSafe(&pSink->lstStreams, pStream, pStreamNext, AUDMIXSTREAM, Node)
     {
-        /* Save a pointer to the stream to remove, as pStream
-         * will not be valid anymore after calling audioMixerSinkRemoveStreamInternal(). */
-        PAUDMIXSTREAM pStreamToRemove = pStream;
-
-        audioMixerSinkRemoveStreamInternal(pSink, pStreamToRemove);
-        audioMixerStreamDestroyInternal(pStreamToRemove);
+        audioMixerSinkRemoveStreamInternal(pSink, pStream);
+        audioMixerStreamDestroyInternal(pStream, pDevIns);
     }
 
@@ -917,19 +923,10 @@
     }
 
-    if (pSink->pszName)
-    {
-        RTStrFree(pSink->pszName);
-        pSink->pszName = NULL;
-    }
-
-    if (pSink->pabScratchBuf)
-    {
-        Assert(pSink->cbScratchBuf);
-
-        RTMemFree(pSink->pabScratchBuf);
-        pSink->pabScratchBuf = NULL;
-
-        pSink->cbScratchBuf = 0;
-    }
+    RTStrFree(pSink->pszName);
+    pSink->pszName = NULL;
+
+    RTMemFree(pSink->pabScratchBuf);
+    pSink->pabScratchBuf = NULL;
+    pSink->cbScratchBuf = 0;
 
     AudioMixBufDestroy(&pSink->MixBuf);
@@ -1973,4 +1970,5 @@
     }
 
+    pMixStream->StatsCircBufUsed = RTCircBufUsed(pCircBuf);
     Log3Func(("[%s] cbWritten=%RU32\n", pMixStream->pszName, cbWritten));
 
@@ -2048,4 +2046,5 @@
 
                 pMixStream->tsLastReadWrittenNs = RTTimeNanoTS();
+                pMixStream->StatsCircBufUsed    = RTCircBufUsed(pCircBuf);
                 Log3Func(("[%s] Mixer stream '%s' -> cbWrittenBuf=%RU32\n", pSink->pszName, pMixStream->pszName, cbToWrite));
             }
@@ -2078,6 +2077,5 @@
 
     int rc = RTCritSectEnter(&pSink->CritSect);
-    if (RT_FAILURE(rc))
-        return rc;
+    AssertRCReturn(rc, rc);
 
     AssertMsg(pSink->fStatus & AUDMIXSINK_STS_RUNNING,
@@ -2090,16 +2088,17 @@
     while (cbToWrite)
     {
-        /* First, write the data to the mixer sink's own mixing buffer.
-         * Here the audio data can be transformed into the mixer sink's format. */
-        uint32_t cfWritten = 0;
-        rc = AudioMixBufWriteCirc(&pSink->MixBuf, (uint8_t *)pvBuf + cbWritten, cbToWrite, &cfWritten);
-        if (RT_FAILURE(rc))
+        /* Write the data to the mixer sink's own mixing buffer.
+           Here the audio data is transformed into the mixer sink's format. */
+        uint32_t cFramesWritten = 0;
+        rc = AudioMixBufWriteCirc(&pSink->MixBuf, (uint8_t const*)pvBuf + cbWritten, cbToWrite, &cFramesWritten);
+        if (RT_SUCCESS(rc))
+        {
+            const uint32_t cbWrittenChunk = PDMAudioPropsFramesToBytes(&pSink->PCMProps, cFramesWritten);
+            Assert(cbToWrite >= cbWrittenChunk);
+            cbToWrite -= cbWrittenChunk;
+            cbWritten += cbWrittenChunk;
+        }
+        else
             break;
-
-        const uint32_t cbWrittenChunk = PDMAudioPropsFramesToBytes(&pSink->PCMProps, cfWritten);
-
-        Assert(cbToWrite >= cbWrittenChunk);
-        cbToWrite -= cbWrittenChunk;
-        cbWritten += cbWrittenChunk;
     }
 
@@ -2112,7 +2111,5 @@
         *pcbWritten = cbWritten;
 
-    int rc2 = RTCritSectLeave(&pSink->CritSect);
-    AssertRC(rc2);
-
+    RTCritSectLeave(&pSink->CritSect);
     return rc;
 }
@@ -2214,7 +2211,8 @@
  * Destroys a mixer stream, internal version.
  *
- * @param   pMixStream          Mixer stream to destroy.
- */
-static void audioMixerStreamDestroyInternal(PAUDMIXSTREAM pMixStream)
+ * @param   pMixStream  Mixer stream to destroy.
+ * @param   pDevIns     The device instance the statistics are registered with.
+ */
+static void audioMixerStreamDestroyInternal(PAUDMIXSTREAM pMixStream, PPDMDEVINS pDevIns)
 {
     AssertPtrReturnVoid(pMixStream);
@@ -2235,9 +2233,13 @@
     }
 
-    if (pMixStream->pszName)
-    {
-        RTStrFree(pMixStream->pszName);
-        pMixStream->pszName = NULL;
-    }
+    if (pMixStream->pszStatPrefix)
+    {
+        PDMDevHlpSTAMDeregisterByPrefix(pDevIns, pMixStream->pszStatPrefix);
+        RTStrFree(pMixStream->pszStatPrefix);
+        pMixStream->pszStatPrefix = NULL;
+    }
+
+    RTStrFree(pMixStream->pszName);
+    pMixStream->pszName = NULL;
 
     if (pMixStream->pCircBuf)
@@ -2257,7 +2259,8 @@
  * Destroys a mixer stream.
  *
- * @param   pMixStream          Mixer stream to destroy.
- */
-void AudioMixerStreamDestroy(PAUDMIXSTREAM pMixStream)
+ * @param   pMixStream      Mixer stream to destroy.
+ * @param   pDevIns         The device instance statistics are registered with.
+ */
+void AudioMixerStreamDestroy(PAUDMIXSTREAM pMixStream, PPDMDEVINS pDevIns)
 {
     if (!pMixStream)
@@ -2290,5 +2293,5 @@
     if (RT_SUCCESS(rc2))
     {
-        audioMixerStreamDestroyInternal(pMixStream);
+        audioMixerStreamDestroyInternal(pMixStream, pDevIns);
         pMixStream = NULL;
     }
Index: /trunk/src/VBox/Devices/Audio/AudioMixer.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/AudioMixer.h	(revision 88306)
+++ /trunk/src/VBox/Devices/Audio/AudioMixer.h	(revision 88307)
@@ -86,4 +86,6 @@
     /** Name of this stream. */
     char                   *pszName;
+    /** The statistics prefix. */
+    char                   *pszStatPrefix;
     /** The streams's critical section. */
     RTCRITSECT              CritSect;
@@ -103,4 +105,8 @@
      *  holding (raw) device audio data. */
     PRTCIRCBUF              pCircBuf;
+    /** Stats: Number of bytes used in the circular buffer. */
+    uint32_t                StatsCircBufUsed;
+    /** Stats: Size of circular buffer. */
+    uint32_t                StatsCircBufSize;
 } AUDMIXSTREAM, *PAUDMIXSTREAM;
 
@@ -259,6 +265,6 @@
 
 int AudioMixerCreate(const char *pszName, uint32_t fFlags, PAUDIOMIXER *ppMixer);
-int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PAUDMIXSINK *ppSink);
-void AudioMixerDestroy(PAUDIOMIXER pMixer);
+int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PPDMDEVINS pDevIns, PAUDMIXSINK *ppSink);
+void AudioMixerDestroy(PAUDIOMIXER pMixer, PPDMDEVINS pDevIns);
 void AudioMixerInvalidate(PAUDIOMIXER pMixer);
 void AudioMixerRemoveSink(PAUDIOMIXER pMixer, PAUDMIXSINK pSink);
@@ -267,7 +273,8 @@
 
 int AudioMixerSinkAddStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
-int AudioMixerSinkCreateStream(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg, AUDMIXSTREAMFLAGS fFlags, PAUDMIXSTREAM *ppStream);
+int     AudioMixerSinkCreateStream(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg,
+                                   AUDMIXSTREAMFLAGS fFlags, PPDMDEVINS pDevIns, PAUDMIXSTREAM *ppStream);
 int AudioMixerSinkCtl(PAUDMIXSINK pSink, AUDMIXSINKCMD enmCmd);
-void AudioMixerSinkDestroy(PAUDMIXSINK pSink);
+void AudioMixerSinkDestroy(PAUDMIXSINK pSink, PPDMDEVINS pDevIns);
 uint32_t AudioMixerSinkGetReadable(PAUDMIXSINK pSink);
 uint32_t AudioMixerSinkGetWritable(PAUDMIXSINK pSink);
@@ -291,5 +298,5 @@
 
 int AudioMixerStreamCtl(PAUDMIXSTREAM pStream, PDMAUDIOSTREAMCMD enmCmd, uint32_t fCtl);
-void AudioMixerStreamDestroy(PAUDMIXSTREAM pStream);
+void AudioMixerStreamDestroy(PAUDMIXSTREAM pStream, PPDMDEVINS pDevIns);
 bool AudioMixerStreamIsActive(PAUDMIXSTREAM pStream);
 bool AudioMixerStreamIsValid(PAUDMIXSTREAM pStream);
Index: /trunk/src/VBox/Devices/Audio/DevHda.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevHda.cpp	(revision 88306)
+++ /trunk/src/VBox/Devices/Audio/DevHda.cpp	(revision 88307)
@@ -360,5 +360,5 @@
  */
 #ifdef IN_RING3
-static int hdaR3MixerAddDrvStream(PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv);
+static int hdaR3MixerAddDrvStream(PPDMDEVINS pDevIns, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv);
 #endif
 /** @} */
@@ -2185,8 +2185,9 @@
  *
  * @returns VBox status code.
+ * @param   pDevIns     The HDA device instance.
  * @param   pThisCC     The ring-3 HDA device state.
  * @param   pDrv        HDA driver to add.
  */
-static int hdaR3MixerAddDrv(PHDASTATER3 pThisCC, PHDADRIVER pDrv)
+static int hdaR3MixerAddDrv(PPDMDEVINS pDevIns, PHDASTATER3 pThisCC, PHDADRIVER pDrv)
 {
     int rc = VINF_SUCCESS;
@@ -2196,5 +2197,5 @@
         && AudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     {
-        int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkLineIn.pMixSink, &pStream->State.Cfg, pDrv);
+        int rc2 = hdaR3MixerAddDrvStream(pDevIns, pThisCC->SinkLineIn.pMixSink, &pStream->State.Cfg, pDrv);
         if (RT_SUCCESS(rc))
             rc = rc2;
@@ -2206,5 +2207,5 @@
         && AudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     {
-        int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkMicIn.pMixSink, &pStream->State.Cfg, pDrv);
+        int rc2 = hdaR3MixerAddDrvStream(pDevIns, pThisCC->SinkMicIn.pMixSink, &pStream->State.Cfg, pDrv);
         if (RT_SUCCESS(rc))
             rc = rc2;
@@ -2216,5 +2217,5 @@
         && AudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     {
-        int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkFront.pMixSink, &pStream->State.Cfg, pDrv);
+        int rc2 = hdaR3MixerAddDrvStream(pDevIns, pThisCC->SinkFront.pMixSink, &pStream->State.Cfg, pDrv);
         if (RT_SUCCESS(rc))
             rc = rc2;
@@ -2226,5 +2227,5 @@
         && AudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     {
-        int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkCenterLFE.pMixSink, &pStream->State.Cfg, pDrv);
+        int rc2 = hdaR3MixerAddDrvStream(pDevIns, pThisCC->SinkCenterLFE.pMixSink, &pStream->State.Cfg, pDrv);
         if (RT_SUCCESS(rc))
             rc = rc2;
@@ -2235,5 +2236,5 @@
         && AudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     {
-        int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkRear.pMixSink, &pStream->State.Cfg, pDrv);
+        int rc2 = hdaR3MixerAddDrvStream(pDevIns, pThisCC->SinkRear.pMixSink, &pStream->State.Cfg, pDrv);
         if (RT_SUCCESS(rc))
             rc = rc2;
@@ -2248,8 +2249,9 @@
  * associated streams.
  *
- * @param   pThisCC             The ring-3 HDA device state.
- * @param   pDrv                HDA driver to remove.
- */
-static void hdaR3MixerRemoveDrv(PHDASTATER3 pThisCC, PHDADRIVER pDrv)
+ * @param   pDevIns     The device instance.
+ * @param   pThisCC     The ring-3 HDA device state.
+ * @param   pDrv        HDA driver to remove.
+ */
+static void hdaR3MixerRemoveDrv(PPDMDEVINS pDevIns, PHDASTATER3 pThisCC, PHDADRIVER pDrv)
 {
     AssertPtrReturnVoid(pDrv);
@@ -2261,5 +2263,5 @@
 
         AudioMixerSinkRemoveStream(pThisCC->SinkLineIn.pMixSink, pDrv->LineIn.pMixStrm);
-        AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm);
+        AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm, pDevIns);
         pDrv->LineIn.pMixStrm = NULL;
     }
@@ -2272,5 +2274,5 @@
 
         AudioMixerSinkRemoveStream(pThisCC->SinkMicIn.pMixSink, pDrv->MicIn.pMixStrm);
-        AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm);
+        AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm, pDevIns);
         pDrv->MicIn.pMixStrm = NULL;
     }
@@ -2280,5 +2282,5 @@
     {
         AudioMixerSinkRemoveStream(pThisCC->SinkFront.pMixSink, pDrv->Front.pMixStrm);
-        AudioMixerStreamDestroy(pDrv->Front.pMixStrm);
+        AudioMixerStreamDestroy(pDrv->Front.pMixStrm, pDevIns);
         pDrv->Front.pMixStrm = NULL;
     }
@@ -2288,5 +2290,5 @@
     {
         AudioMixerSinkRemoveStream(pThisCC->SinkCenterLFE.pMixSink, pDrv->CenterLFE.pMixStrm);
-        AudioMixerStreamDestroy(pDrv->CenterLFE.pMixStrm);
+        AudioMixerStreamDestroy(pDrv->CenterLFE.pMixStrm, pDevIns);
         pDrv->CenterLFE.pMixStrm = NULL;
     }
@@ -2295,5 +2297,5 @@
     {
         AudioMixerSinkRemoveStream(pThisCC->SinkRear.pMixSink, pDrv->Rear.pMixStrm);
-        AudioMixerStreamDestroy(pDrv->Rear.pMixStrm);
+        AudioMixerStreamDestroy(pDrv->Rear.pMixStrm, pDevIns);
         pDrv->Rear.pMixStrm = NULL;
     }
@@ -2307,9 +2309,11 @@
  *
  * @returns VBox status code (ignored by caller).
- * @param   pMixSink            Audio mixer sink to add audio streams to.
- * @param   pCfg                Audio stream configuration to use for the audio streams to add.
- * @param   pDrv                Driver stream to add.
- */
-static int hdaR3MixerAddDrvStream(PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv)
+ * @param   pDevIns     The HDA device instance.
+ * @param   pMixSink    Audio mixer sink to add audio streams to.
+ * @param   pCfg        Audio stream configuration to use for the audio
+ *                      streams to add.
+ * @param   pDrv        Driver stream to add.
+ */
+static int hdaR3MixerAddDrvStream(PPDMDEVINS pDevIns, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv)
 {
     AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
@@ -2318,19 +2322,12 @@
     LogFunc(("szSink=%s, szStream=%s, cChannels=%RU8\n", pMixSink->pszName, pCfg->szName, PDMAudioPropsChannels(&pCfg->Props)));
 
-    PPDMAUDIOSTREAMCFG pStreamCfg = PDMAudioStrmCfgDup(pCfg);
-    if (!pStreamCfg)
-        return VERR_NO_MEMORY;
-
-    LogFunc(("[LUN#%RU8] %s\n", pDrv->uLUN, pStreamCfg->szName));
-
-    int rc = VINF_SUCCESS;
-
+    /*
+     * Get the matching stream driver.
+     */
     PHDADRIVERSTREAM pDrvStream = NULL;
-
-    if (pStreamCfg->enmDir == PDMAUDIODIR_IN)
-    {
-        LogFunc(("enmRecSource=%d\n", pStreamCfg->u.enmSrc));
-
-        switch (pStreamCfg->u.enmSrc)
+    if (pCfg->enmDir == PDMAUDIODIR_IN)
+    {
+        LogFunc(("enmSrc=%d\n", pCfg->u.enmSrc));
+        switch (pCfg->u.enmSrc)
         {
             case PDMAUDIORECSRC_LINE:
@@ -2343,13 +2340,12 @@
 # endif
             default:
-                rc = VERR_NOT_SUPPORTED;
-                break;
-        }
-    }
-    else if (pStreamCfg->enmDir == PDMAUDIODIR_OUT)
-    {
-        LogFunc(("enmPlaybackDest=%d\n", pStreamCfg->u.enmDst));
-
-        switch (pStreamCfg->u.enmDst)
+                LogFunc(("returns VERR_NOT_SUPPORTED - enmSrc=%d\n", pCfg->u.enmSrc));
+                return VERR_NOT_SUPPORTED;
+        }
+    }
+    else if (pCfg->enmDir == PDMAUDIODIR_OUT)
+    {
+        LogFunc(("enmDst=%d %s\n", pCfg->u.enmDst, PDMAudioPlaybackDstGetName(pCfg->u.enmDst)));
+        switch (pCfg->u.enmDst)
         {
             case PDMAUDIOPLAYBACKDST_FRONT:
@@ -2365,60 +2361,61 @@
 # endif
             default:
-                rc = VERR_NOT_SUPPORTED;
-                break;
+                LogFunc(("returns VERR_NOT_SUPPORTED - enmDst=%d %s\n", pCfg->u.enmDst, PDMAudioPlaybackDstGetName(pCfg->u.enmDst)));
+                return VERR_NOT_SUPPORTED;
         }
     }
     else
-        rc = VERR_NOT_SUPPORTED;
-
+        AssertFailedReturn(VERR_NOT_SUPPORTED);
+
+    PDMAUDIOSTREAMCFG StreamCfg; /** @todo r=bird: Why do we need to copy this? (We used to duplicate it originally.) */
+    PDMAudioStrmCfgCopy(&StreamCfg, pCfg);
+
+    LogFunc(("[LUN#%RU8] %s\n", pDrv->uLUN, StreamCfg.szName));
+
+    AssertPtr(pDrvStream);
+    AssertMsg(pDrvStream->pMixStrm == NULL, ("[LUN#%RU8] Driver stream already present when it must not\n", pDrv->uLUN));
+
+    PAUDMIXSTREAM pMixStrm = NULL;
+    int rc = AudioMixerSinkCreateStream(pMixSink, pDrv->pConnector, &StreamCfg, 0 /* fFlags */, pDevIns, &pMixStrm);
+    LogFlowFunc(("LUN#%RU8: Created stream \"%s\" for sink, rc=%Rrc\n", pDrv->uLUN, StreamCfg.szName, rc));
     if (RT_SUCCESS(rc))
     {
-        AssertPtr(pDrvStream);
-        AssertMsg(pDrvStream->pMixStrm == NULL, ("[LUN#%RU8] Driver stream already present when it must not\n", pDrv->uLUN));
-
-        PAUDMIXSTREAM pMixStrm;
-        rc = AudioMixerSinkCreateStream(pMixSink, pDrv->pConnector, pStreamCfg, 0 /* fFlags */, &pMixStrm);
-        LogFlowFunc(("LUN#%RU8: Created stream \"%s\" for sink, rc=%Rrc\n", pDrv->uLUN, pStreamCfg->szName, rc));
+        rc = AudioMixerSinkAddStream(pMixSink, pMixStrm);
+        LogFlowFunc(("LUN#%RU8: Added stream \"%s\" to sink, rc=%Rrc\n", pDrv->uLUN, StreamCfg.szName, rc));
         if (RT_SUCCESS(rc))
         {
-            rc = AudioMixerSinkAddStream(pMixSink, pMixStrm);
-            LogFlowFunc(("LUN#%RU8: Added stream \"%s\" to sink, rc=%Rrc\n", pDrv->uLUN, pStreamCfg->szName, rc));
-            if (RT_SUCCESS(rc))
+            /* If this is an input stream, always set the latest (added) stream
+             * as the recording source. */
+            /** @todo Make the recording source dynamic (CFGM?). */
+            if (StreamCfg.enmDir == PDMAUDIODIR_IN)
             {
-                /* If this is an input stream, always set the latest (added) stream
-                 * as the recording source. */
-                /** @todo Make the recording source dynamic (CFGM?). */
-                if (pStreamCfg->enmDir == PDMAUDIODIR_IN)
+                PDMAUDIOBACKENDCFG Cfg;
+                rc = pDrv->pConnector->pfnGetConfig(pDrv->pConnector, &Cfg);
+                if (RT_SUCCESS(rc))
                 {
-                    PDMAUDIOBACKENDCFG Cfg;
-                    rc = pDrv->pConnector->pfnGetConfig(pDrv->pConnector, &Cfg);
-                    if (RT_SUCCESS(rc))
+                    if (Cfg.cMaxStreamsIn) /* At least one input source available? */
                     {
-                        if (Cfg.cMaxStreamsIn) /* At least one input source available? */
-                        {
-                            rc = AudioMixerSinkSetRecordingSource(pMixSink, pMixStrm);
-                            LogFlowFunc(("LUN#%RU8: Recording source for '%s' -> '%s', rc=%Rrc\n",
-                                         pDrv->uLUN, pStreamCfg->szName, Cfg.szName, rc));
-
-                            if (RT_SUCCESS(rc))
-                                LogRel(("HDA: Set recording source for '%s' to '%s'\n",
-                                        pStreamCfg->szName, Cfg.szName));
-                        }
-                        else
-                            LogRel(("HDA: Backend '%s' currently is not offering any recording source for '%s'\n",
-                                    Cfg.szName, pStreamCfg->szName));
+                        rc = AudioMixerSinkSetRecordingSource(pMixSink, pMixStrm);
+                        LogFlowFunc(("LUN#%RU8: Recording source for '%s' -> '%s', rc=%Rrc\n",
+                                     pDrv->uLUN, StreamCfg.szName, Cfg.szName, rc));
+
+                        if (RT_SUCCESS(rc))
+                            LogRel(("HDA: Set recording source for '%s' to '%s'\n",
+                                    StreamCfg.szName, Cfg.szName));
                     }
-                    else if (RT_FAILURE(rc))
-                        LogFunc(("LUN#%RU8: Unable to retrieve backend configuration for '%s', rc=%Rrc\n",
-                                 pDrv->uLUN, pStreamCfg->szName, rc));
+                    else
+                        LogRel(("HDA: Backend '%s' currently is not offering any recording source for '%s'\n",
+                                Cfg.szName, StreamCfg.szName));
                 }
+                else if (RT_FAILURE(rc))
+                    LogFunc(("LUN#%RU8: Unable to retrieve backend configuration for '%s', rc=%Rrc\n",
+                             pDrv->uLUN, StreamCfg.szName, rc));
             }
         }
-
-        if (RT_SUCCESS(rc))
-            pDrvStream->pMixStrm = pMixStrm;
-    }
-
-    PDMAudioStrmCfgFree(pStreamCfg);
+/** @todo r=bird: We are missing cleanup code here!   */
+    }
+
+    if (RT_SUCCESS(rc))
+        pDrvStream->pMixStrm = pMixStrm;
 
     LogFlowFuncLeaveRC(rc);
@@ -2430,9 +2427,11 @@
  *
  * @returns VBox status code.
- * @param   pThisCC             The ring-3 HDA device state.
- * @param   pMixSink            Audio mixer sink to add stream to.
- * @param   pCfg                Audio stream configuration to use for the audio streams to add.
- */
-static int hdaR3MixerAddDrvStreams(PHDASTATER3 pThisCC, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
+ * @param   pDevIns     The HDA device instance.
+ * @param   pThisCC     The ring-3 HDA device state.
+ * @param   pMixSink    Audio mixer sink to add stream to.
+ * @param   pCfg        Audio stream configuration to use for the audio streams
+ *                      to add.
+ */
+static int hdaR3MixerAddDrvStreams(PPDMDEVINS pDevIns, PHDASTATER3 pThisCC, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
 {
     AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
@@ -2445,18 +2444,17 @@
 
     int rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props);
-    if (RT_FAILURE(rc))
-        return rc;
-
-    PHDADRIVER pDrv;
-    RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node)
-    {
-        int rc2 = hdaR3MixerAddDrvStream(pMixSink, pCfg, pDrv);
-        if (RT_FAILURE(rc2))
-            LogFunc(("Attaching stream failed with %Rrc\n", rc2));
-
-        /* Do not pass failure to rc here, as there might be drivers which aren't
-         * configured / ready yet. */
-    }
-
+    if (RT_SUCCESS(rc))
+    {
+        PHDADRIVER pDrv;
+        RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node)
+        {
+            int rc2 = hdaR3MixerAddDrvStream(pDevIns, pMixSink, pCfg, pDrv);
+            if (RT_FAILURE(rc2))
+                LogFunc(("Attaching stream failed with %Rrc\n", rc2));
+
+            /* Do not pass failure to rc here, as there might be drivers which aren't
+             * configured / ready yet. */
+        }
+    }
     return rc;
 }
@@ -2474,5 +2472,5 @@
     if (pSink)
     {
-        rc = hdaR3MixerAddDrvStreams(pThisCC, pSink->pMixSink, pCfg);
+        rc = hdaR3MixerAddDrvStreams(pDevIns, pThisCC, pSink->pMixSink, pCfg);
 
         AssertPtr(pSink->pMixSink);
@@ -2541,5 +2539,5 @@
             {
                 AudioMixerSinkRemoveStream(pSink->pMixSink, pMixStream);
-                AudioMixerStreamDestroy(pMixStream);
+                AudioMixerStreamDestroy(pMixStream, pDevIns);
 
                 pMixStream = NULL;
@@ -3453,16 +3451,14 @@
     AssertRCReturn(rc, rc);
 
-    uint32_t cbCircBufSize = 0;
+    uint32_t cbCircBuf     = 0;
     uint32_t cbCircBufUsed = 0;
 
     if (pStreamR3->State.pCircBuf)
     {
-        cbCircBufSize = (uint32_t)RTCircBufSize(pStreamR3->State.pCircBuf);
+        cbCircBuf     = (uint32_t)RTCircBufSize(pStreamR3->State.pCircBuf);
         cbCircBufUsed = (uint32_t)RTCircBufUsed(pStreamR3->State.pCircBuf);
     }
 
-    rc = pHlp->pfnSSMPutU32(pSSM, cbCircBufSize);
-    AssertRCReturn(rc, rc);
-
+    pHlp->pfnSSMPutU32(pSSM, cbCircBuf);
     rc = pHlp->pfnSSMPutU32(pSSM, cbCircBufUsed);
     AssertRCReturn(rc, rc);
@@ -4045,25 +4041,25 @@
          * Load internal (FIFO) buffer.
          */
-        uint32_t cbCircBufSize = 0;
-        pHlp->pfnSSMGetU32(pSSM, &cbCircBufSize); /* cbCircBuf */
+        uint32_t cbCircBuf = 0;
+        pHlp->pfnSSMGetU32(pSSM, &cbCircBuf); /* cbCircBuf */
         uint32_t cbCircBufUsed = 0;
         rc = pHlp->pfnSSMGetU32(pSSM, &cbCircBufUsed); /* cbCircBuf */
         AssertRCReturn(rc, rc);
 
-        if (cbCircBufSize) /* If 0, skip the buffer. */
+        if (cbCircBuf) /* If 0, skip the buffer. */
         {
             /* Paranoia. */
-            AssertLogRelMsgReturn(cbCircBufSize <= _32M,
+            AssertLogRelMsgReturn(cbCircBuf <= _32M,
                                   ("HDA: Saved state contains bogus DMA buffer size (%RU32) for stream #%RU8",
-                                   cbCircBufSize, idStream),
+                                   cbCircBuf, idStream),
                                   VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
-            AssertLogRelMsgReturn(cbCircBufUsed <= cbCircBufSize,
+            AssertLogRelMsgReturn(cbCircBufUsed <= cbCircBuf,
                                   ("HDA: Saved state contains invalid DMA buffer usage (%RU32/%RU32) for stream #%RU8",
-                                   cbCircBufUsed, cbCircBufSize, idStream),
+                                   cbCircBufUsed, cbCircBuf, idStream),
                                   VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
 
             /* Do we need to cre-create the circular buffer do fit the data size? */
             if (   pStreamR3->State.pCircBuf
-                && cbCircBufSize != (uint32_t)RTCircBufSize(pStreamR3->State.pCircBuf))
+                && cbCircBuf != (uint32_t)RTCircBufSize(pStreamR3->State.pCircBuf))
             {
                 RTCircBufDestroy(pStreamR3->State.pCircBuf);
@@ -4071,6 +4067,7 @@
             }
 
-            rc = RTCircBufCreate(&pStreamR3->State.pCircBuf, cbCircBufSize);
+            rc = RTCircBufCreate(&pStreamR3->State.pCircBuf, cbCircBuf);
             AssertRCReturn(rc, rc);
+            pStreamR3->State.StatDmaBufSize = cbCircBuf;
 
             if (cbCircBufUsed)
@@ -4524,9 +4521,10 @@
  *
  * @returns VBox status code.
+ * @param   pDevIns     The device instance.
  * @param   pThisCC     The ring-3 HDA device state.
  * @param   pDrv        Driver to detach from device.
  * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
  */
-static int hdaR3DetachInternal(PHDASTATER3 pThisCC, PHDADRIVER pDrv, uint32_t fFlags)
+static int hdaR3DetachInternal(PPDMDEVINS pDevIns, PHDASTATER3 pThisCC, PHDADRIVER pDrv, uint32_t fFlags)
 {
     RT_NOREF(fFlags);
@@ -4534,5 +4532,5 @@
     /* First, remove the driver from our list and destory it's associated streams.
      * This also will un-set the driver as a recording source (if associated). */
-    hdaR3MixerRemoveDrv(pThisCC, pDrv);
+    hdaR3MixerRemoveDrv(pDevIns, pThisCC, pDrv);
 
     /* Next, search backwards for a capable (attached) driver which now will be the
@@ -4589,5 +4587,5 @@
     int rc2 = hdaR3AttachInternal(pDevIns, pThis, pThisCC, uLUN, fFlags, &pDrv);
     if (RT_SUCCESS(rc2))
-        rc2 = hdaR3MixerAddDrv(pThisCC, pDrv);
+        rc2 = hdaR3MixerAddDrv(pDevIns, pThisCC, pDrv);
 
     if (RT_FAILURE(rc2))
@@ -4616,5 +4614,5 @@
         if (pDrv->uLUN == uLUN)
         {
-            int rc2 = hdaR3DetachInternal(pThisCC, pDrv, fFlags);
+            int rc2 = hdaR3DetachInternal(pDevIns, pThisCC, pDrv, fFlags);
             if (RT_SUCCESS(rc2))
             {
@@ -4622,5 +4620,4 @@
                 pDrv = NULL;
             }
-
             break;
         }
@@ -4654,5 +4651,5 @@
     if (pThisCC->pMixer)
     {
-        AudioMixerDestroy(pThisCC->pMixer);
+        AudioMixerDestroy(pThisCC->pMixer, pDevIns);
         pThisCC->pMixer = NULL;
     }
@@ -5022,12 +5019,16 @@
      */
 # ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
-    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] Front", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkFront.pMixSink);
+    rc = AudioMixerCreateSink(pThisCC->pMixer, "Front",
+                              AUDMIXSINKDIR_OUTPUT, pDevIns, &pThisCC->SinkFront.pMixSink);
     AssertRCReturn(rc, rc);
-    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] Center / Subwoofer", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkCenterLFE.pMixSink);
+    rc = AudioMixerCreateSink(pThisCC->pMixer, "Center+Subwoofer",
+                              AUDMIXSINKDIR_OUTPUT, pDevIns, &pThisCC->SinkCenterLFE.pMixSink);
     AssertRCReturn(rc, rc);
-    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] Rear", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkRear.pMixSink);
+    rc = AudioMixerCreateSink(pThisCC->pMixer, "Rear",
+                              AUDMIXSINKDIR_OUTPUT, pDevIns, &pThisCC->SinkRear.pMixSink);
     AssertRCReturn(rc, rc);
 # else
-    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkFront.pMixSink);
+    rc = AudioMixerCreateSink(pThisCC->pMixer, "PCM Output",
+                              AUDMIXSINKDIR_OUTPUT, pDevIns, &pThisCC->SinkFront.pMixSink);
     AssertRCReturn(rc, rc);
 # endif /* VBOX_WITH_AUDIO_HDA_51_SURROUND */
@@ -5036,8 +5037,10 @@
      * Add mixer input sinks.
      */
-    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThisCC->SinkLineIn.pMixSink);
+    rc = AudioMixerCreateSink(pThisCC->pMixer, "Line In",
+                              AUDMIXSINKDIR_INPUT, pDevIns, &pThisCC->SinkLineIn.pMixSink);
     AssertRCReturn(rc, rc);
 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
-    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThisCC->SinkMicIn.pMixSink);
+    rc = AudioMixerCreateSink(pThisCC->pMixer, "Microphone In",
+                              AUDMIXSINKDIR_INPUT, pDevIns, &pThisCC->SinkMicIn.pMixSink);
     AssertRCReturn(rc, rc);
 # endif
@@ -5357,5 +5360,5 @@
         PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.Mapping.GuestProps.cbFrame, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
                                "The number of channels.",                   "Stream%u/Cfg/FrameSize-Guest", idxStream);
-#if 0 /** @todo this would require some callback */
+#if 0 /** @todo this would require some callback or expansion. */
         PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.cChannelsX, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
                                "The number of channels.",                   "Stream%u/Cfg/Channels-Host", idxStream);
@@ -5365,4 +5368,9 @@
                                "The size of a sample (per channel).",       "Stream%u/Cfg/cbSample", idxStream);
 #endif
+
+        PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaBufSize, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES,
+                               "Size of the internal DMA buffer.",  "Stream%u/DMABufSize", idxStream);
+        PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaBufUsed, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES,
+                               "Number of bytes used in the internal DMA buffer.",  "Stream%u/DMABufUsed", idxStream);
     }
 
Index: /trunk/src/VBox/Devices/Audio/DevHdaStream.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevHdaStream.cpp	(revision 88306)
+++ /trunk/src/VBox/Devices/Audio/DevHdaStream.cpp	(revision 88307)
@@ -191,4 +191,6 @@
         RTCircBufDestroy(pStreamR3->State.pCircBuf);
         pStreamR3->State.pCircBuf = NULL;
+        pStreamR3->State.StatDmaBufSize = 0;
+        pStreamR3->State.StatDmaBufUsed = 0;
     }
 
@@ -692,4 +694,6 @@
         RTCircBufDestroy(pStreamR3->State.pCircBuf);
         pStreamR3->State.pCircBuf = NULL;
+        pStreamR3->State.StatDmaBufSize = 0;
+        pStreamR3->State.StatDmaBufUsed = 0;
     }
     pStreamR3->State.offWrite = 0;
@@ -750,4 +754,6 @@
         if (RT_SUCCESS(rc))
         {
+            pStreamR3->State.StatDmaBufSize = cbCircBuf;
+
             /*
              * Forward the timer frequency hint to TM as well for better accuracy on
@@ -1216,7 +1222,8 @@
  * @param   pDevIns         The device instance.
  * @param   pThis           The shared HDA device state.
- * @param   pStreamShared   HDA stream to update (shared).
- */
-DECLINLINE(void) hdaR3StreamDoDmaEpilogue(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared)
+ * @param   pStreamShared   The HDA stream (shared).
+ * @param   pStreamR3       The HDA stream (ring-3).
+ */
+DECLINLINE(void) hdaR3StreamDoDmaEpilogue(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3)
 {
     /*
@@ -1232,4 +1239,9 @@
      */
     pStreamShared->State.tsTransferLast = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer);
+
+    /*
+     * Update the buffer statistics.
+     */
+    pStreamR3->State.StatDmaBufUsed = RTCircBufUsed(pStreamR3->State.pCircBuf);
 }
 
@@ -1513,5 +1525,5 @@
      * Common epilogue.
      */
-    hdaR3StreamDoDmaEpilogue(pDevIns, pThis, pStreamShared);
+    hdaR3StreamDoDmaEpilogue(pDevIns, pThis, pStreamShared, pStreamR3);
 
     /*
@@ -1596,4 +1608,7 @@
         cbSinkReadable -= cbRead;
     }
+
+    /* Update buffer stats. */
+    pStreamR3->State.StatDmaBufUsed = RTCircBufUsed(pStreamR3->State.pCircBuf);
 }
 
@@ -1797,5 +1812,5 @@
      * Common epilogue.
      */
-    hdaR3StreamDoDmaEpilogue(pDevIns, pThis, pStreamShared);
+    hdaR3StreamDoDmaEpilogue(pDevIns, pThis, pStreamShared, pStreamR3);
 
     /*
@@ -1863,4 +1878,10 @@
     }
 
+    /* Update buffer stats. */
+    pStreamR3->State.StatDmaBufUsed = RTCircBufUsed(pStreamR3->State.pCircBuf);
+
+    /*
+     * Push the stuff thru the mixer jungle and down the host audio driver (backend).
+     */
     int rc2 = AudioMixerSinkUpdate(pSink);
     AssertRC(rc2);
Index: /trunk/src/VBox/Devices/Audio/DevHdaStream.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevHdaStream.h	(revision 88306)
+++ /trunk/src/VBox/Devices/Audio/DevHdaStream.h	(revision 88307)
@@ -316,4 +316,8 @@
         HDASTREAMSTATEAIO       AIO;
 #endif
+        /** Size of the DMA buffer (pCircBuf) in bytes. */
+        uint32_t                StatDmaBufSize;
+        /** Number of used bytes in the DMA buffer (pCircBuf). */
+        uint32_t                StatDmaBufUsed;
         /** Counter for all under/overflows problems. */
         STAMCOUNTER             StatDmaFlowProblems;
@@ -325,5 +329,5 @@
     /** Debug bits. */
     HDASTREAMDEBUG              Dbg;
-    uint64_t                    au64Alignment[2];
+    uint64_t                    au64Alignment[1];
 } HDASTREAMR3;
 AssertCompileSizeAlignment(HDASTREAMR3, 64);
Index: /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 88306)
+++ /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 88307)
@@ -682,5 +682,6 @@
 *********************************************************************************************************************************/
 #ifdef IN_RING3
-static int                ichac97R3StreamOpen(PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce);
+static int                ichac97R3StreamOpen(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream,
+                                              PAC97STREAMR3 pStreamCC, bool fForce);
 static int                ichac97R3StreamClose(PAC97STREAM pStream);
 static void               ichac97R3StreamLock(PAC97STREAMR3 pStreamCC);
@@ -695,6 +696,6 @@
 static DECLCALLBACK(void) ichac97R3Reset(PPDMDEVINS pDevIns);
 
-static void               ichac97R3MixerRemoveDrvStreams(PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir,
-                                                         PDMAUDIODSTSRCUNION dstSrc);
+static void               ichac97R3MixerRemoveDrvStreams(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink,
+                                                         PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc);
 
 # ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
@@ -968,13 +969,14 @@
  *
  * @returns VBox status code.
- * @param   pThis               The shared AC'97 state.
- * @param   pThisCC             The ring-3 AC'97 state.
- * @param   pStream             The AC'97 stream to enable or disable (shared
- *                              state).
- * @param   pStreamCC           The ring-3 stream state (matching to @a pStream).
- * @param   fEnable             Whether to enable or disable the stream.
- *
- */
-static int ichac97R3StreamEnable(PAC97STATE pThis, PAC97STATER3 pThisCC,
+ * @param   pDevIns     The device instance.
+ * @param   pThis       The shared AC'97 state.
+ * @param   pThisCC     The ring-3 AC'97 state.
+ * @param   pStream     The AC'97 stream to enable or disable (shared
+ *                      state).
+ * @param   pStreamCC   The ring-3 stream state (matching to @a pStream).
+ * @param   fEnable     Whether to enable or disable the stream.
+ *
+ */
+static int ichac97R3StreamEnable(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC,
                                  PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fEnable)
 {
@@ -995,5 +997,5 @@
             RTCircBufReset(pStreamCC->State.pCircBuf);
 
-        rc = ichac97R3StreamOpen(pThis, pThisCC, pStream, pStreamCC, false /* fForce */);
+        rc = ichac97R3StreamOpen(pDevIns, pThis, pThisCC, pStream, pStreamCC, false /* fForce */);
 
         if (RT_LIKELY(!pStreamCC->Dbg.Runtime.fEnabled))
@@ -1176,8 +1178,9 @@
  * Destroys all AC'97 audio streams of the device.
  *
- * @param   pThis               The shared AC'97 state.
- * @param   pThisCC             The ring-3 AC'97 state.
- */
-static void ichac97R3StreamsDestroy(PAC97STATE pThis, PAC97STATER3 pThisCC)
+ * @param   pDevIns     The device AC'97 instance.
+ * @param   pThis       The shared AC'97 state.
+ * @param   pThisCC     The ring-3 AC'97 state.
+ */
+static void ichac97R3StreamsDestroy(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC)
 {
     LogFlowFuncEnter();
@@ -1197,7 +1200,7 @@
     {
         dstSrc.enmSrc = PDMAUDIORECSRC_LINE;
-        ichac97R3MixerRemoveDrvStreams(pThisCC, pThisCC->pSinkLineIn, PDMAUDIODIR_IN, dstSrc);
-
-        AudioMixerSinkDestroy(pThisCC->pSinkLineIn);
+        ichac97R3MixerRemoveDrvStreams(pDevIns, pThisCC, pThisCC->pSinkLineIn, PDMAUDIODIR_IN, dstSrc);
+
+        AudioMixerSinkDestroy(pThisCC->pSinkLineIn, pDevIns);
         pThisCC->pSinkLineIn = NULL;
     }
@@ -1206,7 +1209,7 @@
     {
         dstSrc.enmSrc = PDMAUDIORECSRC_MIC;
-        ichac97R3MixerRemoveDrvStreams(pThisCC, pThisCC->pSinkMicIn, PDMAUDIODIR_IN, dstSrc);
-
-        AudioMixerSinkDestroy(pThisCC->pSinkMicIn);
+        ichac97R3MixerRemoveDrvStreams(pDevIns, pThisCC, pThisCC->pSinkMicIn, PDMAUDIODIR_IN, dstSrc);
+
+        AudioMixerSinkDestroy(pThisCC->pSinkMicIn, pDevIns);
         pThisCC->pSinkMicIn = NULL;
     }
@@ -1215,7 +1218,7 @@
     {
         dstSrc.enmDst = PDMAUDIOPLAYBACKDST_FRONT;
-        ichac97R3MixerRemoveDrvStreams(pThisCC, pThisCC->pSinkOut, PDMAUDIODIR_OUT, dstSrc);
-
-        AudioMixerSinkDestroy(pThisCC->pSinkOut);
+        ichac97R3MixerRemoveDrvStreams(pDevIns, pThisCC, pThisCC->pSinkOut, PDMAUDIODIR_OUT, dstSrc);
+
+        AudioMixerSinkDestroy(pThisCC->pSinkOut, pDevIns);
         pThisCC->pSinkOut = NULL;
     }
@@ -1839,9 +1842,10 @@
  *
  * @returns VBox status code.
- * @param   pMixSink            Mixer sink to add driver stream to.
- * @param   pCfg                Stream configuration to use.
- * @param   pDrv                Driver stream to add.
- */
-static int ichac97R3MixerAddDrvStream(PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PAC97DRIVER pDrv)
+ * @param   pDevIns     The device instance.
+ * @param   pMixSink    Mixer sink to add driver stream to.
+ * @param   pCfg        Stream configuration to use.
+ * @param   pDrv        Driver stream to add.
+ */
+static int ichac97R3MixerAddDrvStream(PPDMDEVINS pDevIns, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PAC97DRIVER pDrv)
 {
     AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
@@ -1867,5 +1871,5 @@
 
         PAUDMIXSTREAM pMixStrm;
-        rc = AudioMixerSinkCreateStream(pMixSink, pDrv->pConnector, pStreamCfg, 0 /* fFlags */, &pMixStrm);
+        rc = AudioMixerSinkCreateStream(pMixSink, pDrv->pConnector, pStreamCfg, 0 /* fFlags */, pDevIns, &pMixStrm);
         LogFlowFunc(("LUN#%RU8: Created stream \"%s\" for sink, rc=%Rrc\n", pDrv->uLUN, pStreamCfg->szName, rc));
         if (RT_SUCCESS(rc))
@@ -1913,5 +1917,5 @@
              * STAM when 48000Hz is configured right afterwards. */
             if (RT_FAILURE(rc))
-                AudioMixerStreamDestroy(pMixStrm);
+                AudioMixerStreamDestroy(pMixStrm, pDevIns);
         }
 
@@ -1932,9 +1936,10 @@
  *
  * @returns VBox status code.
- * @param   pThisCC             The ring-3 AC'97 state.
- * @param   pMixSink            Mixer sink to add stream to.
- * @param   pCfg                Stream configuration to use.
- */
-static int ichac97R3MixerAddDrvStreams(PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
+ * @param   pDevIns     The device instance.
+ * @param   pThisCC     The ring-3 AC'97 state.
+ * @param   pMixSink    Mixer sink to add stream to.
+ * @param   pCfg        Stream configuration to use.
+ */
+static int ichac97R3MixerAddDrvStreams(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
 {
     AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
@@ -1950,5 +1955,5 @@
     RTListForEach(&pThisCC->lstDrv, pDrv, AC97DRIVER, Node)
     {
-        int rc2 = ichac97R3MixerAddDrvStream(pMixSink, pCfg, pDrv);
+        int rc2 = ichac97R3MixerAddDrvStream(pDevIns, pMixSink, pCfg, pDrv);
         if (RT_FAILURE(rc2))
             LogFunc(("Attaching stream failed with %Rrc\n", rc2));
@@ -1966,17 +1971,20 @@
  *
  * @returns VBox status code.
+ * @param   pDevIns     The device instance.
  * @param   pThisCC     The ring-3 AC'97 device state.
  * @param   pDrv        The AC'97 driver to add.
  */
-static int ichac97R3MixerAddDrv(PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
+static int ichac97R3MixerAddDrv(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
 {
     int rc = VINF_SUCCESS;
 
     if (AudioHlpStreamCfgIsValid(&pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg))
-        rc = ichac97R3MixerAddDrvStream(pThisCC->pSinkLineIn, &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg, pDrv);
+        rc = ichac97R3MixerAddDrvStream(pDevIns, pThisCC->pSinkLineIn,
+                                        &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg, pDrv);
 
     if (AudioHlpStreamCfgIsValid(&pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg))
     {
-        int rc2 = ichac97R3MixerAddDrvStream(pThisCC->pSinkOut, &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg, pDrv);
+        int rc2 = ichac97R3MixerAddDrvStream(pDevIns, pThisCC->pSinkOut,
+                                             &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg, pDrv);
         if (RT_SUCCESS(rc))
             rc = rc2;
@@ -1985,5 +1993,6 @@
     if (AudioHlpStreamCfgIsValid(&pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg))
     {
-        int rc2 = ichac97R3MixerAddDrvStream(pThisCC->pSinkMicIn, &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg, pDrv);
+        int rc2 = ichac97R3MixerAddDrvStream(pDevIns, pThisCC->pSinkMicIn,
+                                             &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg, pDrv);
         if (RT_SUCCESS(rc))
             rc = rc2;
@@ -1997,8 +2006,9 @@
  * associated streams.
  *
- * @param pThisCC               The ring-3 AC'97 device state.
- * @param pDrv                  AC'97 driver to remove.
- */
-static void ichac97R3MixerRemoveDrv(PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
+ * @param   pDevIns     The device instance.
+ * @param   pThisCC     The ring-3 AC'97 device state.
+ * @param   pDrv        AC'97 driver to remove.
+ */
+static void ichac97R3MixerRemoveDrv(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
 {
     if (pDrv->MicIn.pMixStrm)
@@ -2008,5 +2018,5 @@
 
         AudioMixerSinkRemoveStream(pThisCC->pSinkMicIn,  pDrv->MicIn.pMixStrm);
-        AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm);
+        AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm, pDevIns);
         pDrv->MicIn.pMixStrm = NULL;
     }
@@ -2018,5 +2028,5 @@
 
         AudioMixerSinkRemoveStream(pThisCC->pSinkLineIn, pDrv->LineIn.pMixStrm);
-        AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm);
+        AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm, pDevIns);
         pDrv->LineIn.pMixStrm = NULL;
     }
@@ -2025,5 +2035,5 @@
     {
         AudioMixerSinkRemoveStream(pThisCC->pSinkOut,    pDrv->Out.pMixStrm);
-        AudioMixerStreamDestroy(pDrv->Out.pMixStrm);
+        AudioMixerStreamDestroy(pDrv->Out.pMixStrm, pDevIns);
         pDrv->Out.pMixStrm = NULL;
     }
@@ -2035,10 +2045,12 @@
  * Removes a driver stream from a specific mixer sink.
  *
- * @param   pMixSink            Mixer sink to remove audio streams from.
- * @param   enmDir              Stream direction to remove.
- * @param   dstSrc              Stream destination / source to remove.
- * @param   pDrv                Driver stream to remove.
- */
-static void ichac97R3MixerRemoveDrvStream(PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc, PAC97DRIVER pDrv)
+ * @param   pDevIns     The device instance.
+ * @param   pMixSink    Mixer sink to remove audio streams from.
+ * @param   enmDir      Stream direction to remove.
+ * @param   dstSrc      Stream destination / source to remove.
+ * @param   pDrv        Driver stream to remove.
+ */
+static void ichac97R3MixerRemoveDrvStream(PPDMDEVINS pDevIns, PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir,
+                                          PDMAUDIODSTSRCUNION dstSrc, PAC97DRIVER pDrv)
 {
     PAC97DRIVERSTREAM pDrvStream = ichac97R3MixerGetDrvStream(pDrv, enmDir, dstSrc);
@@ -2049,5 +2061,5 @@
             AudioMixerSinkRemoveStream(pMixSink, pDrvStream->pMixStrm);
 
-            AudioMixerStreamDestroy(pDrvStream->pMixStrm);
+            AudioMixerStreamDestroy(pDrvStream->pMixStrm, pDevIns);
             pDrvStream->pMixStrm = NULL;
         }
@@ -2058,10 +2070,11 @@
  * Removes all driver streams from a specific mixer sink.
  *
- * @param   pThisCC             The ring-3 AC'97 state.
- * @param   pMixSink            Mixer sink to remove audio streams from.
- * @param   enmDir              Stream direction to remove.
- * @param   dstSrc              Stream destination / source to remove.
- */
-static void ichac97R3MixerRemoveDrvStreams(PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink,
+ * @param   pDevIns     The device instance.
+ * @param   pThisCC     The ring-3 AC'97 state.
+ * @param   pMixSink    Mixer sink to remove audio streams from.
+ * @param   enmDir      Stream direction to remove.
+ * @param   dstSrc      Stream destination / source to remove.
+ */
+static void ichac97R3MixerRemoveDrvStreams(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink,
                                            PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc)
 {
@@ -2071,5 +2084,5 @@
     RTListForEach(&pThisCC->lstDrv, pDrv, AC97DRIVER, Node)
     {
-        ichac97R3MixerRemoveDrvStream(pMixSink, enmDir, dstSrc, pDrv);
+        ichac97R3MixerRemoveDrvStream(pDevIns, pMixSink, enmDir, dstSrc, pDrv);
     }
 }
@@ -2128,12 +2141,14 @@
  *
  * @returns VBox status code.
- * @param   pThis               The shared AC'97 device state (shared).
- * @param   pThisCC             The shared AC'97 device state (ring-3).
- * @param   pStream             The AC'97 stream to open (shared).
- * @param   pStreamCC           The AC'97 stream to open (ring-3).
- * @param   fForce              Whether to force re-opening the stream or not.
- *                              Otherwise re-opening only will happen if the PCM properties have changed.
- */
-static int ichac97R3StreamOpen(PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce)
+ * @param   pDevIns     The device instance.
+ * @param   pThis       The shared AC'97 device state (shared).
+ * @param   pThisCC     The shared AC'97 device state (ring-3).
+ * @param   pStream     The AC'97 stream to open (shared).
+ * @param   pStreamCC   The AC'97 stream to open (ring-3).
+ * @param   fForce      Whether to force re-opening the stream or not.
+ *                      Otherwise re-opening only will happen if the PCM properties have changed.
+ */
+static int ichac97R3StreamOpen(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream,
+                               PAC97STREAMR3 pStreamCC, bool fForce)
 {
     int                 rc = VINF_SUCCESS;
@@ -2230,7 +2245,7 @@
                 if (RT_SUCCESS(rc))
                 {
-                    ichac97R3MixerRemoveDrvStreams(pThisCC, pMixSink, Cfg.enmDir, Cfg.u);
-
-                    rc = ichac97R3MixerAddDrvStreams(pThisCC, pMixSink, &Cfg);
+                    ichac97R3MixerRemoveDrvStreams(pDevIns, pThisCC, pMixSink, Cfg.enmDir, Cfg.u);
+
+                    rc = ichac97R3MixerAddDrvStreams(pDevIns, pThisCC, pMixSink, &Cfg);
                     if (RT_SUCCESS(rc))
                         rc = PDMAudioStrmCfgCopy(&pStreamCC->State.Cfg, &Cfg);
@@ -2264,12 +2279,13 @@
  *
  * @returns VBox status code.
- * @param   pThis               The shared AC'97 device state.
- * @param   pThisCC             The ring-3 AC'97 device state.
- * @param   pStream             The AC'97 stream to re-open (shared).
- * @param   pStreamCC           The AC'97 stream to re-open (ring-3).
- * @param   fForce              Whether to force re-opening the stream or not.
- *                              Otherwise re-opening only will happen if the PCM properties have changed.
- */
-static int ichac97R3StreamReOpen(PAC97STATE pThis, PAC97STATER3 pThisCC,
+ * @param   pDevIns     The device instance.
+ * @param   pThis       The shared AC'97 device state.
+ * @param   pThisCC     The ring-3 AC'97 device state.
+ * @param   pStream     The AC'97 stream to re-open (shared).
+ * @param   pStreamCC   The AC'97 stream to re-open (ring-3).
+ * @param   fForce      Whether to force re-opening the stream or not.
+ *                      Otherwise re-opening only will happen if the PCM properties have changed.
+ */
+static int ichac97R3StreamReOpen(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC,
                                  PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce)
 {
@@ -2281,5 +2297,5 @@
     int rc = ichac97R3StreamClose(pStream);
     if (RT_SUCCESS(rc))
-        rc = ichac97R3StreamOpen(pThis, pThisCC, pStream, pStreamCC, fForce);
+        rc = ichac97R3StreamOpen(pDevIns, pThis, pThisCC, pStream, pStreamCC, fForce);
 
     return rc;
@@ -3244,5 +3260,5 @@
                             Assert((pRegs->cr & AC97_CR_RPBM) == 0);
 
-                            ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, false /* fEnable */);
+                            ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, false /* fEnable */);
                             ichac97R3StreamReset(pThis, pStream, pStreamCC);
 
@@ -3257,5 +3273,5 @@
                                 Log3Func(("[SD%RU8] Disable\n", pStream->u8SD));
 
-                                ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, false /* fEnable */);
+                                ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, false /* fEnable */);
 
                                 pRegs->sr |= AC97_SR_DCH;
@@ -3275,5 +3291,5 @@
                                 ichac97R3BDLEDumpAll(pDevIns, pStream->Regs.bdbar, pStream->Regs.lvi + 1);
 # endif
-                                ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, true /* fEnable */);
+                                ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, true /* fEnable */);
 
                                 /* Arm the timer for this stream. */
@@ -3557,9 +3573,9 @@
                     {
                         ichac97MixerSet(pThis, AC97_PCM_Front_DAC_Rate, 0xbb80); /* Set default (48000 Hz). */
-                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX],
+                        ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX],
                                               &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */);
 
                         ichac97MixerSet(pThis, AC97_PCM_LR_ADC_Rate, 0xbb80); /* Set default (48000 Hz). */
-                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX],
+                        ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX],
                                               &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
                     }
@@ -3573,5 +3589,5 @@
                     {
                         ichac97MixerSet(pThis, AC97_MIC_ADC_Rate, 0xbb80); /* Set default (48000 Hz). */
-                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX],
+                        ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX],
                                               &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */);
                     }
@@ -3591,5 +3607,5 @@
                         LogRel2(("AC97: Setting front DAC rate to 0x%x\n", u32));
                         ichac97MixerSet(pThis, offPort, u32);
-                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX],
+                        ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX],
                                               &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */);
                     }
@@ -3606,5 +3622,5 @@
                         LogRel2(("AC97: Setting microphone ADC rate to 0x%x\n", u32));
                         ichac97MixerSet(pThis, offPort, u32);
-                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX],
+                        ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX],
                                               &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */);
                     }
@@ -3621,5 +3637,5 @@
                         LogRel2(("AC97: Setting line-in ADC rate to 0x%x\n", u32));
                         ichac97MixerSet(pThis, offPort, u32);
-                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX],
+                        ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX],
                                               &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
                     }
@@ -3801,5 +3817,5 @@
         const PAC97STREAMR3 pStreamCC = &pThisCC->aStreams[i];
 
-        rc2 = ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, fEnable);
+        rc2 = ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, fEnable);
         AssertRC(rc2);
         if (   fEnable
@@ -3851,5 +3867,5 @@
     /* Note: Involves mixer stream / sink destruction, so also do this here
      *       instead of in ichac97R3Destruct(). */
-    ichac97R3StreamsDestroy(pThis, pThisCC);
+    ichac97R3StreamsDestroy(pDevIns, pThis, pThisCC);
 
     /*
@@ -3860,5 +3876,5 @@
     if (pThisCC->pMixer)
     {
-        AudioMixerDestroy(pThisCC->pMixer);
+        AudioMixerDestroy(pThisCC->pMixer, pDevIns);
         pThisCC->pMixer = NULL;
     }
@@ -3891,5 +3907,5 @@
     for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
     {
-        ichac97R3StreamEnable(pThis, pThisCC, &pThis->aStreams[i], &pThisCC->aStreams[i], false /* fEnable */);
+        ichac97R3StreamEnable(pDevIns, pThis, pThisCC, &pThis->aStreams[i], &pThisCC->aStreams[i], false /* fEnable */);
         ichac97R3StreamReset(pThis, &pThis->aStreams[i], &pThisCC->aStreams[i]);
     }
@@ -3988,9 +4004,10 @@
  *
  * @returns VBox status code.
+ * @param   pDevIns     The device instance.
  * @param   pThisCC     The ring-3 AC'97 device state.
  * @param   pDrv        Driver to detach from device.
  * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
  */
-static int ichac97R3DetachInternal(PAC97STATER3 pThisCC, PAC97DRIVER pDrv, uint32_t fFlags)
+static int ichac97R3DetachInternal(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAC97DRIVER pDrv, uint32_t fFlags)
 {
     RT_NOREF(fFlags);
@@ -3998,5 +4015,5 @@
     /* First, remove the driver from our list and destory it's associated streams.
      * This also will un-set the driver as a recording source (if associated). */
-    ichac97R3MixerRemoveDrv(pThisCC, pDrv);
+    ichac97R3MixerRemoveDrv(pDevIns, pThisCC, pDrv);
 
     /* Next, search backwards for a capable (attached) driver which now will be the
@@ -4054,5 +4071,5 @@
     int rc2 = ichac97R3AttachInternal(pDevIns, pThisCC, iLUN, fFlags, &pDrv);
     if (RT_SUCCESS(rc2))
-        rc2 = ichac97R3MixerAddDrv(pThisCC, pDrv);
+        rc2 = ichac97R3MixerAddDrv(pDevIns, pThisCC, pDrv);
 
     if (RT_FAILURE(rc2))
@@ -4081,5 +4098,5 @@
         if (pDrv->uLUN == iLUN)
         {
-            int rc2 = ichac97R3DetachInternal(pThisCC, pDrv, fFlags);
+            int rc2 = ichac97R3DetachInternal(pDevIns, pThisCC, pDrv, fFlags);
             if (RT_SUCCESS(rc2))
             {
@@ -4312,9 +4329,12 @@
     AssertRCReturn(rc, rc);
 
-    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThisCC->pSinkLineIn);
+    rc = AudioMixerCreateSink(pThisCC->pMixer, "Line In",
+                              AUDMIXSINKDIR_INPUT, pDevIns, &pThisCC->pSinkLineIn);
     AssertRCReturn(rc, rc);
-    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThisCC->pSinkMicIn);
+    rc = AudioMixerCreateSink(pThisCC->pMixer, "Microphone In",
+                              AUDMIXSINKDIR_INPUT, pDevIns, &pThisCC->pSinkMicIn);
     AssertRCReturn(rc, rc);
-    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThisCC->pSinkOut);
+    rc = AudioMixerCreateSink(pThisCC->pMixer, "PCM Output",
+                              AUDMIXSINKDIR_OUTPUT, pDevIns, &pThisCC->pSinkOut);
     AssertRCReturn(rc, rc);
 
Index: /trunk/src/VBox/Devices/Audio/DrvAudio.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 88306)
+++ /trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 88307)
@@ -1428,4 +1428,5 @@
             pStream->Out.cbBackendMaxWritable = cbWritable;
     }
+    pStream->Out.Stats.cbBackendWritableBefore = cbWritable;
 
     /*
@@ -1458,4 +1459,6 @@
 
         pStream->tsLastPlayedCapturedNs = RTTimeNanoTS();
+        pStream->Out.Stats.cbBackendWritableAfter = pThis->pHostDrvAudio->pfnStreamGetWritable(pThis->pHostDrvAudio,
+                                                                                               pStream->pvBackend);
     }
     else
@@ -2646,4 +2649,24 @@
      * Register statistics.
      */
+    PPDMDRVINS const pDrvIns = pThis->pDrvIns;
+    /** @todo expose config and more. */
+    if (pCfgGuest->enmDir == PDMAUDIODIR_OUT)
+    {
+        PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Out.Stats.cbBackendWritableBefore, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
+                               "Host side: Free space in backend buffer before play",  "%s/HostBackedBufFreeBefore", pStream->szName);
+        PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Out.Stats.cbBackendWritableAfter, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
+                               "Host side: Free space in backend buffer after play",   "%s/HostBackedBufFreeAfter", pStream->szName);
+    }
+    PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Host.Cfg.Backend.cFramesBufferSize, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
+                           "Host side: The size of the backend buffer (in frames)", "%s/HostBackedBufSize", pStream->szName);
+    PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Host.MixBuf.cFrames, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
+                           "Host side: The size of the mixer buffer (in frames)",   "%s/HostMixBufSize", pStream->szName);
+    PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Host.MixBuf.cUsed, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
+                           "Host side: Number of frames in the mixer buffer",       "%s/HostMixBufUsed", pStream->szName);
+    PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Guest.MixBuf.cFrames, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
+                           "Guest side: The size of the mixer buffer (in frames)",  "%s/GuestMixBufSize", pStream->szName);
+    PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Guest.MixBuf.cUsed, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
+                           "Guest side: Number of frames in the mixer buffer",      "%s/GuestMixBufUsed", pStream->szName);
+
 #ifdef VBOX_WITH_STATISTICS
     char szStatName[255];
@@ -2651,14 +2674,14 @@
     {
         RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalFramesCaptured", pStream->szName);
-        PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->In.Stats.TotalFramesCaptured,
+        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->In.Stats.TotalFramesCaptured,
                                   szStatName, STAMUNIT_COUNT, "Total frames played.");
         RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalTimesCaptured", pStream->szName);
-        PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->In.Stats.TotalTimesCaptured,
+        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->In.Stats.TotalTimesCaptured,
                                   szStatName, STAMUNIT_COUNT, "Total number of playbacks.");
         RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalFramesRead", pStream->szName);
-        PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->In.Stats.TotalFramesRead,
+        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->In.Stats.TotalFramesRead,
                                   szStatName, STAMUNIT_COUNT, "Total frames read.");
         RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalTimesRead", pStream->szName);
-        PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->In.Stats.TotalTimesRead,
+        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->In.Stats.TotalTimesRead,
                                   szStatName, STAMUNIT_COUNT, "Total number of reads.");
     }
@@ -2667,16 +2690,16 @@
         Assert(pCfgGuest->enmDir == PDMAUDIODIR_OUT);
         RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalFramesPlayed", pStream->szName);
-        PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->Out.Stats.TotalFramesPlayed,
+        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->Out.Stats.TotalFramesPlayed,
                                   szStatName, STAMUNIT_COUNT, "Total frames played.");
 
         RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalTimesPlayed", pStream->szName);
-        PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->Out.Stats.TotalTimesPlayed,
+        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->Out.Stats.TotalTimesPlayed,
                                   szStatName, STAMUNIT_COUNT, "Total number of playbacks.");
         RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalFramesWritten", pStream->szName);
-        PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->Out.Stats.TotalFramesWritten,
+        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->Out.Stats.TotalFramesWritten,
                                   szStatName, STAMUNIT_COUNT, "Total frames written.");
 
         RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalTimesWritten", pStream->szName);
-        PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->Out.Stats.TotalTimesWritten,
+        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->Out.Stats.TotalTimesWritten,
                                   szStatName, STAMUNIT_COUNT, "Total number of writes.");
     }
@@ -3203,11 +3226,12 @@
     }
 
+    PPDMDRVINS const pDrvIns = pThis->pDrvIns;
     if (pStream->enmDir == PDMAUDIODIR_IN)
     {
 #ifdef VBOX_WITH_STATISTICS
-        PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->In.Stats.TotalFramesCaptured);
-        PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->In.Stats.TotalTimesCaptured);
-        PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->In.Stats.TotalFramesRead);
-        PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->In.Stats.TotalTimesRead);
+        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->In.Stats.TotalFramesCaptured);
+        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->In.Stats.TotalTimesCaptured);
+        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->In.Stats.TotalFramesRead);
+        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->In.Stats.TotalTimesRead);
 #endif
         if (pThis->In.Cfg.Dbg.fEnabled)
@@ -3224,8 +3248,8 @@
         Assert(pStream->enmDir == PDMAUDIODIR_OUT);
 #ifdef VBOX_WITH_STATISTICS
-        PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->Out.Stats.TotalFramesPlayed);
-        PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->Out.Stats.TotalTimesPlayed);
-        PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->Out.Stats.TotalFramesWritten);
-        PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->Out.Stats.TotalTimesWritten);
+        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Out.Stats.TotalFramesPlayed);
+        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Out.Stats.TotalTimesPlayed);
+        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Out.Stats.TotalFramesWritten);
+        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Out.Stats.TotalTimesWritten);
 #endif
         if (pThis->Out.Cfg.Dbg.fEnabled)
@@ -3237,5 +3261,12 @@
             pStream->Out.Dbg.pFileStreamWrite = NULL;
         }
-    }
+        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Out.Stats.cbBackendWritableAfter);
+        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Out.Stats.cbBackendWritableBefore);
+    }
+    PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Host.Cfg.Backend.cFramesBufferSize);
+    PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Host.MixBuf.cFrames);
+    PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Host.MixBuf.cUsed);
+    PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Guest.MixBuf.cFrames);
+    PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Guest.MixBuf.cUsed);
 
     LogFlowFunc(("Returning %Rrc\n", rc));
