Index: /trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp	(revision 54459)
+++ /trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp	(revision 54460)
@@ -1,5 +1,6 @@
 /* $Id$ */
 /** @file
- * VBox audio: TODO
+ * VBox audio: Audio mixing buffer for converting reading/writing audio
+ *             samples.
  */
 
@@ -229,5 +230,5 @@
 # define AUDMIXBUF_MACRO_LOG(x) RTPrintf x
 #else
-# define AUDMIXBUF_MACRO_LOG(x)
+# define AUDMIXBUF_MACRO_LOG(x) do {} while (0)
 #endif
 
@@ -342,5 +343,5 @@
                                                   uint32_t *pcDstWritten, uint32_t *pcSrcRead) \
     { \
-        AUDMIXBUF_MACRO_LOG(("pRate=%p, offSrc=%RU32, offDst=%RU64, incDst=%RU64\n", \
+        AUDMIXBUF_MACRO_LOG(("pRate=%p: srcOffset=%RU32, dstOffset=%RU64, dstInc=%RU64\n", \
                              pRate, pRate->srcOffset, pRate->dstOffset, pRate->dstInc)); \
         \
@@ -370,4 +371,7 @@
         uint64_t        l          = 0; \
         \
+        AUDMIXBUF_MACRO_LOG(("Start: paDstEnd=%p - paDstStart=%p -> %zu\n", paDstEnd, paDst, paDstEnd - paDstStart)); \
+        AUDMIXBUF_MACRO_LOG(("Start: paSrcEnd=%p - paSrcStart=%p -> %zu\n", paSrcEnd, paSrc, paSrcEnd - paSrcStart)); \
+        \
         while (paDst < paDstEnd) \
         { \
@@ -377,4 +381,5 @@
             while (pRate->srcOffset <= (pRate->dstOffset >> 32)) \
             { \
+                AUDMIXBUF_MACRO_LOG(("foo1\n")); \
                 samLast = *paSrc++; \
                 pRate->srcOffset++; \
@@ -382,8 +387,7 @@
                 if (paSrc >= paSrcEnd) \
                     break; \
+                    AUDMIXBUF_MACRO_LOG(("foo1.1\n")); \
             } \
-            \
-            if (paSrc >= paSrcEnd) \
-                break; \
+            AUDMIXBUF_MACRO_LOG(("foo2\n")); \
             \
             samCur = *paSrc; \
@@ -405,10 +409,13 @@
             pRate->dstOffset += pRate->dstInc; \
             \
-            AUDMIXBUF_MACRO_LOG(("\t\trate->pos=%RU64\n", pRate->dstOffset)); \
+            AUDMIXBUF_MACRO_LOG(("\t\tpRate->dstOffset=%RU64\n", pRate->dstOffset)); \
         } \
+        \
+        AUDMIXBUF_MACRO_LOG(("End: paDst=%p - paDstStart=%p -> %zu\n", paDst, paDstStart, paDst - paDstStart)); \
+        AUDMIXBUF_MACRO_LOG(("End: paSrc=%p - paSrcStart=%p -> %zu\n", paSrc, paSrcStart, paSrc - paSrcStart)); \
         \
         pRate->srcSampleLast = samLast; \
         \
-        AUDMIXBUF_MACRO_LOG(("l=%RU64, rate->ilast l=%RI64, r=%RI64\n", \
+        AUDMIXBUF_MACRO_LOG(("l=%RU64, pRate->srcSampleLast l=%RI64, r=%RI64\n", \
                               l, pRate->srcSampleLast.u64LSample, pRate->srcSampleLast.u64RSample)); \
         \
@@ -740,9 +747,10 @@
                               ("Buffer is not linked to a parent buffer\n"),
                               0);
+
+    AUDMIXBUF_LOG(("%s: cMixed=%RU32\n", pMixBuf->pszName, pMixBuf->cMixed));
     return pMixBuf->cMixed;
 }
 
-static int audioMixBufMixTo(PPDMAUDIOMIXBUF pDst, PPDMAUDIOMIXBUF pSrc,
-                            uint32_t cSamples, uint32_t *pcProcessed)
+static int audioMixBufMixTo(PPDMAUDIOMIXBUF pDst, PPDMAUDIOMIXBUF pSrc, uint32_t cSamples, uint32_t *pcProcessed)
 {
     AssertPtrReturn(pDst, VERR_INVALID_POINTER);
@@ -780,6 +788,5 @@
 
         cToRead  = cToReadTotal;
-        cToWrite = RT_MIN(cDead,
-                          pDst->cSamples - offWrite);
+        cToWrite = RT_MIN(cDead, pDst->cSamples - offWrite);
         if (!cToWrite)
         {
@@ -796,6 +803,5 @@
         audioMixBufOpBlend(pDst->pSamples + offWrite, cToWrite,
                            pSrc->pSamples + offRead, cToRead,
-                           pSrc->pRate,
-                           &cWritten, &cRead);
+                           pSrc->pRate, &cWritten, &cRead);
 
         AUDMIXBUF_LOG(("\t\tcWritten=%RU32, cRead=%RU32\n", cWritten, cRead));
@@ -817,13 +823,12 @@
 #ifdef DEBUG
     s_cSamplesMixedTotal += cWrittenTotal;
+    audioMixBufPrint(pDst);
 #endif
-
-    audioMixBufPrint(pDst);
 
     if (pcProcessed)
         *pcProcessed = cReadTotal;
 
-    AUDMIXBUF_LOG(("cSrcRead=%RU32, cSrcMixed=%RU32, rc=%Rrc\n",
-                   cReadTotal, pSrc->cMixed, VINF_SUCCESS));
+    AUDMIXBUF_LOG(("cReadTotal=%RU32 (pcProcessed), cWrittenTotal=%RU32, cSrcMixed=%RU32, cDstProc=%RU32\n",
+                   cReadTotal, cWrittenTotal, pSrc->cMixed, pDst->cProcessed));
     return VINF_SUCCESS;
 }
@@ -840,6 +845,5 @@
     RTListForEach(&pMixBuf->lstBuffers, pIter, PDMAUDIOMIXBUF, Node)
     {
-        rc = audioMixBufMixTo(pIter, pMixBuf, cSamples,
-                              &cProcessed);
+        rc = audioMixBufMixTo(pIter, pMixBuf, cSamples, &cProcessed);
         if (RT_FAILURE(rc))
             break;
@@ -861,6 +865,5 @@
                     VERR_INVALID_PARAMETER);
 
-    return audioMixBufMixTo(pMixBuf->pParent, pMixBuf, cSamples,
-                            pcProcessed);
+    return audioMixBufMixTo(pMixBuf->pParent, pMixBuf, cSamples, pcProcessed);
 }
 
Index: /trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp	(revision 54459)
+++ /trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp	(revision 54460)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2014 Oracle Corporation
+ * Copyright (C) 2014-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -133,9 +133,9 @@
 static int tstParentChild(RTTEST hTest)
 {
-    RTTestSubF(hTest, "Child<->Parent");
+    RTTestSubF(hTest, "2 Children -> Parent");
 
     uint32_t cBufSize = _1K;
 
-    PDMAUDIOSTREAMCFG cp =
+    PDMAUDIOSTREAMCFG cfg_p =
     {
         44100,                   /* Hz */
@@ -146,5 +146,5 @@
     PDMPCMPROPS props;
 
-    int rc = drvAudioStreamCfgToProps(&cp, &props);
+    int rc = drvAudioStreamCfgToProps(&cfg_p, &props);
     AssertRC(rc);
 
@@ -152,5 +152,5 @@
     RTTESTI_CHECK_RC_OK(audioMixBufInit(&parent, "Parent", &props, cBufSize));
 
-    PDMAUDIOSTREAMCFG cc =
+    PDMAUDIOSTREAMCFG cfg_c1 = /* Downmixing */
     {
         22100,                   /* Hz */
@@ -160,5 +160,5 @@
     };
 
-    rc = drvAudioStreamCfgToProps(&cc, &props);
+    rc = drvAudioStreamCfgToProps(&cfg_c1, &props);
     AssertRC(rc);
 
@@ -167,4 +167,15 @@
     RTTESTI_CHECK_RC_OK(audioMixBufLinkTo(&child1, &parent));
 
+    PDMAUDIOSTREAMCFG cfg_c2 = /* Upmixing */
+    {
+        48000,                   /* Hz */
+        2                        /* Channels */,
+        AUD_FMT_S16              /* Format */,
+        PDMAUDIOENDIANESS_LITTLE /* Endianess */
+    };
+
+    rc = drvAudioStreamCfgToProps(&cfg_c2, &props);
+    AssertRC(rc);
+
     PDMAUDIOMIXBUF child2;
     RTTESTI_CHECK_RC_OK(audioMixBufInit(&child2, "Child2", &props, cBufSize));
@@ -172,23 +183,36 @@
 
     /*
-     * Writing + mixing from child(s) -> parent, sequential.
-     */
-    int16_t samples16[2] = { 0xAA, 0xBB };
-    uint32_t read = 0, written = 0, proc, mixed = 0;
-
-    RTTESTI_CHECK_RC_OK(audioMixBufWriteAt(&child1, 0, &samples16, sizeof(samples16),
-                                           &written));
-    RTTESTI_CHECK_RC_OK(audioMixBufMixToParent(&child1, written, &mixed));
-    RTTESTI_CHECK(mixed == 1);
-    RTTESTI_CHECK(audioMixBufMixed(&child1) == mixed);
-
-    RTTESTI_CHECK_RC_OK(audioMixBufWriteAt(&child2, 0, &samples16, sizeof(samples16),
-                                           &written));
-    RTTESTI_CHECK_RC_OK(audioMixBufMixToParent(&child2, written, &mixed));
-    RTTESTI_CHECK(mixed == 1);
-    RTTESTI_CHECK(audioMixBufMixed(&child2) == mixed);
+     * Writing + mixing from child/children -> parent, sequential.
+     */
+    size_t cbBuf = _1K;
+    char pvBuf[_1K];
+    int16_t samples16[32] = { 0xAA, 0xBB };
+    uint32_t read , written, proc, mixed;
+
+    uint32_t cSamplesParent1 = 16;
+    uint32_t cSamplesChild1  = 16;
+    uint32_t cSamplesParent2 = 32;
+    uint32_t cSamplesChild2  = 16;
+
+    for (int i = 0; i < 32; i++)
+    {
+        RTTESTI_CHECK_RC_OK(audioMixBufWriteAt(&child1, 0, &samples16, sizeof(samples16), &written));
+        RTTESTI_CHECK(written == cSamplesChild1);
+        RTTESTI_CHECK_RC_OK(audioMixBufMixToParent(&child1, written, &mixed));
+        RTTESTI_CHECK(mixed == cSamplesChild1);
+
+        RTTESTI_CHECK_RC_OK(audioMixBufReadCirc(&parent, pvBuf, cbBuf, &read));
+        RTTESTI_CHECK(read == 31);
+
+        RTTESTI_CHECK_RC_OK(audioMixBufWriteAt(&child2, 0, &samples16, sizeof(samples16), &written));
+        RTTESTI_CHECK(written == cSamplesChild2);
+        RTTESTI_CHECK_RC_OK(audioMixBufMixToParent(&child2, written, &mixed));
+        RTTESTI_CHECK(mixed == cSamplesChild2);
+
+        RTTESTI_CHECK_RC_OK(audioMixBufReadCirc(&parent, pvBuf, cbBuf, &read));
+        RTTESTI_CHECK(read == 15);
+    }
 
     RTTESTI_CHECK(audioMixBufProcessed(&parent) == 0);
-
 
     return RTTestSubErrorCount(hTest) ? VERR_GENERAL_FAILURE : VINF_SUCCESS;
@@ -208,6 +232,6 @@
     RTTestBanner(hTest);
 
-    rc = tstSingle(hTest);
-    if (RT_SUCCESS(rc))
+    /*rc = tstSingle(hTest);
+    if (RT_SUCCESS(rc))*/
         rc = tstParentChild(hTest);
 
