Index: trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp	(revision 89351)
+++ trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp	(revision 89352)
@@ -154,14 +154,68 @@
 
 
-/*********************************************************************************************************************************
-*   Internal Functions                                                                                                           *
-*********************************************************************************************************************************/
-#ifdef DEBUG
-static void audioMixBufDbgPrintInternal(PAUDIOMIXBUF pMixBuf, const char *pszFunc);
+
+#ifdef VBOX_STRICT
 # ifdef UNUSED
-static bool audioMixBufDbgValidate(PAUDIOMIXBUF pMixBuf);
-# endif
-#endif
-
+
+/**
+ * Prints a single mixing buffer.
+ * Internal helper function for debugging. Do not use directly.
+ *
+ * @returns VBox status code.
+ * @param   pMixBuf                 Mixing buffer to print.
+ * @param   pszFunc                 Function name to log this for.
+ * @param   uIdtLvl                 Indention level to use.
+ */
+static void audioMixBufDbgPrintSingle(PAUDIOMIXBUF pMixBuf, const char *pszFunc, uint16_t uIdtLvl)
+{
+    Log(("%s: %*s %s: offRead=%RU32, offWrite=%RU32, cMixed=%RU32 -> %RU32/%RU32\n",
+         pszFunc, uIdtLvl * 4, "",
+         pMixBuf->pszName, pMixBuf->offRead, pMixBuf->offWrite, pMixBuf->cMixed, pMixBuf->cUsed, pMixBuf->cFrames));
+}
+
+static void audioMixBufDbgPrintInternal(PAUDIOMIXBUF pMixBuf, const char *pszFunc)
+{
+    audioMixBufDbgPrintSingle(pMixBuf, pszFunc, 0 /* iIdtLevel */);
+}
+
+/**
+ * Validates a single mixing buffer.
+ *
+ * @return  @true if the buffer state is valid or @false if not.
+ * @param   pMixBuf                 Mixing buffer to validate.
+ */
+static bool audioMixBufDbgValidate(PAUDIOMIXBUF pMixBuf)
+{
+    //const uint32_t offReadEnd  = (pMixBuf->offRead + pMixBuf->cUsed) % pMixBuf->cFrames;
+    //const uint32_t offWriteEnd = (pMixBuf->offWrite + (pMixBuf->cFrames - pMixBuf->cUsed)) % pMixBuf->cFrames;
+
+    bool fValid = true;
+
+    AssertStmt(pMixBuf->offRead  <= pMixBuf->cFrames, fValid = false);
+    AssertStmt(pMixBuf->offWrite <= pMixBuf->cFrames, fValid = false);
+    AssertStmt(pMixBuf->cUsed    <= pMixBuf->cFrames, fValid = false);
+
+    if (pMixBuf->offWrite > pMixBuf->offRead)
+    {
+        if (pMixBuf->offWrite - pMixBuf->offRead != pMixBuf->cUsed)
+            fValid = false;
+    }
+    else if (pMixBuf->offWrite < pMixBuf->offRead)
+    {
+        if (pMixBuf->offWrite + pMixBuf->cFrames - pMixBuf->offRead != pMixBuf->cUsed)
+            fValid = false;
+    }
+
+    if (!fValid)
+    {
+        audioMixBufDbgPrintInternal(pMixBuf, __FUNCTION__);
+        AssertFailed();
+    }
+
+    return fValid;
+}
+
+# endif /* UNUSED */
+#endif /* VBOX_STRICT */
 
 
@@ -658,367 +712,4 @@
 #undef AUDMIXBUF_MACRO_LOG
 
-/**
- * Initializes a mixing buffer.
- *
- * @returns VBox status code.
- * @param   pMixBuf                 Mixing buffer to initialize.
- * @param   pszName                 Name of mixing buffer for easier identification. Optional.
- * @param   pProps                  PCM audio properties to use for the mixing buffer.
- * @param   cFrames                 Maximum number of audio frames the mixing buffer can hold.
- */
-int AudioMixBufInit(PAUDIOMIXBUF pMixBuf, const char *pszName, PCPDMAUDIOPCMPROPS pProps, uint32_t cFrames)
-{
-    AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
-    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
-    AssertPtrReturn(pProps,  VERR_INVALID_POINTER);
-    Assert(PDMAudioPropsAreValid(pProps));
-
-    pMixBuf->uMagic  = AUDIOMIXBUF_MAGIC;
-
-    pMixBuf->pFrames = NULL;
-    pMixBuf->cFrames = 0;
-
-    pMixBuf->offRead  = 0;
-    pMixBuf->offWrite = 0;
-    pMixBuf->cMixed   = 0;
-    pMixBuf->cUsed    = 0;
-
-    /* Set initial volume to max. */
-    pMixBuf->Volume.fMuted = false;
-    pMixBuf->Volume.uLeft  = AUDIOMIXBUF_VOL_0DB;
-    pMixBuf->Volume.uRight = AUDIOMIXBUF_VOL_0DB;
-
-    pMixBuf->Props       = *pProps;
-
-    pMixBuf->pszName = RTStrDup(pszName);
-    if (pMixBuf->pszName)
-    {
-        pMixBuf->pFrames = (PPDMAUDIOFRAME)RTMemAllocZ(cFrames * sizeof(PDMAUDIOFRAME));
-        if (pMixBuf->pFrames)
-        {
-            pMixBuf->cFrames = cFrames;
-#ifdef AUDMIXBUF_LOG_ENABLED
-            char szTmp[PDMAUDIOPROPSTOSTRING_MAX];
-            AUDMIXBUF_LOG(("%s: %s - cFrames=%#x (%d)\n",
-                           pMixBuf->pszName, PDMAudioPropsToString(pProps, szTmp, sizeof(szTmp)), cFrames, cFrames));
-#endif
-            return VINF_SUCCESS;
-        }
-        RTStrFree(pMixBuf->pszName);
-        pMixBuf->pszName = NULL;
-    }
-    pMixBuf->uMagic = AUDIOMIXBUF_MAGIC_DEAD;
-    return VERR_NO_MEMORY;
-}
-
-/**
- * Destroys (uninitializes) a mixing buffer.
- *
- * @param   pMixBuf                 Mixing buffer to destroy.
- */
-void AudioMixBufDestroy(PAUDIOMIXBUF pMixBuf)
-{
-    if (!pMixBuf)
-        return;
-
-    /* Ignore calls for an uninitialized (zeroed) or already destroyed instance.  Happens a lot. */
-    if (   pMixBuf->uMagic == 0
-        || pMixBuf->uMagic == ~AUDIOMIXBUF_MAGIC)
-    {
-        Assert(!pMixBuf->pszName);
-        Assert(!pMixBuf->pFrames);
-        Assert(!pMixBuf->cFrames);
-        return;
-    }
-
-    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
-    pMixBuf->uMagic = ~AUDIOMIXBUF_MAGIC;
-
-    if (pMixBuf->pszName)
-    {
-        AUDMIXBUF_LOG(("%s\n", pMixBuf->pszName));
-
-        RTStrFree(pMixBuf->pszName);
-        pMixBuf->pszName = NULL;
-    }
-
-    if (pMixBuf->pFrames)
-    {
-        Assert(pMixBuf->cFrames);
-
-        RTMemFree(pMixBuf->pFrames);
-        pMixBuf->pFrames = NULL;
-    }
-
-    pMixBuf->cFrames = 0;
-}
-
-
-/**
- * Drops all the frames in the given mixing buffer
- *
- * This will reset the read and write offsets to zero.
- *
- * @param   pMixBuf             The mixing buffer.
- */
-void AudioMixBufDrop(PAUDIOMIXBUF pMixBuf)
-{
-    AssertPtrReturnVoid(pMixBuf);
-    AssertReturnVoid(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
-
-    AUDMIXBUF_LOG(("%s\n", pMixBuf->pszName));
-
-    pMixBuf->offRead  = 0;
-    pMixBuf->offWrite = 0;
-    pMixBuf->cMixed   = 0;
-    pMixBuf->cUsed    = 0;
-}
-
-
-/**
- * Gets the maximum number of audio frames this buffer can hold.
- *
- * @returns Number of frames.
- * @param   pMixBuf     The mixing buffer.
- */
-uint32_t AudioMixBufSize(PCAUDIOMIXBUF pMixBuf)
-{
-    AssertPtrReturn(pMixBuf, 0);
-    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
-    return pMixBuf->cFrames;
-}
-
-
-/**
- * Gets the maximum number of bytes this buffer can hold.
- *
- * @returns Number of bytes.
- * @param   pMixBuf     The mixing buffer.
- */
-uint32_t AudioMixBufSizeBytes(PCAUDIOMIXBUF pMixBuf)
-{
-    AssertPtrReturn(pMixBuf, 0);
-    AssertReturn(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC, 0);
-    return AUDIOMIXBUF_F2B(pMixBuf, pMixBuf->cFrames);
-}
-
-
-/**
- * Worker for AudioMixBufUsed and AudioMixBufUsedBytes.
- */
-DECLINLINE(uint32_t) audioMixBufUsedInternal(PCAUDIOMIXBUF pMixBuf)
-{
-    uint32_t const cFrames = pMixBuf->cFrames;
-    uint32_t       cUsed   = pMixBuf->cUsed;
-    AssertStmt(cUsed <= cFrames, cUsed = cFrames);
-    return cUsed;
-}
-
-
-/**
- * Get the number of used (readable) frames in the buffer.
- *
- * @returns Number of frames.
- * @param   pMixBuf     The mixing buffer.
- */
-uint32_t AudioMixBufUsed(PCAUDIOMIXBUF pMixBuf)
-{
-    AssertPtrReturn(pMixBuf, 0);
-    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
-    return audioMixBufUsedInternal(pMixBuf);
-}
-
-
-/**
- * Get the number of (readable) bytes in the buffer.
- *
- * @returns Number of bytes.
- * @param   pMixBuf     The mixing buffer.
- */
-uint32_t AudioMixBufUsedBytes(PCAUDIOMIXBUF pMixBuf)
-{
-    AssertPtrReturn(pMixBuf, 0);
-    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
-    return AUDIOMIXBUF_F2B(pMixBuf, audioMixBufUsedInternal(pMixBuf));
-}
-
-
-/**
- * Worker for AudioMixBufFree and AudioMixBufFreeBytes.
- */
-DECLINLINE(uint32_t) audioMixBufFreeInternal(PCAUDIOMIXBUF pMixBuf)
-{
-    uint32_t const cFrames = pMixBuf->cFrames;
-    uint32_t       cUsed   = pMixBuf->cUsed;
-    AssertStmt(cUsed <= cFrames, cUsed = cFrames);
-    uint32_t const cFramesFree = cFrames - cUsed;
-
-    AUDMIXBUF_LOG(("%s: %RU32 of %RU32\n", pMixBuf->pszName, cFramesFree, cFrames));
-    return cFramesFree;
-}
-
-/**
- * Gets the free buffer space in frames.
- *
- * @return  Number of frames.
- * @param   pMixBuf     The mixing buffer.
- */
-uint32_t AudioMixBufFree(PCAUDIOMIXBUF pMixBuf)
-{
-    AssertPtrReturn(pMixBuf, 0);
-    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
-    return audioMixBufFreeInternal(pMixBuf);
-}
-
-/**
- * Gets the free buffer space in bytes.
- *
- * @return  Number of bytes.
- * @param   pMixBuf     The mixing buffer.
- */
-uint32_t AudioMixBufFreeBytes(PCAUDIOMIXBUF pMixBuf)
-{
-    AssertPtrReturn(pMixBuf, 0);
-    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
-    return AUDIOMIXBUF_F2B(pMixBuf, audioMixBufFreeInternal(pMixBuf));
-}
-
-
-/**
- * Checks if the buffer is empty.
- *
- * @retval  true if empty buffer.
- * @retval  false if not empty and there are frames to be processed.
- * @param   pMixBuf     The mixing buffer.
- */
-bool AudioMixBufIsEmpty(PCAUDIOMIXBUF pMixBuf)
-{
-    AssertPtrReturn(pMixBuf, true);
-    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
-    return pMixBuf->cUsed == 0;
-}
-
-
-/**
- * Get the current read position.
- *
- * This is for the testcase.
- *
- * @returns Frame number.
- * @param   pMixBuf     The mixing buffer.
- */
-uint32_t AudioMixBufReadPos(PCAUDIOMIXBUF pMixBuf)
-{
-    AssertPtrReturn(pMixBuf, 0);
-    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
-    return pMixBuf->offRead;
-}
-
-
-/**
- * Gets the current write position.
- *
- * This is for the testcase.
- *
- * @returns Frame number.
- * @param   pMixBuf     The mixing buffer.
- */
-uint32_t AudioMixBufWritePos(PCAUDIOMIXBUF pMixBuf)
-{
-    AssertPtrReturn(pMixBuf, 0);
-    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
-    return pMixBuf->offWrite;
-}
-
-#ifdef DEBUG
-
-/**
- * Prints a single mixing buffer.
- * Internal helper function for debugging. Do not use directly.
- *
- * @returns VBox status code.
- * @param   pMixBuf                 Mixing buffer to print.
- * @param   pszFunc                 Function name to log this for.
- * @param   uIdtLvl                 Indention level to use.
- */
-static void audioMixBufDbgPrintSingle(PAUDIOMIXBUF pMixBuf, const char *pszFunc, uint16_t uIdtLvl)
-{
-    Log(("%s: %*s %s: offRead=%RU32, offWrite=%RU32, cMixed=%RU32 -> %RU32/%RU32\n",
-         pszFunc, uIdtLvl * 4, "",
-         pMixBuf->pszName, pMixBuf->offRead, pMixBuf->offWrite, pMixBuf->cMixed, pMixBuf->cUsed, pMixBuf->cFrames));
-}
-
-# ifdef UNUSED
-/**
- * Validates a single mixing buffer.
- *
- * @return  @true if the buffer state is valid or @false if not.
- * @param   pMixBuf                 Mixing buffer to validate.
- */
-static bool audioMixBufDbgValidate(PAUDIOMIXBUF pMixBuf)
-{
-    //const uint32_t offReadEnd  = (pMixBuf->offRead + pMixBuf->cUsed) % pMixBuf->cFrames;
-    //const uint32_t offWriteEnd = (pMixBuf->offWrite + (pMixBuf->cFrames - pMixBuf->cUsed)) % pMixBuf->cFrames;
-
-    bool fValid = true;
-
-    AssertStmt(pMixBuf->offRead  <= pMixBuf->cFrames, fValid = false);
-    AssertStmt(pMixBuf->offWrite <= pMixBuf->cFrames, fValid = false);
-    AssertStmt(pMixBuf->cUsed    <= pMixBuf->cFrames, fValid = false);
-
-    if (pMixBuf->offWrite > pMixBuf->offRead)
-    {
-        if (pMixBuf->offWrite - pMixBuf->offRead != pMixBuf->cUsed)
-            fValid = false;
-    }
-    else if (pMixBuf->offWrite < pMixBuf->offRead)
-    {
-        if (pMixBuf->offWrite + pMixBuf->cFrames - pMixBuf->offRead != pMixBuf->cUsed)
-            fValid = false;
-    }
-
-    if (!fValid)
-    {
-        audioMixBufDbgPrintInternal(pMixBuf, __FUNCTION__);
-        AssertFailed();
-    }
-
-    return fValid;
-}
-# endif
-
-/**
- * Prints statistics and status of the full chain of a mixing buffer to the logger,
- * starting from the top root mixing buffer.
- * For debug versions only.
- *
- * @returns VBox status code.
- * @param   pMixBuf                 Mixing buffer to print.
- */
-void AudioMixBufDbgPrintChain(PAUDIOMIXBUF pMixBuf)
-{
-    audioMixBufDbgPrintSingle(pMixBuf, __FUNCTION__, 0 /* uIdtLvl */);
-}
-
-DECL_FORCE_INLINE(void) audioMixBufDbgPrintInternal(PAUDIOMIXBUF pMixBuf, const char *pszFunc)
-{
-    audioMixBufDbgPrintSingle(pMixBuf, pszFunc, 0 /* iIdtLevel */);
-}
-
-/**
- * Prints statistics and status of a mixing buffer to the logger.
- * For debug versions only.
- *
- * @returns VBox status code.
- * @param   pMixBuf                 Mixing buffer to print.
- */
-void AudioMixBufDbgPrint(PAUDIOMIXBUF pMixBuf)
-{
-    audioMixBufDbgPrintInternal(pMixBuf, __FUNCTION__);
-}
-
-#endif /* DEBUG */
-
-
 /*
  * Resampling core.
@@ -1176,4 +867,279 @@
 
 
+/**
+ * Initializes a mixing buffer.
+ *
+ * @returns VBox status code.
+ * @param   pMixBuf                 Mixing buffer to initialize.
+ * @param   pszName                 Name of mixing buffer for easier identification. Optional.
+ * @param   pProps                  PCM audio properties to use for the mixing buffer.
+ * @param   cFrames                 Maximum number of audio frames the mixing buffer can hold.
+ */
+int AudioMixBufInit(PAUDIOMIXBUF pMixBuf, const char *pszName, PCPDMAUDIOPCMPROPS pProps, uint32_t cFrames)
+{
+    AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
+    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
+    AssertPtrReturn(pProps,  VERR_INVALID_POINTER);
+    Assert(PDMAudioPropsAreValid(pProps));
+
+    pMixBuf->uMagic  = AUDIOMIXBUF_MAGIC;
+
+    pMixBuf->pFrames = NULL;
+    pMixBuf->cFrames = 0;
+
+    pMixBuf->offRead  = 0;
+    pMixBuf->offWrite = 0;
+    pMixBuf->cMixed   = 0;
+    pMixBuf->cUsed    = 0;
+
+    /* Set initial volume to max. */
+    pMixBuf->Volume.fMuted = false;
+    pMixBuf->Volume.uLeft  = AUDIOMIXBUF_VOL_0DB;
+    pMixBuf->Volume.uRight = AUDIOMIXBUF_VOL_0DB;
+
+    pMixBuf->Props       = *pProps;
+
+    pMixBuf->pszName = RTStrDup(pszName);
+    if (pMixBuf->pszName)
+    {
+        pMixBuf->pFrames = (PPDMAUDIOFRAME)RTMemAllocZ(cFrames * sizeof(PDMAUDIOFRAME));
+        if (pMixBuf->pFrames)
+        {
+            pMixBuf->cFrames = cFrames;
+#ifdef AUDMIXBUF_LOG_ENABLED
+            char szTmp[PDMAUDIOPROPSTOSTRING_MAX];
+            AUDMIXBUF_LOG(("%s: %s - cFrames=%#x (%d)\n",
+                           pMixBuf->pszName, PDMAudioPropsToString(pProps, szTmp, sizeof(szTmp)), cFrames, cFrames));
+#endif
+            return VINF_SUCCESS;
+        }
+        RTStrFree(pMixBuf->pszName);
+        pMixBuf->pszName = NULL;
+    }
+    pMixBuf->uMagic = AUDIOMIXBUF_MAGIC_DEAD;
+    return VERR_NO_MEMORY;
+}
+
+/**
+ * Destroys (uninitializes) a mixing buffer.
+ *
+ * @param   pMixBuf                 Mixing buffer to destroy.
+ */
+void AudioMixBufDestroy(PAUDIOMIXBUF pMixBuf)
+{
+    if (!pMixBuf)
+        return;
+
+    /* Ignore calls for an uninitialized (zeroed) or already destroyed instance.  Happens a lot. */
+    if (   pMixBuf->uMagic == 0
+        || pMixBuf->uMagic == ~AUDIOMIXBUF_MAGIC)
+    {
+        Assert(!pMixBuf->pszName);
+        Assert(!pMixBuf->pFrames);
+        Assert(!pMixBuf->cFrames);
+        return;
+    }
+
+    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
+    pMixBuf->uMagic = ~AUDIOMIXBUF_MAGIC;
+
+    if (pMixBuf->pszName)
+    {
+        AUDMIXBUF_LOG(("%s\n", pMixBuf->pszName));
+
+        RTStrFree(pMixBuf->pszName);
+        pMixBuf->pszName = NULL;
+    }
+
+    if (pMixBuf->pFrames)
+    {
+        Assert(pMixBuf->cFrames);
+
+        RTMemFree(pMixBuf->pFrames);
+        pMixBuf->pFrames = NULL;
+    }
+
+    pMixBuf->cFrames = 0;
+}
+
+
+/**
+ * Drops all the frames in the given mixing buffer
+ *
+ * This will reset the read and write offsets to zero.
+ *
+ * @param   pMixBuf             The mixing buffer.
+ */
+void AudioMixBufDrop(PAUDIOMIXBUF pMixBuf)
+{
+    AssertPtrReturnVoid(pMixBuf);
+    AssertReturnVoid(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
+
+    AUDMIXBUF_LOG(("%s\n", pMixBuf->pszName));
+
+    pMixBuf->offRead  = 0;
+    pMixBuf->offWrite = 0;
+    pMixBuf->cMixed   = 0;
+    pMixBuf->cUsed    = 0;
+}
+
+
+/**
+ * Gets the maximum number of audio frames this buffer can hold.
+ *
+ * @returns Number of frames.
+ * @param   pMixBuf     The mixing buffer.
+ */
+uint32_t AudioMixBufSize(PCAUDIOMIXBUF pMixBuf)
+{
+    AssertPtrReturn(pMixBuf, 0);
+    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
+    return pMixBuf->cFrames;
+}
+
+
+/**
+ * Gets the maximum number of bytes this buffer can hold.
+ *
+ * @returns Number of bytes.
+ * @param   pMixBuf     The mixing buffer.
+ */
+uint32_t AudioMixBufSizeBytes(PCAUDIOMIXBUF pMixBuf)
+{
+    AssertPtrReturn(pMixBuf, 0);
+    AssertReturn(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC, 0);
+    return AUDIOMIXBUF_F2B(pMixBuf, pMixBuf->cFrames);
+}
+
+
+/**
+ * Worker for AudioMixBufUsed and AudioMixBufUsedBytes.
+ */
+DECLINLINE(uint32_t) audioMixBufUsedInternal(PCAUDIOMIXBUF pMixBuf)
+{
+    uint32_t const cFrames = pMixBuf->cFrames;
+    uint32_t       cUsed   = pMixBuf->cUsed;
+    AssertStmt(cUsed <= cFrames, cUsed = cFrames);
+    return cUsed;
+}
+
+
+/**
+ * Get the number of used (readable) frames in the buffer.
+ *
+ * @returns Number of frames.
+ * @param   pMixBuf     The mixing buffer.
+ */
+uint32_t AudioMixBufUsed(PCAUDIOMIXBUF pMixBuf)
+{
+    AssertPtrReturn(pMixBuf, 0);
+    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
+    return audioMixBufUsedInternal(pMixBuf);
+}
+
+
+/**
+ * Get the number of (readable) bytes in the buffer.
+ *
+ * @returns Number of bytes.
+ * @param   pMixBuf     The mixing buffer.
+ */
+uint32_t AudioMixBufUsedBytes(PCAUDIOMIXBUF pMixBuf)
+{
+    AssertPtrReturn(pMixBuf, 0);
+    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
+    return AUDIOMIXBUF_F2B(pMixBuf, audioMixBufUsedInternal(pMixBuf));
+}
+
+
+/**
+ * Worker for AudioMixBufFree and AudioMixBufFreeBytes.
+ */
+DECLINLINE(uint32_t) audioMixBufFreeInternal(PCAUDIOMIXBUF pMixBuf)
+{
+    uint32_t const cFrames = pMixBuf->cFrames;
+    uint32_t       cUsed   = pMixBuf->cUsed;
+    AssertStmt(cUsed <= cFrames, cUsed = cFrames);
+    uint32_t const cFramesFree = cFrames - cUsed;
+
+    AUDMIXBUF_LOG(("%s: %RU32 of %RU32\n", pMixBuf->pszName, cFramesFree, cFrames));
+    return cFramesFree;
+}
+
+
+/**
+ * Gets the free buffer space in frames.
+ *
+ * @return  Number of frames.
+ * @param   pMixBuf     The mixing buffer.
+ */
+uint32_t AudioMixBufFree(PCAUDIOMIXBUF pMixBuf)
+{
+    AssertPtrReturn(pMixBuf, 0);
+    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
+    return audioMixBufFreeInternal(pMixBuf);
+}
+
+
+/**
+ * Gets the free buffer space in bytes.
+ *
+ * @return  Number of bytes.
+ * @param   pMixBuf     The mixing buffer.
+ */
+uint32_t AudioMixBufFreeBytes(PCAUDIOMIXBUF pMixBuf)
+{
+    AssertPtrReturn(pMixBuf, 0);
+    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
+    return AUDIOMIXBUF_F2B(pMixBuf, audioMixBufFreeInternal(pMixBuf));
+}
+
+
+/**
+ * Checks if the buffer is empty.
+ *
+ * @retval  true if empty buffer.
+ * @retval  false if not empty and there are frames to be processed.
+ * @param   pMixBuf     The mixing buffer.
+ */
+bool AudioMixBufIsEmpty(PCAUDIOMIXBUF pMixBuf)
+{
+    AssertPtrReturn(pMixBuf, true);
+    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
+    return pMixBuf->cUsed == 0;
+}
+
+
+/**
+ * Get the current read position.
+ *
+ * This is for the testcase.
+ *
+ * @returns Frame number.
+ * @param   pMixBuf     The mixing buffer.
+ */
+uint32_t AudioMixBufReadPos(PCAUDIOMIXBUF pMixBuf)
+{
+    AssertPtrReturn(pMixBuf, 0);
+    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
+    return pMixBuf->offRead;
+}
+
+
+/**
+ * Gets the current write position.
+ *
+ * This is for the testcase.
+ *
+ * @returns Frame number.
+ * @param   pMixBuf     The mixing buffer.
+ */
+uint32_t AudioMixBufWritePos(PCAUDIOMIXBUF pMixBuf)
+{
+    AssertPtrReturn(pMixBuf, 0);
+    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
+    return pMixBuf->offWrite;
+}
+
 
 /**
Index: trunk/src/VBox/Devices/Audio/AudioMixBuffer.h
===================================================================
--- trunk/src/VBox/Devices/Audio/AudioMixBuffer.h	(revision 89351)
+++ trunk/src/VBox/Devices/Audio/AudioMixBuffer.h	(revision 89352)
@@ -219,10 +219,4 @@
 /** @} */
 
-
-#ifdef DEBUG
-void AudioMixBufDbgPrint(PAUDIOMIXBUF pMixBuf);
-void AudioMixBufDbgPrintChain(PAUDIOMIXBUF pMixBuf);
-#endif
-
 #endif /* !VBOX_INCLUDED_SRC_Audio_AudioMixBuffer_h */
 
