VirtualBox

Changeset 67365 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Jun 13, 2017 2:17:59 PM (8 years ago)
Author:
vboxsync
Message:

Audio: Forward ported audio mixing buffer changes from 5.1 (as of r115728).

Location:
trunk/src/VBox/Devices/Audio
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp

    r65739 r67365  
    6262
    6363#ifdef DEBUG
    64 DECLINLINE(void) audioMixBufDbgPrintInternal(PPDMAUDIOMIXBUF pMixBuf);
     64DECLINLINE(void)        audioMixBufDbgPrintInternal(PPDMAUDIOMIXBUF pMixBuf, const char *pszFunc);
     65DECL_FORCE_INLINE(bool) audioMixBufDbgValidate(PPDMAUDIOMIXBUF pMixBuf);
    6566#endif
    6667
     
    134135AssertCompile(AUDIOMIXBUF_VOL_0DB == 0x40000000);   /* For now -- when only attenuation is used. */
    135136
    136 #ifdef DEBUG
    137 static uint64_t s_cSamplesMixedTotal = 0;
    138 #endif
    139 
    140137
    141138/**
     
    288285
    289286        pIter->cMixed -= RT_MIN(pIter->cMixed, cSamplesToClear);
    290         pIter->cUsed  -= RT_MIN(pIter->cUsed,  AUDIOMIXBUF_S2S_RATIO(pMixBuf, cSamplesToClear));
     287        /* Note: Do not increment pIter->cUsed here, as this gets done when reading from that buffer using AudioMixBufReadXXX. */
    291288    }
    292289
     
    822819
    823820    pMixBuf->pParent = NULL;
     821
    824822    RTListInit(&pMixBuf->lstChildren);
     823    pMixBuf->cChildren = 0;
    825824
    826825    pMixBuf->pSamples = NULL;
     
    883882
    884883/**
     884 * Calculates the frequency (sample rate) ratio of mixing buffer A in relation to mixing buffer B.
     885 *
     886 * @returns Calculated frequency ratio.
     887 * @param   pMixBufA            First mixing buffer.
     888 * @param   pMixBufB            Second mixing buffer.
     889 */
     890static int64_t audioMixBufCalcFreqRatio(PPDMAUDIOMIXBUF pMixBufA, PPDMAUDIOMIXBUF pMixBufB)
     891{
     892    int64_t iRatio = ((int64_t)AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBufA->AudioFmt) << 32)
     893                   /           AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBufB->AudioFmt);
     894
     895    if (iRatio == 0)      /* Catch division by zero. */
     896        iRatio = 1 << 20; /* Do a 1:1 conversion instead. */
     897
     898    return iRatio;
     899}
     900
     901/**
    885902 * Links an audio mixing buffer to a parent mixing buffer. A parent mixing
    886903 * buffer can have multiple children mixing buffers [1:N], whereas a child only can
     
    922939
    923940    RTListAppend(&pParent->lstChildren, &pMixBuf->Node);
     941    pParent->cChildren++;
     942
     943    /* Set the parent. */
    924944    pMixBuf->pParent = pParent;
    925945
    926     /* Calculate the frequency ratio. */
    927     pMixBuf->iFreqRatio = ((int64_t)AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt) << 32)
    928                         /           AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt);
    929 
    930     if (pMixBuf->iFreqRatio == 0) /* Catch division by zero. */
    931         pMixBuf->iFreqRatio = 1 << 20; /* Do a 1:1 conversion instead. */
     946    /* Calculate the frequency ratios. */
     947    pMixBuf->iFreqRatio = audioMixBufCalcFreqRatio(pParent, pMixBuf);
    932948
    933949    int rc = VINF_SUCCESS;
     
    10441060 * @param   pDst                    Destination mixing buffer.
    10451061 * @param   pSrc                    Source mixing buffer.
     1062 * @param   cSrcOff                 Offset of source audio samples to mix.
    10461063 * @param   cSrcSamples             Number of source audio samples to mix.
    1047  * @param   pcProcessed             Number of audio samples successfully mixed.
    1048  */
    1049 static int audioMixBufMixTo(PPDMAUDIOMIXBUF pDst, PPDMAUDIOMIXBUF pSrc, uint32_t cSrcSamples, uint32_t *pcProcessed)
     1064 * @param   pcSrcMixed              Number of source audio samples successfully mixed. Optional.
     1065 */
     1066static int audioMixBufMixTo(PPDMAUDIOMIXBUF pDst, PPDMAUDIOMIXBUF pSrc, uint32_t cSrcOff, uint32_t cSrcSamples,
     1067                            uint32_t *pcSrcMixed)
    10501068{
    10511069    AssertPtrReturn(pDst,  VERR_INVALID_POINTER);
    10521070    AssertPtrReturn(pSrc,  VERR_INVALID_POINTER);
    1053     /* pcProcessed is optional. */
     1071    /* pcSrcMixed is optional. */
    10541072
    10551073    AssertMsgReturn(pDst == pSrc->pParent, ("Source buffer '%s' is not a child of destination '%s'\n",
     
    10581076    uint32_t cWrittenTotal = 0;
    10591077
    1060     if (pSrc->cMixed >= pDst->cSamples)
    1061     {
    1062         AUDMIXBUF_LOG(("Warning: Destination buffer '%s' full (%RU32 samples max), got %RU32 mixed samples\n",
    1063                        pDst->pszName, pDst->cSamples, pSrc->cMixed));
    1064         if (pcProcessed)
    1065             *pcProcessed = 0;
     1078    Assert(pSrc->cMixed <= pDst->cSamples);
     1079
     1080    Assert(pSrc->cUsed >= pDst->cMixed);
     1081    Assert(pDst->cUsed <= pDst->cSamples);
     1082
     1083    uint32_t offSrcRead  = cSrcOff;
     1084
     1085    uint32_t offDstWrite = pDst->offWrite;
     1086    uint32_t cDstMixed   = pSrc->cMixed;
     1087
     1088    uint32_t cSrcAvail   = RT_MIN(cSrcSamples, pSrc->cUsed);
     1089    uint32_t cDstAvail   = pDst->cSamples - pDst->cUsed; /** @todo Use pDst->cMixed later? */
     1090
     1091    AUDMIXBUF_LOG(("%s (%RU32 available) -> %s (%RU32 available)\n",
     1092                   pSrc->pszName, cSrcAvail, pDst->pszName, cDstAvail));
     1093#ifdef DEBUG
     1094    audioMixBufDbgPrintInternal(pDst, __FUNCTION__);
     1095#endif
     1096
     1097    if (!cSrcAvail)
     1098        return VERR_BUFFER_UNDERFLOW;
     1099
     1100    if (!cDstAvail)
    10661101        return VERR_BUFFER_OVERFLOW;
    1067     }
    1068 
    1069     Assert(pSrc->cUsed >= pDst->cMixed);
    1070 
    1071     uint32_t cSrcAvail  = RT_MIN(cSrcSamples, pSrc->cUsed - pDst->cMixed);
    1072     uint32_t offSrcRead = pSrc->offRead;
    1073     uint32_t cDstMixed  = pSrc->cMixed;
    1074 
    1075     Assert(pDst->cUsed <= pDst->cSamples);
    1076     uint32_t cDstAvail    = pDst->cSamples - pDst->cUsed;
    1077     uint32_t offDstWrite  = pDst->offWrite;
    1078 
    1079     AUDMIXBUF_LOG(("cSrcSamples=%RU32, cSrcAvail=%RU32 -> cDstAvail=%RU32\n", cSrcSamples,  cSrcAvail, cDstAvail));
    1080 
    1081     if (   !cSrcAvail
    1082         || !cDstAvail)
    1083     {
    1084         if (pcProcessed)
    1085             *pcProcessed = 0;
    1086         return VINF_SUCCESS;
    1087     }
    1088 
    1089 #ifdef DEBUG
    1090     audioMixBufDbgPrintInternal(pDst);
    1091 #endif
    10921102
    10931103    uint32_t cSrcToRead = 0;
     
    10991109    int rc = VINF_SUCCESS;
    11001110
    1101     while (   cSrcAvail
    1102            && cDstAvail)
     1111    while (cSrcAvail && cDstAvail)
    11031112    {
    11041113        cSrcToRead  = RT_MIN(cSrcAvail, pSrc->cSamples - offSrcRead);
    11051114        cDstToWrite = RT_MIN(cDstAvail, pDst->cSamples - offDstWrite);
    11061115
    1107         AUDMIXBUF_LOG(("\tSource: %RU32 samples available, %RU32 @ %RU32 -> reading %RU32\n", cSrcAvail, offSrcRead, pSrc->cSamples, cSrcToRead));
    1108         AUDMIXBUF_LOG(("\tDest  : %RU32 samples available, %RU32 @ %RU32 -> writing %RU32\n", cDstAvail, offDstWrite, pDst->cSamples, cDstToWrite));
     1116        AUDMIXBUF_LOG(("\tSource: %RU32 @ %RU32 -> reading %RU32\n", cSrcAvail, offSrcRead, cSrcToRead));
     1117        AUDMIXBUF_LOG(("\tDest  : %RU32 @ %RU32 -> writing %RU32\n", cDstAvail, offDstWrite, cDstToWrite));
     1118
     1119        if (   !cDstToWrite
     1120            || !cSrcToRead)
     1121        {
     1122            break;
     1123        }
    11091124
    11101125        cDstWritten = cSrcRead = 0;
    11111126
    1112         if (   cDstToWrite
    1113             && cSrcToRead)
    1114         {
    1115             Assert(offSrcRead < pSrc->cSamples);
    1116             Assert(offSrcRead + cSrcToRead <= pSrc->cSamples);
    1117 
    1118             Assert(offDstWrite < pDst->cSamples);
    1119             Assert(offDstWrite + cDstToWrite <= pDst->cSamples);
    1120 
    1121             audioMixBufOpAssign(pDst->pSamples + offDstWrite, cDstToWrite,
    1122                                 pSrc->pSamples + offSrcRead,  cSrcToRead,
    1123                                 pSrc->pRate, &cDstWritten, &cSrcRead);
    1124         }
     1127        Assert(offSrcRead < pSrc->cSamples);
     1128        Assert(offSrcRead + cSrcToRead <= pSrc->cSamples);
     1129
     1130        Assert(offDstWrite < pDst->cSamples);
     1131        Assert(offDstWrite + cDstToWrite <= pDst->cSamples);
     1132
     1133        audioMixBufOpAssign(pDst->pSamples + offDstWrite, cDstToWrite,
     1134                            pSrc->pSamples + offSrcRead,  cSrcToRead,
     1135                            pSrc->pRate, &cDstWritten, &cSrcRead);
    11251136
    11261137        cReadTotal    += cSrcRead;
     
    11331144
    11341145        Assert(cSrcAvail >= cSrcRead);
    1135         cSrcAvail     -= cSrcRead;
     1146        cSrcAvail        -= cSrcRead;
     1147
    11361148        Assert(cDstAvail >= cDstWritten);
    1137         cDstAvail     -= cDstWritten;
    1138 
    1139         AUDMIXBUF_LOG(("\t%RU32 read (%RU32 left), %RU32 written (%RU32 left)\n", cSrcRead, cSrcAvail, cDstWritten, cDstAvail));
     1149        cDstAvail        -= cDstWritten;
     1150
     1151        AUDMIXBUF_LOG(("\t%RU32 read (%RU32 left @ %RU32), %RU32 written (%RU32 left @ %RU32)\n",
     1152                       cSrcRead, cSrcAvail, offSrcRead,
     1153                       cDstWritten, cDstAvail, offDstWrite));
    11401154    }
    11411155
    11421156    pSrc->offRead     = offSrcRead;
    11431157    Assert(pSrc->cUsed >= cReadTotal);
    1144     pSrc->cUsed      -= cReadTotal;
     1158    pSrc->cUsed      -= RT_MIN(pSrc->cUsed, cReadTotal);
    11451159
    11461160    /* Note: Always count in parent samples, as the rate can differ! */
     
    11591173    if (pDst->cUsed > pDst->cSamples)
    11601174    {
    1161         LogFunc(("Warning: Destination buffer used %RU32 / %RU32 samples\n", pDst->cUsed, pDst->cSamples));
     1175        LogFunc(("%s: Warning: Destination buffer used %RU32 / %RU32 samples\n", pDst->pszName, pDst->cUsed, pDst->cSamples));
    11621176        pDst->offWrite     = 0;
    11631177        pDst->cUsed        = pDst->cSamples;
     
    11651179        rc = VERR_BUFFER_OVERFLOW;
    11661180    }
    1167     else if (!cSrcToRead && cDstAvail)
    1168     {
    1169         LogFunc(("Warning: Source buffer '%s' ran out of data\n", pSrc->pszName));
    1170         rc = VERR_BUFFER_UNDERFLOW;
    1171     }
    1172     else if (cSrcAvail && !cDstAvail)
    1173     {
    1174         LogFunc(("Warning: Destination buffer '%s' full (%RU32 source samples left)\n", pDst->pszName, cSrcAvail));
    1175         rc = VERR_BUFFER_OVERFLOW;
    1176     }
    11771181
    11781182#ifdef DEBUG
    1179     s_cSamplesMixedTotal += cWrittenTotal;
    1180     audioMixBufDbgPrintInternal(pDst);
    1181 #endif
    1182 
    1183     if (pcProcessed)
    1184         *pcProcessed = cReadTotal;
    1185 
    1186     AUDMIXBUF_LOG(("cReadTotal=%RU32 (pcProcessed), cWrittenTotal=%RU32, cSrcMixed=%RU32, cDstUsed=%RU32, rc=%Rrc\n",
     1183    audioMixBufDbgValidate(pSrc);
     1184    audioMixBufDbgValidate(pDst);
     1185
     1186    Assert(pSrc->cMixed <= pDst->cSamples);
     1187#endif
     1188
     1189#ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
     1190    uint32_t offRead = pDst->offRead;
     1191
     1192    uint32_t cLeft = cWrittenTotal;
     1193    while (cLeft)
     1194    {
     1195        uint8_t auBuf[256];
     1196        RT_ZERO(auBuf);
     1197
     1198        Assert(sizeof(auBuf) >= 4);
     1199        Assert(sizeof(auBuf) % 4 == 0);
     1200
     1201        uint32_t cToRead = RT_MIN(AUDIOMIXBUF_B2S(pDst, sizeof(auBuf)), RT_MIN(cLeft, pDst->cSamples - offRead));
     1202        Assert(cToRead <= pDst->cUsed);
     1203
     1204        PDMAUDMIXBUFCONVOPTS convOpts;
     1205        RT_ZERO(convOpts);
     1206        convOpts.cSamples = cToRead;
     1207
     1208        pDst->pfnConvTo(auBuf, pDst->pSamples + offRead, &convOpts);
     1209
     1210        RTFILE fh;
     1211        int rc2 = RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_mixto.pcm",
     1212                             RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
     1213        if (RT_SUCCESS(rc2))
     1214        {
     1215            RTFileWrite(fh, auBuf, AUDIOMIXBUF_S2B(pDst, cToRead), NULL);
     1216            RTFileClose(fh);
     1217        }
     1218
     1219        offRead  = (offRead + cToRead) % pDst->cSamples;
     1220        cLeft   -= cToRead;
     1221    }
     1222#endif /* AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA */
     1223
     1224#ifdef DEBUG
     1225    audioMixBufDbgPrintInternal(pDst, __FUNCTION__);
     1226#endif
     1227
     1228    if (pcSrcMixed)
     1229        *pcSrcMixed = cReadTotal;
     1230
     1231    AUDMIXBUF_LOG(("cReadTotal=%RU32, cWrittenTotal=%RU32, cSrcMixed=%RU32, cDstUsed=%RU32, rc=%Rrc\n",
    11871232                   cReadTotal, cWrittenTotal, pSrc->cMixed, pDst->cUsed, rc));
    11881233    return rc;
     
    11901235
    11911236/**
    1192  * Mixes audio samples down to the parent mixing buffer.
     1237 * Mixes audio samples down to the parent mixing buffer, extended version.
    11931238 *
    11941239 * @return  IPRT status code. See audioMixBufMixTo() for a more detailed explanation.
    1195  * @param   pMixBuf                 Mixing buffer to mix samples down to parent.
    1196  * @param   cSamples                Number of audio samples of specified mixing buffer to to mix
    1197  *                                  to its attached parent mixing buffer (if any).
    1198  * @param   pcProcessed             Number of audio samples successfully processed. Optional.
    1199  */
    1200 int AudioMixBufMixToParent(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSamples,
    1201                            uint32_t *pcProcessed)
     1240 * @param   pMixBuf                 Source mixing buffer to mix to its parent.
     1241 * @param   cSrcOffset              Offset (in samples) of source mixing buffer.
     1242 * @param   cSrcSamples             Number of source audio samples to mix to its parent.
     1243 * @param   pcSrcMixed              Number of source audio samples successfully mixed. Optional.
     1244 */
     1245int AudioMixBufMixToParentEx(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSrcOffset, uint32_t cSrcSamples, uint32_t *pcSrcMixed)
    12021246{
    12031247    AssertMsgReturn(VALID_PTR(pMixBuf->pParent),
     
    12051249                    VERR_INVALID_PARAMETER);
    12061250
    1207     return audioMixBufMixTo(pMixBuf->pParent, pMixBuf, cSamples, pcProcessed);
     1251    return audioMixBufMixTo(pMixBuf->pParent, pMixBuf, cSrcOffset, cSrcSamples, pcSrcMixed);
     1252}
     1253
     1254/**
     1255 * Mixes audio samples down to the parent mixing buffer.
     1256 *
     1257 * @return  IPRT status code. See audioMixBufMixTo() for a more detailed explanation.
     1258 * @param   pMixBuf                 Source mixing buffer to mix to its parent.
     1259 * @param   cSrcSamples             Number of source audio samples to mix to its parent.
     1260 * @param   pcSrcMixed              Number of source audio samples successfully mixed. Optional.
     1261 */
     1262int AudioMixBufMixToParent(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSrcSamples, uint32_t *pcSrcMixed)
     1263{
     1264    return audioMixBufMixTo(pMixBuf->pParent, pMixBuf, pMixBuf->offRead, cSrcSamples, pcSrcMixed);
    12081265}
    12091266
    12101267#ifdef DEBUG
    1211 
    12121268/**
    12131269 * Prints a single mixing buffer.
     
    12161272 * @return  IPRT status code.
    12171273 * @param   pMixBuf                 Mixing buffer to print.
     1274 * @param   pszFunc                 Function name to log this for.
    12181275 * @param   fIsParent               Whether this is a parent buffer or not.
    12191276 * @param   uIdtLvl                 Indention level to use.
    12201277 */
    1221 DECL_FORCE_INLINE(void) audioMixBufDbgPrintSingle(PPDMAUDIOMIXBUF pMixBuf, bool fIsParent, uint16_t uIdtLvl)
    1222 {
    1223     LogFunc(("%*s[%s] %s: offRead=%RU32, offWrite=%RU32, cMixed=%RU32 -> %RU32/%RU32\n",
    1224              uIdtLvl * 4, "", fIsParent ? "PARENT" : "CHILD",
    1225              pMixBuf->pszName, pMixBuf->offRead, pMixBuf->offWrite, pMixBuf->cMixed, pMixBuf->cUsed, pMixBuf->cSamples));
     1278DECL_FORCE_INLINE(void) audioMixBufDbgPrintSingle(PPDMAUDIOMIXBUF pMixBuf, const char *pszFunc, bool fIsParent, uint16_t uIdtLvl)
     1279{
     1280    Log(("%s: %*s[%s] %s: offRead=%RU32, offWrite=%RU32, cMixed=%RU32 -> %RU32/%RU32\n",
     1281         pszFunc, uIdtLvl * 4, "", fIsParent ? "PARENT" : "CHILD",
     1282         pMixBuf->pszName, pMixBuf->offRead, pMixBuf->offWrite, pMixBuf->cMixed, pMixBuf->cUsed, pMixBuf->cSamples));
     1283}
     1284
     1285/**
     1286 * Validates a single mixing buffer.
     1287 *
     1288 * @return  @true if the buffer state is valid or @false if not.
     1289 * @param   pMixBuf                 Mixing buffer to validate.
     1290 */
     1291DECL_FORCE_INLINE(bool) audioMixBufDbgValidate(PPDMAUDIOMIXBUF pMixBuf)
     1292{
     1293    //const uint32_t offReadEnd  = (pMixBuf->offRead + pMixBuf->cUsed) % pMixBuf->cSamples;
     1294    //const uint32_t offWriteEnd = (pMixBuf->offWrite + (pMixBuf->cSamples - pMixBuf->cUsed)) % pMixBuf->cSamples;
     1295
     1296    bool fValid = true;
     1297
     1298    AssertStmt(pMixBuf->offRead  <= pMixBuf->cSamples, fValid = false);
     1299    AssertStmt(pMixBuf->offWrite <= pMixBuf->cSamples, fValid = false);
     1300    AssertStmt(pMixBuf->cUsed    <= pMixBuf->cSamples, fValid = false);
     1301
     1302    if (pMixBuf->offWrite > pMixBuf->offRead)
     1303    {
     1304        if (pMixBuf->offWrite - pMixBuf->offRead != pMixBuf->cUsed)
     1305            fValid = false;
     1306    }
     1307    else if (pMixBuf->offWrite < pMixBuf->offRead)
     1308    {
     1309        if (pMixBuf->offWrite + pMixBuf->cSamples - pMixBuf->offRead != pMixBuf->cUsed)
     1310            fValid = false;
     1311    }
     1312
     1313    if (!fValid)
     1314    {
     1315        audioMixBufDbgPrintInternal(pMixBuf, __FUNCTION__);
     1316        AssertFailed();
     1317    }
     1318
     1319    return fValid;
    12261320}
    12271321
     
    12321326 * @return  IPRT status code.
    12331327 * @param   pMixBuf                 Mixing buffer to print.
     1328 * @param   pszFunc                 Function name to print the chain for.
    12341329 * @param   uIdtLvl                 Indention level to use.
    12351330 * @param   pcChildren              Pointer to children counter.
    12361331 */
    1237 DECL_FORCE_INLINE(void) audioMixBufDbgPrintChainHelper(PPDMAUDIOMIXBUF pMixBuf, uint16_t uIdtLvl, size_t *pcChildren)
     1332DECL_FORCE_INLINE(void) audioMixBufDbgPrintChainHelper(PPDMAUDIOMIXBUF pMixBuf, const char *pszFunc, uint16_t uIdtLvl,
     1333                                                       size_t *pcChildren)
    12381334{
    12391335    PPDMAUDIOMIXBUF pIter;
    12401336    RTListForEach(&pMixBuf->lstChildren, pIter, PDMAUDIOMIXBUF, Node)
    12411337    {
    1242         audioMixBufDbgPrintSingle(pIter, false /* ifIsParent */, uIdtLvl + 1);
     1338        audioMixBufDbgPrintSingle(pIter, pszFunc, false /* ifIsParent */, uIdtLvl + 1);
    12431339        *pcChildren++;
    12441340    }
    12451341}
    12461342
    1247 DECL_FORCE_INLINE(void) audioMixBufDbgPrintChainInternal(PPDMAUDIOMIXBUF pMixBuf)
     1343DECL_FORCE_INLINE(void) audioMixBufDbgPrintChainInternal(PPDMAUDIOMIXBUF pMixBuf, const char *pszFunc)
    12481344{
    12491345    PPDMAUDIOMIXBUF pParent = pMixBuf->pParent;
     
    12591355        pParent = pMixBuf;
    12601356
    1261     AUDMIXBUF_LOG(("********************************************\n"));
    1262 
    1263     audioMixBufDbgPrintSingle(pParent, true /* fIsParent */, 0 /* uIdtLvl */);
     1357    audioMixBufDbgPrintSingle(pParent, pszFunc, true /* fIsParent */, 0 /* uIdtLvl */);
    12641358
    12651359    /* Recursively iterate children. */
    12661360    size_t cChildren = 0;
    1267     audioMixBufDbgPrintChainHelper(pParent, 0 /* uIdtLvl */, &cChildren);
    1268 
    1269     AUDMIXBUF_LOG(("Children: %zu - Total samples mixed: %RU64\n", cChildren, s_cSamplesMixedTotal));
    1270     AUDMIXBUF_LOG(("********************************************\n"));
     1361    audioMixBufDbgPrintChainHelper(pParent, pszFunc, 0 /* uIdtLvl */, &cChildren);
     1362
     1363    Log(("%s: Children: %zu\n", pszFunc, cChildren));
    12711364}
    12721365
     
    12811374void AudioMixBufDbgPrintChain(PPDMAUDIOMIXBUF pMixBuf)
    12821375{
    1283     audioMixBufDbgPrintChainInternal(pMixBuf);
    1284 }
    1285 
    1286 DECL_FORCE_INLINE(void) audioMixBufDbgPrintInternal(PPDMAUDIOMIXBUF pMixBuf)
     1376    audioMixBufDbgPrintChainInternal(pMixBuf, __FUNCTION__);
     1377}
     1378
     1379DECL_FORCE_INLINE(void) audioMixBufDbgPrintInternal(PPDMAUDIOMIXBUF pMixBuf, const char *pszFunc)
    12871380{
    12881381    PPDMAUDIOMIXBUF pParent = pMixBuf;
     
    12901383        pParent = pMixBuf->pParent;
    12911384
    1292     LogFunc(("***************************************************************************************\n"));
    1293 
    1294     audioMixBufDbgPrintSingle(pMixBuf, pParent == pMixBuf /* fIsParent */, 0 /* iIdtLevel */);
     1385    audioMixBufDbgPrintSingle(pMixBuf, pszFunc, pParent == pMixBuf /* fIsParent */, 0 /* iIdtLevel */);
    12951386
    12961387    PPDMAUDIOMIXBUF pIter;
    1297     RTListForEach(&pParent->lstChildren, pIter, PDMAUDIOMIXBUF, Node)
     1388    RTListForEach(&pMixBuf->lstChildren, pIter, PDMAUDIOMIXBUF, Node)
    12981389    {
    12991390        if (pIter == pMixBuf)
    13001391            continue;
    1301         audioMixBufDbgPrintSingle(pIter, false /* fIsParent */, 1 /* iIdtLevel */);
    1302     }
    1303 
    1304     LogFunc(("***************************************************************************************\n"));
     1392        audioMixBufDbgPrintSingle(pIter, pszFunc, false /* fIsParent */, 1 /* iIdtLevel */);
     1393    }
    13051394}
    13061395
     
    13141403void AudioMixBufDbgPrint(PPDMAUDIOMIXBUF pMixBuf)
    13151404{
    1316     audioMixBufDbgPrintInternal(pMixBuf);
    1317 }
    1318 
     1405    audioMixBufDbgPrintInternal(pMixBuf, __FUNCTION__);
     1406}
    13191407#endif /* DEBUG */
    13201408
     
    14541542{
    14551543    AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
     1544    AssertReturn(cbBuf,      VERR_INVALID_PARAMETER);
    14561545    AssertPtrReturn(pvBuf,   VERR_INVALID_POINTER);
    1457     /* pcbRead is optional. */
    1458 
    1459     if (!cbBuf)
    1460     {
    1461         if (pcRead)
    1462             *pcRead = 0;
    1463         return VINF_SUCCESS;
    1464     }
    1465 
    1466     uint32_t cToRead = RT_MIN(AUDIOMIXBUF_B2S(pMixBuf, cbBuf), pMixBuf->cUsed);
     1546    /* pcRead is optional. */
     1547
     1548    /* Make sure that we at least have space for a full audio sample. */
     1549    AssertReturn(AUDIOMIXBUF_B2S(pMixBuf, cbBuf), VERR_INVALID_PARAMETER);
     1550
     1551    uint32_t cToRead = RT_MIN(pMixBuf->cUsed, AUDIOMIXBUF_B2S(pMixBuf, cbBuf));
    14671552
    14681553    AUDMIXBUF_LOG(("%s: cbBuf=%RU32 (%RU32 samples), cToRead=%RU32, fmtSrc=0x%x, fmtDst=0x%x\n",
     
    14721557    {
    14731558#ifdef DEBUG
    1474         audioMixBufDbgPrintInternal(pMixBuf);
     1559        audioMixBufDbgPrintInternal(pMixBuf, __FUNCTION__);
    14751560#endif
    14761561        if (pcRead)
     
    14911576    }
    14921577
    1493     PPDMAUDIOSAMPLE pSamplesSrc1 = pMixBuf->pSamples + pMixBuf->offRead;
    1494     uint32_t cLenSrc1 = cToRead;
    1495 
    1496     PPDMAUDIOSAMPLE pSamplesSrc2 = NULL;
    1497     uint32_t cLenSrc2 = 0;
    1498 
    1499     /*
    1500      * Do we need to wrap around to read all requested data, that is,
    1501      * starting at the beginning of our circular buffer? This then will
    1502      * be the optional second part to do.
    1503      */
    1504     if ((pMixBuf->offRead + cToRead) > pMixBuf->cSamples)
    1505     {
    1506         Assert(pMixBuf->offRead <= pMixBuf->cSamples);
    1507         cLenSrc1 = pMixBuf->cSamples - pMixBuf->offRead;
    1508 
    1509         pSamplesSrc2 = pMixBuf->pSamples;
    1510         Assert(cToRead >= cLenSrc1);
    1511         cLenSrc2 = RT_MIN(cToRead - cLenSrc1, pMixBuf->cSamples);
    1512     }
    1513 
    1514     PDMAUDMIXBUFCONVOPTS convOpts;
    1515     RT_ZERO(convOpts);
    1516     /* Note: No volume handling/conversion done in the conversion-to macros (yet). */
    1517 
    1518     /* Anything to do at all? */
    1519     int rc = VINF_SUCCESS;
    1520     if (cLenSrc1)
    1521     {
    1522         AssertPtr(pSamplesSrc1);
    1523 
    1524         convOpts.cSamples = cLenSrc1;
    1525 
    1526         AUDMIXBUF_LOG(("P1: offRead=%RU32, cToRead=%RU32\n", pMixBuf->offRead, cLenSrc1));
    1527         pfnConvTo(pvBuf, pSamplesSrc1, &convOpts);
    1528     }
    1529 
    1530     /* Second part present? */
    1531     if (   RT_LIKELY(RT_SUCCESS(rc))
    1532         && cLenSrc2)
    1533     {
    1534         AssertPtr(pSamplesSrc2);
    1535 
    1536         convOpts.cSamples = cLenSrc2;
    1537 
    1538         AUDMIXBUF_LOG(("P2: cToRead=%RU32, offWrite=%RU32 (%zu bytes)\n", cLenSrc2, cLenSrc1,
    1539                        AUDIOMIXBUF_S2B(pMixBuf, cLenSrc1)));
    1540         pfnConvTo((uint8_t *)pvBuf + AUDIOMIXBUF_S2B(pMixBuf, cLenSrc1), pSamplesSrc2, &convOpts);
    1541     }
    1542 
    1543     if (RT_SUCCESS(rc))
    1544     {
     1578    cToRead = RT_MIN(cToRead, pMixBuf->cSamples - pMixBuf->offRead);
     1579    if (cToRead)
     1580    {
     1581        PDMAUDMIXBUFCONVOPTS convOpts;
     1582        RT_ZERO(convOpts);
     1583        convOpts.cSamples = cToRead;
     1584
     1585        AUDMIXBUF_LOG(("cToRead=%RU32\n", cToRead));
     1586
     1587        pfnConvTo(pvBuf, pMixBuf->pSamples + pMixBuf->offRead, &convOpts);
     1588
    15451589#ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
    15461590        RTFILE fh;
    1547         rc = RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_readcirc.pcm",
    1548                         RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    1549         if (RT_SUCCESS(rc))
     1591        int rc2 = RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_readcirc.pcm",
     1592                             RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
     1593        if (RT_SUCCESS(rc2))
    15501594        {
    1551             RTFileWrite(fh, pvBuf, AUDIOMIXBUF_S2B(pMixBuf, cLenSrc1 + cLenSrc2), NULL);
     1595            RTFileWrite(fh, pvBuf, AUDIOMIXBUF_S2B(pMixBuf, cToRead), NULL);
    15521596            RTFileClose(fh);
    15531597        }
    15541598#endif
    15551599        pMixBuf->offRead  = (pMixBuf->offRead + cToRead) % pMixBuf->cSamples;
    1556         Assert(cToRead <= pMixBuf->cUsed);
    1557         pMixBuf->cUsed   -= RT_MIN(cToRead, pMixBuf->cUsed);
    1558 
    1559         if (pcRead)
    1560             *pcRead = cToRead;
    1561     }
     1600        Assert(pMixBuf->cUsed >= cToRead);
     1601        pMixBuf->cUsed   -= cToRead;
     1602    }
     1603
     1604    if (pcRead)
     1605        *pcRead = cToRead;
    15621606
    15631607#ifdef DEBUG
    1564     audioMixBufDbgPrintInternal(pMixBuf);
    1565 #endif
    1566 
    1567     AUDMIXBUF_LOG(("cRead=%RU32 (%RU32 bytes), rc=%Rrc\n", cToRead, AUDIOMIXBUF_S2B(pMixBuf, cToRead), rc));
    1568     return rc;
     1608    audioMixBufDbgValidate(pMixBuf);
     1609#endif
     1610
     1611    AUDMIXBUF_LOG(("cRead=%RU32 (%RU32 bytes)\n", cToRead, AUDIOMIXBUF_S2B(pMixBuf, cToRead)));
     1612    return VINF_SUCCESS;
     1613}
     1614
     1615/**
     1616 * Returns the current read position of a mixing buffer.
     1617 *
     1618 * @returns IPRT status code.
     1619 * @param   pMixBuf                 Mixing buffer to return position for.
     1620 */
     1621uint32_t AudioMixBufReadPos(PPDMAUDIOMIXBUF pMixBuf)
     1622{
     1623    AssertPtrReturn(pMixBuf, 0);
     1624
     1625    return pMixBuf->offRead;
    15691626}
    15701627
     
    16421699    AUDMIXBUF_LOG(("%s\n", pMixBuf->pszName));
    16431700
    1644     if (pMixBuf->pParent)
     1701    if (pMixBuf->pParent) /* IS this a children buffer? */
    16451702    {
    16461703        AUDMIXBUF_LOG(("%s: Unlinking from parent \"%s\"\n",
     
    16481705
    16491706        RTListNodeRemove(&pMixBuf->Node);
     1707
     1708        /* Decrease the paren't children count. */
     1709        Assert(pMixBuf->pParent->cChildren);
     1710        pMixBuf->pParent->cChildren--;
    16501711
    16511712        /* Make sure to reset the parent mixing buffer each time it gets linked
     
    16661727
    16671728        RTListNodeRemove(&pChild->Node);
     1729
     1730        /* Decrease the children count. */
     1731        Assert(pMixBuf->cChildren);
     1732        pMixBuf->cChildren--;
    16681733    }
    16691734
    16701735    Assert(RTListIsEmpty(&pMixBuf->lstChildren));
     1736    Assert(pMixBuf->cChildren == 0);
    16711737
    16721738    AudioMixBufReset(pMixBuf);
     
    16991765/**
    17001766 * Writes audio samples at a specific offset.
     1767 *
     1768 * Note that this operation also modifies the current read and write position
     1769 * to \a offSamples + written samples on success.
    17011770 *
    17021771 * The audio sample format to be written can be different from the audio format
     
    17121781 */
    17131782int AudioMixBufWriteAtEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt,
    1714                          uint32_t offSamples,
    1715                          const void *pvBuf, uint32_t cbBuf,
     1783                         uint32_t offSamples, const void *pvBuf, uint32_t cbBuf,
    17161784                         uint32_t *pcWritten)
    17171785{
    17181786    AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
     1787    AssertReturn(cbBuf,      VERR_INVALID_PARAMETER);
    17191788    AssertPtrReturn(pvBuf,   VERR_INVALID_POINTER);
    1720     /* pcWritten is optional. */
     1789    /* pcbWritten is optional. */
     1790
     1791    if (offSamples >= pMixBuf->cSamples)
     1792    {
     1793        if (pcWritten)
     1794            *pcWritten = 0;
     1795        return VERR_BUFFER_OVERFLOW;
     1796    }
    17211797
    17221798    /*
    17231799     * Adjust cToWrite so we don't overflow our buffers.
    17241800     */
    1725     int rc;
    1726     uint32_t cToWrite = AUDIOMIXBUF_B2S(pMixBuf, cbBuf);
    1727     if (offSamples <= pMixBuf->cSamples)
    1728     {
    1729         if (offSamples + cToWrite <= pMixBuf->cSamples)
    1730             rc = VINF_SUCCESS;
    1731         else
    1732         {
    1733             rc = VINF_BUFFER_OVERFLOW;
    1734             cToWrite = pMixBuf->cSamples - offSamples;
    1735         }
    1736     }
    1737     else
    1738     {
    1739         rc = VINF_BUFFER_OVERFLOW;
    1740         cToWrite = 0;
    1741     }
     1801    uint32_t cToWrite = RT_MIN(AUDIOMIXBUF_B2S(pMixBuf, cbBuf), pMixBuf->cSamples - offSamples);
    17421802
    17431803#ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
     
    17691829        pfnConvFrom = &audioMixBufConvFromSilence;
    17701830
     1831    int rc = VINF_SUCCESS;
     1832
    17711833    uint32_t cWritten;
    17721834    if (   pfnConvFrom
     
    17921854    }
    17931855
    1794 #ifdef DEBUG
    1795     audioMixBufDbgPrintInternal(pMixBuf);
    1796 #endif
    1797 
    17981856    AUDMIXBUF_LOG(("%s: offSamples=%RU32, cbBuf=%RU32, cToWrite=%RU32 (%zu bytes), cWritten=%RU32 (%zu bytes), rc=%Rrc\n",
    17991857                   pMixBuf->pszName, offSamples, cbBuf,
     
    18011859                   cWritten, AUDIOMIXBUF_S2B(pMixBuf, cWritten), rc));
    18021860
    1803     if (RT_SUCCESS(rc) && pcWritten)
    1804         *pcWritten = cWritten;
     1861    if (RT_SUCCESS(rc))
     1862    {
     1863        pMixBuf->offRead  = offSamples % pMixBuf->cSamples;
     1864        pMixBuf->offWrite = (offSamples + cWritten) % pMixBuf->cSamples;
     1865        pMixBuf->cUsed    = cWritten;
     1866        pMixBuf->cMixed   = 0;
     1867
     1868#ifdef DEBUG
     1869        audioMixBufDbgValidate(pMixBuf);
     1870#endif
     1871        if (pcWritten)
     1872            *pcWritten = cWritten;
     1873    }
     1874    else
     1875        AUDMIXBUF_LOG(("%s: Failed with %Rrc\n", pMixBuf->pszName, rc));
    18051876
    18061877    return rc;
     
    18281899/**
    18291900 * Writes audio samples of a specific format.
    1830  *
    1831  * @return  IPRT status code, or VERR_BUFFER_OVERFLOW if samples which not have
    1832  *          been processed yet have been overwritten (due to cyclic buffer).
     1901 * This function might write less data at once than requested.
     1902 *
     1903 * @return  IPRT status code, or VERR_BUFFER_OVERFLOW no space is available for writing anymore.
    18331904 * @param   pMixBuf                 Pointer to mixing buffer to write to.
    18341905 * @param   enmFmt                  Audio format supplied in the buffer.
     
    18511922    }
    18521923
    1853     PPDMAUDIOMIXBUF pParent = pMixBuf->pParent;
    1854 
    1855     AUDMIXBUF_LOG(("%s: enmFmt=0x%x, cbBuf=%RU32 (%RU32 samples)\n",
    1856                    pMixBuf->pszName, enmFmt, cbBuf, AUDIOMIXBUF_B2S(pMixBuf, cbBuf)));
    1857 
    1858     if (   pParent
    1859         && pParent->cSamples < pMixBuf->cMixed)
    1860     {
    1861         if (pcWritten)
    1862             *pcWritten = 0;
    1863 
    1864         AUDMIXBUF_LOG(("%s: Parent buffer '%s' is full\n",
    1865                        pMixBuf->pszName, pMixBuf->pParent->pszName));
    1866 
    1867         return VERR_BUFFER_OVERFLOW;
    1868     }
     1924    /* Make sure that we at least write a full audio sample. */
     1925    AssertReturn(AUDIOMIXBUF_B2S(pMixBuf, cbBuf), VERR_INVALID_PARAMETER);
     1926
     1927    Assert(pMixBuf->cSamples);
     1928    AssertPtr(pMixBuf->pSamples);
    18691929
    18701930    PFNPDMAUDIOMIXBUFCONVFROM pfnConvFrom = NULL;
     
    18851945    }
    18861946
    1887     uint32_t cToWrite = AUDIOMIXBUF_B2S(pMixBuf, cbBuf);
    1888     AssertMsg(cToWrite, ("cToWrite is 0 (cbBuf=%zu)\n", cbBuf));
    1889 
    1890     PPDMAUDIOSAMPLE pSamplesDst1 = pMixBuf->pSamples + pMixBuf->offWrite;
    1891     uint32_t cLenDst1 = cToWrite;
    1892 
    1893     PPDMAUDIOSAMPLE pSamplesDst2 = NULL;
    1894     uint32_t cLenDst2 = 0;
    1895 
    1896     uint32_t cOffWrite = pMixBuf->offWrite + cToWrite;
    1897 
    1898     /*
    1899      * Do we need to wrap around to write all requested data, that is,
    1900      * starting at the beginning of our circular buffer? This then will
    1901      * be the optional second part to do.
    1902      */
    1903     if (cOffWrite >= pMixBuf->cSamples)
    1904     {
     1947    int rc = VINF_SUCCESS;
     1948
     1949    uint32_t cWritten = 0;
     1950
     1951    uint32_t cFree = pMixBuf->cSamples - pMixBuf->cUsed;
     1952    if (cFree)
     1953    {
     1954        if ((pMixBuf->cSamples - pMixBuf->offWrite) == 0)
     1955            pMixBuf->offWrite = 0;
     1956
     1957        uint32_t cToWrite = RT_MIN(AUDIOMIXBUF_B2S(pMixBuf, cbBuf), RT_MIN(pMixBuf->cSamples - pMixBuf->offWrite, cFree));
     1958        Assert(cToWrite);
     1959
     1960        PDMAUDMIXBUFCONVOPTS convOpts;
     1961        RT_ZERO(convOpts);
     1962
     1963        convOpts.From.Volume.fMuted = pMixBuf->Volume.fMuted;
     1964        convOpts.From.Volume.uLeft  = pMixBuf->Volume.uLeft;
     1965        convOpts.From.Volume.uRight = pMixBuf->Volume.uRight;
     1966
     1967        convOpts.cSamples = cToWrite;
     1968
     1969        cWritten = pfnConvFrom(pMixBuf->pSamples + pMixBuf->offWrite,
     1970                               pvBuf, AUDIOMIXBUF_S2B(pMixBuf, cToWrite), &convOpts);
     1971        Assert(cWritten == cToWrite);
     1972
     1973#ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
     1974        RTFILE fh;
     1975        RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_writecirc_ex.pcm",
     1976                   RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
     1977        RTFileWrite(fh, pvBuf, AUDIOMIXBUF_S2B(pMixBuf, cToWrite), NULL);
     1978        RTFileClose(fh);
     1979#endif
     1980        pMixBuf->cUsed   += cWritten;
     1981        Assert(pMixBuf->cUsed <= pMixBuf->cSamples);
     1982
     1983        pMixBuf->offWrite = (pMixBuf->offWrite + cWritten) % pMixBuf->cSamples;
    19051984        Assert(pMixBuf->offWrite <= pMixBuf->cSamples);
    1906         cLenDst1 = pMixBuf->cSamples - pMixBuf->offWrite;
    1907 
    1908         pSamplesDst2 = pMixBuf->pSamples;
    1909         Assert(cToWrite >= cLenDst1);
    1910         cLenDst2 = RT_MIN(cToWrite - cLenDst1, pMixBuf->cSamples);
    1911 
    1912         /* Save new read offset. */
    1913         cOffWrite = cLenDst2;
    1914     }
    1915 
    1916 #ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
    1917     RTFILE fh;
    1918     RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_writecirc_ex.pcm",
    1919                RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    1920 #endif
    1921 
    1922     uint32_t cWrittenTotal = 0;
    1923 
    1924     PDMAUDMIXBUFCONVOPTS convOpts;
    1925     convOpts.From.Volume.fMuted = pMixBuf->Volume.fMuted;
    1926     convOpts.From.Volume.uLeft  = pMixBuf->Volume.uLeft;
    1927     convOpts.From.Volume.uRight = pMixBuf->Volume.uRight;
    1928 
    1929     /* Anything to do at all? */
    1930     if (cLenDst1)
    1931     {
    1932         convOpts.cSamples = cLenDst1;
    1933         cWrittenTotal = pfnConvFrom(pSamplesDst1, pvBuf, AUDIOMIXBUF_S2B(pMixBuf, cLenDst1), &convOpts);
    1934         Assert(cWrittenTotal == cLenDst1);
    1935 
    1936 #ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
    1937         RTFileWrite(fh, pvBuf, AUDIOMIXBUF_S2B(pMixBuf, cLenDst1), NULL);
    1938 #endif
    1939     }
    1940 
    1941     /* Second part present? */
    1942     if (cLenDst2)
    1943     {
    1944         AssertPtr(pSamplesDst2);
    1945 
    1946         convOpts.cSamples = cLenDst2;
    1947         cWrittenTotal += pfnConvFrom(pSamplesDst2,
    1948                                      (uint8_t *)pvBuf + AUDIOMIXBUF_S2B(pMixBuf, cLenDst1),
    1949                                      cbBuf - AUDIOMIXBUF_S2B(pMixBuf, cLenDst1),
    1950                                      &convOpts);
    1951         Assert(cWrittenTotal == cLenDst1 + cLenDst2);
    1952 
    1953 #ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
    1954         RTFileWrite(fh, (uint8_t *)pvBuf + AUDIOMIXBUF_S2B(pMixBuf, cLenDst1),
    1955                     cbBuf - AUDIOMIXBUF_S2B(pMixBuf, cLenDst1), NULL);
    1956 #endif
    1957     }
    1958 
    1959 #ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
    1960     RTFileClose(fh);
    1961 #endif
    1962 
    1963     pMixBuf->offWrite = (pMixBuf->offWrite + cWrittenTotal) % pMixBuf->cSamples;
    1964     pMixBuf->cUsed   += cWrittenTotal;
    1965 
    1966     int rc = VINF_SUCCESS;
    1967 
    1968     if (pMixBuf->cUsed > pMixBuf->cSamples)
    1969     {
    1970         AUDMIXBUF_LOG(("Warning: %RU32 unprocessed samples overwritten\n", pMixBuf->cUsed - pMixBuf->cSamples));
    1971         pMixBuf->cUsed = pMixBuf->cSamples;
    1972 
     1985    }
     1986    else
    19731987        rc = VERR_BUFFER_OVERFLOW;
    1974     }
     1988
     1989#ifdef DEBUG
     1990    audioMixBufDbgPrintInternal(pMixBuf, __FUNCTION__);
     1991    audioMixBufDbgValidate(pMixBuf);
     1992#endif
    19751993
    19761994    if (pcWritten)
    1977         *pcWritten = cWrittenTotal;
    1978 
    1979 #ifdef DEBUG
    1980     audioMixBufDbgPrintInternal(pMixBuf);
    1981 #endif
    1982 
    1983     AUDMIXBUF_LOG(("%s: offWrite=%RU32, cLenDst1=%RU32, cLenDst2=%RU32, cTotal=%RU32 (%zu bytes), rc=%Rrc\n",
    1984                    pMixBuf->pszName, pMixBuf->offWrite, cLenDst1, cLenDst2, cLenDst1 + cLenDst2,
    1985                    AUDIOMIXBUF_S2B(pMixBuf, cLenDst1 + cLenDst2), rc));
     1995        *pcWritten = cWritten;
     1996
     1997    AUDMIXBUF_LOG(("%s: enmFmt=0x%x, cbBuf=%RU32 (%RU32 samples), cWritten=%RU32, rc=%Rrc\n",
     1998                   pMixBuf->pszName, enmFmt, cbBuf, AUDIOMIXBUF_B2S(pMixBuf, cbBuf), cWritten, rc));
    19861999    return rc;
    19872000}
    19882001
     2002/**
     2003 * Returns the current write position of a mixing buffer.
     2004 *
     2005 * @returns IPRT status code.
     2006 * @param   pMixBuf                 Mixing buffer to return position for.
     2007 */
     2008uint32_t AudioMixBufWritePos(PPDMAUDIOMIXBUF pMixBuf)
     2009{
     2010    AssertPtrReturn(pMixBuf, 0);
     2011
     2012    return pMixBuf->offWrite;
     2013}
     2014
  • trunk/src/VBox/Devices/Audio/AudioMixBuffer.h

    r65739 r67365  
    55
    66/*
    7  * Copyright (C) 2014-2016 Oracle Corporation
     7 * Copyright (C) 2014-2017 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5959int AudioMixBufLinkTo(PPDMAUDIOMIXBUF pMixBuf, PPDMAUDIOMIXBUF pParent);
    6060uint32_t AudioMixBufLive(PPDMAUDIOMIXBUF pMixBuf);
    61 int AudioMixBufMixToParent(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSamples, uint32_t *pcProcessed);
     61int AudioMixBufMixToParent(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSrcSamples, uint32_t *pcSrcMixed);
     62int AudioMixBufMixToParentEx(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSrcOffset, uint32_t cSrcSamples, uint32_t *pcSrcMixed);
    6263int AudioMixBufPeek(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSamplesToRead, PPDMAUDIOSAMPLE paSampleBuf, uint32_t cSampleBuf, uint32_t *pcSamplesRead);
    6364int AudioMixBufPeekMutable(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSamplesToRead, PPDMAUDIOSAMPLE *ppvSamples, uint32_t *pcSamplesRead);
     
    6768int AudioMixBufReadCirc(PPDMAUDIOMIXBUF pMixBuf, void *pvBuf, uint32_t cbBuf, uint32_t *pcRead);
    6869int AudioMixBufReadCircEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt, void *pvBuf, uint32_t cbBuf, uint32_t *pcRead);
     70uint32_t AudioMixBufReadPos(PPDMAUDIOMIXBUF pMixBuf);
    6971void AudioMixBufReset(PPDMAUDIOMIXBUF pMixBuf);
    7072void AudioMixBufSetVolume(PPDMAUDIOMIXBUF pMixBuf, PPDMAUDIOVOLUME pVol);
     
    7678int AudioMixBufWriteCirc(PPDMAUDIOMIXBUF pMixBuf, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
    7779int AudioMixBufWriteCircEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
     80uint32_t AudioMixBufWritePos(PPDMAUDIOMIXBUF pMixBuf);
    7881
    7982#ifdef DEBUG
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette