VirtualBox

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


Ignore:
Timestamp:
May 28, 2021 12:59:52 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144679
Message:

AudioMixBuffer: Removed buffer linking and other unnecessary stuff. bugref:9890

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

Legend:

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

    r89314 r89330  
    6464
    6565#ifdef DEBUG
    66 DECLINLINE(void)        audioMixBufDbgPrintInternal(PAUDIOMIXBUF pMixBuf, const char *pszFunc);
    67 DECL_FORCE_INLINE(bool) audioMixBufDbgValidate(PAUDIOMIXBUF pMixBuf);
     66static void audioMixBufDbgPrintInternal(PAUDIOMIXBUF pMixBuf, const char *pszFunc);
     67static bool audioMixBufDbgValidate(PAUDIOMIXBUF pMixBuf);
    6868#endif
    6969
     
    139139
    140140/**
    141  * Returns a mutable pointer to the mixing buffer's audio frame buffer for writing raw
    142  * audio frames.
    143  *
    144  * @returns VBox status code. VINF_TRY_AGAIN for getting next pointer at beginning (circular).
    145  * @param   pMixBuf                 Mixing buffer to acquire audio frames from.
    146  * @param   cFrames                 Number of requested audio frames to write.
    147  * @param   ppvFrames               Returns a mutable pointer to the buffer's audio frame data.
    148  * @param   pcFramesToWrite         Number of available audio frames to write.
    149  *
    150  * @remark  This function is not thread safe!
    151  */
    152 /** @todo r=bird: This isn't a 'ing Peek function, it's a Read function!
    153  *        Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaarg!!!!!!!!!!!!!!!!!!! */
    154 int AudioMixBufPeekMutable(PAUDIOMIXBUF pMixBuf, uint32_t cFrames,
    155                            PPDMAUDIOFRAME *ppvFrames, uint32_t *pcFramesToWrite)
    156 {
    157     AssertPtrReturn(pMixBuf,         VERR_INVALID_POINTER);
    158     AssertPtrReturn(ppvFrames,       VERR_INVALID_POINTER);
    159     AssertPtrReturn(pcFramesToWrite, VERR_INVALID_POINTER);
    160 
    161     int rc;
    162 
    163     if (!cFrames)
    164     {
    165         *pcFramesToWrite = 0;
    166         return VINF_SUCCESS;
    167     }
    168 
    169     uint32_t cFramesToWrite;
    170     if (pMixBuf->offWrite + cFrames > pMixBuf->cFrames)
    171     {
    172         cFramesToWrite = pMixBuf->cFrames - pMixBuf->offWrite;
    173         rc = VINF_TRY_AGAIN;
    174     }
    175     else
    176     {
    177         cFramesToWrite = cFrames;
    178         rc = VINF_SUCCESS;
    179     }
    180 
    181     *ppvFrames = &pMixBuf->pFrames[pMixBuf->offWrite];
    182     AssertPtr(ppvFrames);
    183 
    184     pMixBuf->offWrite = (pMixBuf->offWrite + cFramesToWrite) % pMixBuf->cFrames;
    185     Assert(pMixBuf->offWrite <= pMixBuf->cFrames);
    186     pMixBuf->cUsed += RT_MIN(cFramesToWrite, pMixBuf->cUsed);
    187 
    188     *pcFramesToWrite = cFramesToWrite;
    189 
    190     return rc;
    191 }
    192 
    193 /**
    194141 * Clears the entire frame buffer.
    195142 *
     
    219166
    220167    AssertStmt(cFramesToClear <= pMixBuf->cFrames, cFramesToClear = pMixBuf->cFrames);
    221 
    222 /** @todo r=bird: Why isn't this done when reading/releaseing ? */
    223     PAUDIOMIXBUF pIter;
    224     RTListForEach(&pMixBuf->lstChildren, pIter, AUDIOMIXBUF, Node)
    225     {
    226         AUDMIXBUF_LOG(("\t%s: cMixed=%RU32 -> %RU32\n",
    227                        pIter->pszName, pIter->cMixed, pIter->cMixed - cFramesToClear));
    228 
    229         pIter->cMixed -= RT_MIN(pIter->cMixed, cFramesToClear);
    230         /* Note: Do not increment pIter->cUsed here, as this gets done when reading from that buffer using AudioMixBufReadXXX. */
    231     }
    232168
    233169/** @todo r=bird: waste of time? */
     
    290226    pMixBuf->uMagic = ~AUDIOMIXBUF_MAGIC;
    291227
    292     AudioMixBufUnlink(pMixBuf);
    293 
    294228    if (pMixBuf->pszName)
    295229    {
     
    327261    AssertPtrReturn(pMixBuf, 0);
    328262
    329     uint32_t cFrames, cFramesFree;
    330     if (pMixBuf->pParent)
    331     {
    332         /*
    333          * As a linked child buffer we want to know how many frames
    334          * already have been consumed by the parent.
    335          */
    336         cFrames = pMixBuf->pParent->cFrames;
    337 
    338         Assert(pMixBuf->cMixed <= cFrames);
    339         cFramesFree = cFrames - pMixBuf->cMixed;
    340     }
    341     else /* As a parent. */
    342     {
    343         cFrames     = pMixBuf->cFrames;
    344         Assert(cFrames >= pMixBuf->cUsed);
    345         cFramesFree = pMixBuf->cFrames - pMixBuf->cUsed;
    346     }
     263    uint32_t const cFrames = pMixBuf->cFrames;
     264    uint32_t       cUsed   = pMixBuf->cUsed;
     265    AssertStmt(cUsed <= cFrames, cUsed = cFrames);
     266    uint32_t const cFramesFree = cFrames - cUsed;
    347267
    348268    AUDMIXBUF_LOG(("%s: %RU32 of %RU32\n", pMixBuf->pszName, cFramesFree, cFrames));
     
    12391159
    12401160    pMixBuf->uMagic  = AUDIOMIXBUF_MAGIC;
    1241     pMixBuf->pParent = NULL;
    1242 
    1243     RTListInit(&pMixBuf->lstChildren);
    1244     pMixBuf->cChildren = 0;
    12451161
    12461162    pMixBuf->pFrames = NULL;
     
    12881204
    12891205/**
    1290  * Returns @c true if there are any audio frames available for processing,
    1291  * @c false if not.
    1292  *
    1293  * @return  bool                    @c true if there are any audio frames available for processing, @c false if not.
    1294  * @param   pMixBuf                 Mixing buffer to return value for.
    1295  */
    1296 bool AudioMixBufIsEmpty(PAUDIOMIXBUF pMixBuf)
     1206 * Checks if the buffer is empty.
     1207 *
     1208 * @retval  true if empty buffer.
     1209 * @retval  false if not empty and there are frames to be processed.
     1210 * @param   pMixBuf     The mixing buffer.
     1211 */
     1212bool AudioMixBufIsEmpty(PCAUDIOMIXBUF pMixBuf)
    12971213{
    12981214    AssertPtrReturn(pMixBuf, true);
    1299 
    1300     if (pMixBuf->pParent)
    1301         return (pMixBuf->cMixed == 0);
    1302     return (pMixBuf->cUsed == 0);
    1303 }
    1304 
    1305 /**
    1306  * Calculates the frequency (sample rate) ratio of mixing buffer A in relation to mixing buffer B.
    1307  *
    1308  * @returns Calculated frequency ratio.
    1309  * @param   pMixBufA            First mixing buffer.
    1310  * @param   pMixBufB            Second mixing buffer.
    1311  */
    1312 static int64_t audioMixBufCalcFreqRatio(PAUDIOMIXBUF pMixBufA, PAUDIOMIXBUF pMixBufB)
    1313 {
    1314     int64_t iRatio = (int64_t)((uint64_t)PDMAudioPropsHz(&pMixBufA->Props) << 32) / PDMAudioPropsHz(&pMixBufB->Props);
    1315     AssertStmt(iRatio, iRatio = RT_BIT_64(32) /*1:1*/);
    1316     return iRatio;
    1317 }
    1318 
    1319 /**
    1320  * Links an audio mixing buffer to a parent mixing buffer.
    1321  *
    1322  * A parent mixing buffer can have multiple children mixing buffers [1:N],
    1323  * whereas a child only can have one parent mixing buffer [N:1].
    1324  *
    1325  * The mixing direction always goes from the child/children buffer(s) to the
    1326  * parent buffer.
    1327  *
    1328  * For guest audio output the host backend "owns" the parent mixing buffer, the
    1329  * device emulation "owns" the child/children.
    1330  *
    1331  * The audio format of each mixing buffer can vary; the internal mixing code
    1332  * then will automatically do the (needed) conversion.
    1333  *
    1334  * @returns VBox status code.
    1335  * @param   pMixBuf                 Mixing buffer to link parent to.
    1336  * @param   pParent                 Parent mixing buffer to use for linking.
    1337  *
    1338  * @remark  Circular linking is not allowed.
    1339  */
    1340 int AudioMixBufLinkTo(PAUDIOMIXBUF pMixBuf, PAUDIOMIXBUF pParent)
    1341 {
    1342     AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
    1343     AssertPtrReturn(pParent, VERR_INVALID_POINTER);
    1344 
    1345     AssertMsgReturn(AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->uAudioFmt),
    1346                     ("Parent frame frequency (Hz) not set\n"), VERR_INVALID_PARAMETER);
    1347     AssertMsgReturn(AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->uAudioFmt),
    1348                     ("Buffer sample frequency (Hz) not set\n"), VERR_INVALID_PARAMETER);
    1349     AssertMsgReturn(pMixBuf != pParent,
    1350                     ("Circular linking not allowed\n"), VERR_INVALID_PARAMETER);
    1351 
    1352     if (pMixBuf->pParent) /* Already linked? */
    1353     {
    1354         AUDMIXBUF_LOG(("%s: Already linked to parent '%s'\n",
    1355                        pMixBuf->pszName, pMixBuf->pParent->pszName));
    1356         return VERR_ACCESS_DENIED;
    1357     }
    1358 
    1359     RTListAppend(&pParent->lstChildren, &pMixBuf->Node);
    1360     pParent->cChildren++;
    1361 
    1362     /* Set the parent. */
    1363     pMixBuf->pParent = pParent;
    1364 
    1365     /* Calculate the frequency ratios. */
    1366     pMixBuf->iFreqRatio = audioMixBufCalcFreqRatio(pParent, pMixBuf);
    1367 
    1368     int rc = VINF_SUCCESS;
    1369 #if 0
    1370     uint32_t cFrames = (uint32_t)RT_MIN(  ((uint64_t)pParent->cFrames << 32)
    1371                                          / pMixBuf->iFreqRatio, _64K /* 64K frames max. */);
    1372     if (!cFrames)
    1373         cFrames = pParent->cFrames;
    1374 
    1375     int rc = VINF_SUCCESS;
    1376 
    1377     if (cFrames != pMixBuf->cFrames)
    1378     {
    1379         AUDMIXBUF_LOG(("%s: Reallocating frames %RU32 -> %RU32\n",
    1380                        pMixBuf->pszName, pMixBuf->cFrames, cFrames));
    1381 
    1382         uint32_t cbSamples = cFrames * sizeof(PDMAUDIOSAMPLE);
    1383         Assert(cbSamples);
    1384         pMixBuf->pSamples = (PPDMAUDIOSAMPLE)RTMemRealloc(pMixBuf->pSamples, cbSamples);
    1385         if (!pMixBuf->pSamples)
    1386             rc = VERR_NO_MEMORY;
    1387 
    1388         if (RT_SUCCESS(rc))
    1389         {
    1390             pMixBuf->cFrames = cFrames;
    1391 
    1392             /* Make sure to zero the reallocated buffer so that it can be
    1393              * used properly when blending with another buffer later. */
    1394             RT_BZERO(pMixBuf->pSamples, cbSamples);
    1395         }
    1396     }
    1397 #endif
    1398 
    1399     if (RT_SUCCESS(rc))
    1400     {
    1401         if (!pMixBuf->pRate)
    1402         {
    1403             pMixBuf->pRate = (PAUDIOSTREAMRATE)RTMemAllocZ(sizeof(AUDIOSTREAMRATE));
    1404             AssertReturn(pMixBuf->pRate, VERR_NO_MEMORY);
    1405         }
    1406         else
    1407             RT_BZERO(pMixBuf->pRate, sizeof(AUDIOSTREAMRATE));
    1408 
    1409         /*
    1410          * Some examples to get an idea of what uDstInc holds:
    1411          *   44100 to 44100 -> (44100<<32) / 44100 = 0x01'00000000 (4294967296)
    1412          *   22050 to 44100 -> (22050<<32) / 44100 = 0x00'80000000 (2147483648)
    1413          *   44100 to 22050 -> (44100<<32) / 22050 = 0x02'00000000 (8589934592)
    1414          *   44100 to 48000 -> (44100<<32) / 48000 = 0x00'EB333333 (3946001203.2)
    1415          *   48000 to 44100 -> (48000<<32) / 44100 = 0x01'16A3B35F (4674794335.7823129251700680272109)
    1416          *
    1417          * Note! The iFreqRatio is the same but with the frequencies switched.
    1418          */
    1419         pMixBuf->pRate->uDstInc = ((uint64_t)PDMAudioPropsHz(&pMixBuf->Props) << 32) / PDMAudioPropsHz(&pParent->Props);
    1420 
    1421         AUDMIXBUF_LOG(("%RU32 Hz vs parent %RU32 Hz => iFreqRatio=0x%'RX64 uDstInc=0x%'RX64; cFrames=%RU32 (%RU32 parent); name: %s, parent: %s\n",
    1422                        PDMAudioPropsHz(&pMixBuf->Props), PDMAudioPropsHz(&pParent->Props), pMixBuf->iFreqRatio,
    1423                        pMixBuf->pRate->uDstInc, pMixBuf->cFrames, pParent->cFrames, pMixBuf->pszName, pMixBuf->pParent->pszName));
    1424     }
    1425 
    1426     return rc;
     1215    return pMixBuf->cUsed == 0;
    14271216}
    14281217
     
    14441233    AssertPtrReturn(pMixBuf, 0);
    14451234
    1446 #ifdef RT_STRICT
    1447     uint32_t cFrames;
    1448 #endif
    1449     uint32_t cAvail;
    1450     if (pMixBuf->pParent) /* Is this a child buffer? */
    1451     {
    1452 #ifdef RT_STRICT
    1453         /* Use the frame count from the parent, as
    1454          * pMixBuf->cMixed specifies the frame count
    1455          * in parent frames. */
    1456         cFrames = pMixBuf->pParent->cFrames;
    1457 #endif
    1458         cAvail   = pMixBuf->cMixed;
    1459     }
    1460     else
    1461     {
    1462 #ifdef RT_STRICT
    1463         cFrames = pMixBuf->cFrames;
    1464 #endif
    1465         cAvail   = pMixBuf->cUsed;
    1466     }
    1467 
    1468     Assert(cAvail <= cFrames);
     1235    uint32_t const cFrames = pMixBuf->cFrames;
     1236    uint32_t       cAvail  = pMixBuf->cUsed;
     1237    AssertStmt(cAvail <= cFrames, cAvail = cFrames);
    14691238    return cAvail;
    1470 }
    1471 
    1472 /**
    1473  * Mixes audio frames from a source mixing buffer to a destination mixing buffer.
    1474  *
    1475  * @returns VBox status code.
    1476  *          VERR_BUFFER_UNDERFLOW if the source did not have enough audio data.
    1477  *          VERR_BUFFER_OVERFLOW if the destination did not have enough space to store the converted source audio data.
    1478  *
    1479  * @param   pDst                    Destination mixing buffer.
    1480  * @param   pSrc                    Source mixing buffer.
    1481  * @param   cSrcOff                 Offset of source audio frames to mix.
    1482  * @param   cSrcFrames              Number of source audio frames to mix.
    1483  * @param   pcSrcMixed              Number of source audio frames successfully mixed. Optional.
    1484  */
    1485 static int audioMixBufMixTo(PAUDIOMIXBUF pDst, PAUDIOMIXBUF pSrc, uint32_t cSrcOff, uint32_t cSrcFrames,
    1486                             uint32_t *pcSrcMixed)
    1487 {
    1488     AssertPtrReturn(pDst,  VERR_INVALID_POINTER);
    1489     AssertPtrReturn(pSrc,  VERR_INVALID_POINTER);
    1490     /* pcSrcMixed is optional. */
    1491 
    1492     AssertMsgReturn(pDst == pSrc->pParent, ("Source buffer '%s' is not a child of destination '%s'\n",
    1493                                             pSrc->pszName, pDst->pszName), VERR_INVALID_PARAMETER);
    1494     uint32_t cReadTotal    = 0;
    1495     uint32_t cWrittenTotal = 0;
    1496 
    1497     Assert(pSrc->cMixed <= pDst->cFrames);
    1498 
    1499     Assert(pSrc->cUsed >= pDst->cMixed);
    1500     Assert(pDst->cUsed <= pDst->cFrames);
    1501 
    1502     uint32_t offSrcRead  = cSrcOff;
    1503 
    1504     uint32_t offDstWrite = pDst->offWrite;
    1505     uint32_t cDstMixed   = pSrc->cMixed;
    1506 
    1507     uint32_t cSrcAvail   = RT_MIN(cSrcFrames, pSrc->cUsed);
    1508     uint32_t cDstAvail   = pDst->cFrames - pDst->cUsed; /** @todo Use pDst->cMixed later? */
    1509 
    1510     AUDMIXBUF_LOG(("%s (%RU32 available) -> %s (%RU32 available)\n",
    1511                    pSrc->pszName, cSrcAvail, pDst->pszName, cDstAvail));
    1512 #ifdef DEBUG
    1513     audioMixBufDbgPrintInternal(pDst, __FUNCTION__);
    1514 #endif
    1515 
    1516     if (!cSrcAvail)
    1517         return VERR_BUFFER_UNDERFLOW;
    1518 
    1519     if (!cDstAvail)
    1520         return VERR_BUFFER_OVERFLOW;
    1521 
    1522     uint32_t cSrcToRead = 0;
    1523     uint32_t cSrcRead;
    1524 
    1525     uint32_t cDstToWrite;
    1526     uint32_t cDstWritten;
    1527 
    1528     int rc = VINF_SUCCESS;
    1529 
    1530     while (cSrcAvail && cDstAvail)
    1531     {
    1532         cSrcToRead  = RT_MIN(cSrcAvail, pSrc->cFrames - offSrcRead);
    1533         cDstToWrite = RT_MIN(cDstAvail, pDst->cFrames - offDstWrite);
    1534 
    1535         AUDMIXBUF_LOG(("  Src: %RU32 @ %RU32 -> reading %RU32\n", cSrcAvail, offSrcRead, cSrcToRead));
    1536         AUDMIXBUF_LOG(("  Dst: %RU32 @ %RU32 -> writing %RU32\n", cDstAvail, offDstWrite, cDstToWrite));
    1537 
    1538         if (   !cDstToWrite
    1539             || !cSrcToRead)
    1540         {
    1541             break;
    1542         }
    1543 
    1544         cDstWritten = cSrcRead = 0;
    1545 
    1546         Assert(offSrcRead < pSrc->cFrames);
    1547         Assert(offSrcRead + cSrcToRead <= pSrc->cFrames);
    1548 
    1549         Assert(offDstWrite < pDst->cFrames);
    1550         Assert(offDstWrite + cDstToWrite <= pDst->cFrames);
    1551 
    1552         audioMixBufOpAssign(pDst->pFrames + offDstWrite, cDstToWrite,
    1553                             pSrc->pFrames + offSrcRead,  cSrcToRead,
    1554                             pSrc->pRate, &cDstWritten, &cSrcRead);
    1555 
    1556         cReadTotal    += cSrcRead;
    1557         cWrittenTotal += cDstWritten;
    1558 
    1559         offSrcRead     = (offSrcRead  + cSrcRead)    % pSrc->cFrames;
    1560         offDstWrite    = (offDstWrite + cDstWritten) % pDst->cFrames;
    1561 
    1562         cDstMixed     += cDstWritten;
    1563 
    1564         Assert(cSrcAvail >= cSrcRead);
    1565         cSrcAvail        -= cSrcRead;
    1566 
    1567         Assert(cDstAvail >= cDstWritten);
    1568         cDstAvail        -= cDstWritten;
    1569 
    1570         AUDMIXBUF_LOG(("  %RU32 read (%RU32 left @ %RU32), %RU32 written (%RU32 left @ %RU32)\n",
    1571                        cSrcRead, cSrcAvail, offSrcRead,
    1572                        cDstWritten, cDstAvail, offDstWrite));
    1573     }
    1574 
    1575     pSrc->offRead     = offSrcRead;
    1576     Assert(pSrc->cUsed >= cReadTotal);
    1577     pSrc->cUsed      -= RT_MIN(pSrc->cUsed, cReadTotal);
    1578 
    1579     /* Note: Always count in parent frames, as the rate can differ! */
    1580     pSrc->cMixed      = RT_MIN(cDstMixed, pDst->cFrames);
    1581 
    1582     pDst->offWrite    = offDstWrite;
    1583     Assert(pDst->offWrite <= pDst->cFrames);
    1584     Assert((pDst->cUsed + cWrittenTotal) <= pDst->cFrames);
    1585     pDst->cUsed      += cWrittenTotal;
    1586 
    1587     /* If there are more used frames than fitting in the destination buffer,
    1588      * adjust the values accordingly.
    1589      *
    1590      * This can happen if this routine has been called too often without
    1591      * actually processing the destination buffer in between. */
    1592     if (pDst->cUsed > pDst->cFrames)
    1593     {
    1594         LogFunc(("%s: Warning: Destination buffer used %RU32 / %RU32 frames\n", pDst->pszName, pDst->cUsed, pDst->cFrames));
    1595         pDst->offWrite     = 0;
    1596         pDst->cUsed        = pDst->cFrames;
    1597 
    1598         rc = VERR_BUFFER_OVERFLOW;
    1599     }
    1600 
    1601 #ifdef DEBUG
    1602     audioMixBufDbgValidate(pSrc);
    1603     audioMixBufDbgValidate(pDst);
    1604 
    1605     Assert(pSrc->cMixed <= pDst->cFrames);
    1606 #endif
    1607 
    1608 #ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA
    1609     uint32_t offRead = pDst->offRead;
    1610 
    1611     uint32_t cLeft = cWrittenTotal;
    1612     while (cLeft)
    1613     {
    1614         uint8_t auBuf[256];
    1615         RT_ZERO(auBuf);
    1616 
    1617         Assert(sizeof(auBuf) >= 4);
    1618         Assert(sizeof(auBuf) % 4 == 0);
    1619 
    1620         uint32_t cToRead = RT_MIN(AUDIOMIXBUF_B2F(pDst, sizeof(auBuf)), RT_MIN(cLeft, pDst->cFrames - offRead));
    1621         Assert(cToRead <= pDst->cUsed);
    1622 
    1623         AUDMIXBUFCONVOPTS convOpts;
    1624         RT_ZERO(convOpts);
    1625         convOpts.cFrames = cToRead;
    1626 
    1627         pDst->pfnConvTo(auBuf, pDst->pFrames + offRead, &convOpts);
    1628 
    1629         RTFILE fh;
    1630         int rc2 = RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_mixto.pcm",
    1631                              RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    1632         if (RT_SUCCESS(rc2))
    1633         {
    1634             RTFileWrite(fh, auBuf, AUDIOMIXBUF_F2B(pDst, cToRead), NULL);
    1635             RTFileClose(fh);
    1636         }
    1637 
    1638         offRead  = (offRead + cToRead) % pDst->cFrames;
    1639         cLeft   -= cToRead;
    1640     }
    1641 #endif /* AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA */
    1642 
    1643 #ifdef DEBUG
    1644     audioMixBufDbgPrintInternal(pDst, __FUNCTION__);
    1645 #endif
    1646 
    1647     if (pcSrcMixed)
    1648         *pcSrcMixed = cReadTotal;
    1649 
    1650     AUDMIXBUF_LOG(("cReadTotal=%RU32, cWrittenTotal=%RU32, cSrcMixed=%RU32, cDstUsed=%RU32, rc=%Rrc\n",
    1651                    cReadTotal, cWrittenTotal, pSrc->cMixed, pDst->cUsed, rc));
    1652     return rc;
    1653 }
    1654 
    1655 /**
    1656  * Mixes audio frames down to the parent mixing buffer, extended version.
    1657  *
    1658  * @returns VBox status code. See audioMixBufMixTo() for a more detailed explanation.
    1659  * @param   pMixBuf                 Source mixing buffer to mix to its parent.
    1660  * @param   cSrcOffset              Offset (in frames) of source mixing buffer.
    1661  * @param   cSrcFrames              Number of source audio frames to mix to its parent.
    1662  * @param   pcSrcMixed              Number of source audio frames successfully mixed. Optional.
    1663  */
    1664 int AudioMixBufMixToParentEx(PAUDIOMIXBUF pMixBuf, uint32_t cSrcOffset, uint32_t cSrcFrames, uint32_t *pcSrcMixed)
    1665 {
    1666     AssertMsgReturn(VALID_PTR(pMixBuf->pParent),
    1667                     ("Buffer is not linked to a parent buffer\n"),
    1668                     VERR_INVALID_PARAMETER);
    1669 
    1670     return audioMixBufMixTo(pMixBuf->pParent, pMixBuf, cSrcOffset, cSrcFrames, pcSrcMixed);
    1671 }
    1672 
    1673 /**
    1674  * Mixes audio frames down to the parent mixing buffer.
    1675  *
    1676  * @returns VBox status code. See audioMixBufMixTo() for a more detailed explanation.
    1677  * @param   pMixBuf                 Source mixing buffer to mix to its parent.
    1678  * @param   cSrcFrames              Number of source audio frames to mix to its parent.
    1679  * @param   pcSrcMixed              Number of source audio frames successfully mixed. Optional.
    1680  */
    1681 int AudioMixBufMixToParent(PAUDIOMIXBUF pMixBuf, uint32_t cSrcFrames, uint32_t *pcSrcMixed)
    1682 {
    1683     return audioMixBufMixTo(pMixBuf->pParent, pMixBuf, pMixBuf->offRead, cSrcFrames, pcSrcMixed);
    16841239}
    16851240
     
    16931248 * @param   pMixBuf                 Mixing buffer to print.
    16941249 * @param   pszFunc                 Function name to log this for.
    1695  * @param   fIsParent               Whether this is a parent buffer or not.
    16961250 * @param   uIdtLvl                 Indention level to use.
    16971251 */
    1698 DECL_FORCE_INLINE(void) audioMixBufDbgPrintSingle(PAUDIOMIXBUF pMixBuf, const char *pszFunc, bool fIsParent, uint16_t uIdtLvl)
    1699 {
    1700     Log(("%s: %*s[%s] %s: offRead=%RU32, offWrite=%RU32, cMixed=%RU32 -> %RU32/%RU32\n",
    1701          pszFunc, uIdtLvl * 4, "", fIsParent ? "PARENT" : "CHILD",
     1252static void audioMixBufDbgPrintSingle(PAUDIOMIXBUF pMixBuf, const char *pszFunc, uint16_t uIdtLvl)
     1253{
     1254    Log(("%s: %*s %s: offRead=%RU32, offWrite=%RU32, cMixed=%RU32 -> %RU32/%RU32\n",
     1255         pszFunc, uIdtLvl * 4, "",
    17021256         pMixBuf->pszName, pMixBuf->offRead, pMixBuf->offWrite, pMixBuf->cMixed, pMixBuf->cUsed, pMixBuf->cFrames));
    17031257}
     
    17091263 * @param   pMixBuf                 Mixing buffer to validate.
    17101264 */
    1711 DECL_FORCE_INLINE(bool) audioMixBufDbgValidate(PAUDIOMIXBUF pMixBuf)
     1265static bool audioMixBufDbgValidate(PAUDIOMIXBUF pMixBuf)
    17121266{
    17131267    //const uint32_t offReadEnd  = (pMixBuf->offRead + pMixBuf->cUsed) % pMixBuf->cFrames;
     
    17411295
    17421296/**
    1743  * Internal helper function for audioMixBufPrintChain().
    1744  * Do not use directly.
    1745  *
    1746  * @returns VBox status code.
    1747  * @param   pMixBuf                 Mixing buffer to print.
    1748  * @param   pszFunc                 Function name to print the chain for.
    1749  * @param   uIdtLvl                 Indention level to use.
    1750  * @param   pcChildren              Pointer to children counter.
    1751  */
    1752 DECL_FORCE_INLINE(void) audioMixBufDbgPrintChainHelper(PAUDIOMIXBUF pMixBuf, const char *pszFunc, uint16_t uIdtLvl,
    1753                                                        size_t *pcChildren)
    1754 {
    1755     PAUDIOMIXBUF pIter;
    1756     RTListForEach(&pMixBuf->lstChildren, pIter, AUDIOMIXBUF, Node)
    1757     {
    1758         audioMixBufDbgPrintSingle(pIter, pszFunc, false /* ifIsParent */, uIdtLvl + 1);
    1759         *pcChildren++;
    1760     }
    1761 }
    1762 
    1763 DECL_FORCE_INLINE(void) audioMixBufDbgPrintChainInternal(PAUDIOMIXBUF pMixBuf, const char *pszFunc)
    1764 {
    1765     PAUDIOMIXBUF pParent = pMixBuf->pParent;
    1766     while (pParent)
    1767     {
    1768         if (!pParent->pParent)
    1769             break;
    1770 
    1771         pParent = pParent->pParent;
    1772     }
    1773 
    1774     if (!pParent)
    1775         pParent = pMixBuf;
    1776 
    1777     audioMixBufDbgPrintSingle(pParent, pszFunc, true /* fIsParent */, 0 /* uIdtLvl */);
    1778 
    1779     /* Recursively iterate children. */
    1780     size_t cChildren = 0;
    1781     audioMixBufDbgPrintChainHelper(pParent, pszFunc, 0 /* uIdtLvl */, &cChildren);
    1782 
    1783     Log(("%s: Children: %zu\n", pszFunc, cChildren));
    1784 }
    1785 
    1786 /**
    17871297 * Prints statistics and status of the full chain of a mixing buffer to the logger,
    17881298 * starting from the top root mixing buffer.
     
    17941304void AudioMixBufDbgPrintChain(PAUDIOMIXBUF pMixBuf)
    17951305{
    1796     audioMixBufDbgPrintChainInternal(pMixBuf, __FUNCTION__);
     1306    audioMixBufDbgPrintSingle(pMixBuf, __FUNCTION__, 0 /* uIdtLvl */);
    17971307}
    17981308
    17991309DECL_FORCE_INLINE(void) audioMixBufDbgPrintInternal(PAUDIOMIXBUF pMixBuf, const char *pszFunc)
    18001310{
    1801     PAUDIOMIXBUF pParent = pMixBuf;
    1802     if (pMixBuf->pParent)
    1803         pParent = pMixBuf->pParent;
    1804 
    1805     audioMixBufDbgPrintSingle(pMixBuf, pszFunc, pParent == pMixBuf /* fIsParent */, 0 /* iIdtLevel */);
    1806 
    1807     PAUDIOMIXBUF pIter;
    1808     RTListForEach(&pMixBuf->lstChildren, pIter, AUDIOMIXBUF, Node)
    1809     {
    1810         if (pIter == pMixBuf)
    1811             continue;
    1812         audioMixBufDbgPrintSingle(pIter, pszFunc, false /* fIsParent */, 1 /* iIdtLevel */);
    1813     }
     1311    audioMixBufDbgPrintSingle(pMixBuf, pszFunc, 0 /* iIdtLevel */);
    18141312}
    18151313
     
    29702468
    29712469/**
    2972  * Unlinks a mixing buffer from its parent, if any.
    2973  *
    2974  * @returns VBox status code.
    2975  * @param   pMixBuf                 Mixing buffer to unlink from parent.
    2976  */
    2977 void AudioMixBufUnlink(PAUDIOMIXBUF pMixBuf)
    2978 {
    2979     if (!pMixBuf || !pMixBuf->pszName)
    2980         return;
    2981 
    2982     AUDMIXBUF_LOG(("%s\n", pMixBuf->pszName));
    2983 
    2984     if (pMixBuf->pParent) /* IS this a children buffer? */
    2985     {
    2986         AUDMIXBUF_LOG(("%s: Unlinking from parent \"%s\"\n",
    2987                        pMixBuf->pszName, pMixBuf->pParent->pszName));
    2988 
    2989         RTListNodeRemove(&pMixBuf->Node);
    2990 
    2991         /* Decrease the paren't children count. */
    2992         Assert(pMixBuf->pParent->cChildren);
    2993         pMixBuf->pParent->cChildren--;
    2994 
    2995         /* Make sure to reset the parent mixing buffer each time it gets linked
    2996          * to a new child. */
    2997         AudioMixBufReset(pMixBuf->pParent);
    2998         pMixBuf->pParent = NULL;
    2999     }
    3000 
    3001     PAUDIOMIXBUF pChild, pChildNext;
    3002     RTListForEachSafe(&pMixBuf->lstChildren, pChild, pChildNext, AUDIOMIXBUF, Node)
    3003     {
    3004         AUDMIXBUF_LOG(("\tUnlinking \"%s\"\n", pChild->pszName));
    3005 
    3006         AudioMixBufReset(pChild);
    3007 
    3008         Assert(pChild->pParent == pMixBuf);
    3009         pChild->pParent = NULL;
    3010 
    3011         RTListNodeRemove(&pChild->Node);
    3012 
    3013         /* Decrease the children count. */
    3014         Assert(pMixBuf->cChildren);
    3015         pMixBuf->cChildren--;
    3016     }
    3017 
    3018     Assert(RTListIsEmpty(&pMixBuf->lstChildren));
    3019     Assert(pMixBuf->cChildren == 0);
    3020 
    3021     AudioMixBufReset(pMixBuf);
    3022 
    3023     if (pMixBuf->pRate)
    3024     {
    3025         pMixBuf->pRate->offDst = pMixBuf->pRate->offSrc = 0;
    3026         pMixBuf->pRate->uDstInc = 0;
    3027     }
    3028 
    3029     pMixBuf->iFreqRatio = 1; /* Prevent division by zero. */
    3030 }
    3031 
    3032 /**
    30332470 * Writes audio frames at a specific offset.
    30342471 * The sample format being written must match the format of the mixing buffer.
  • trunk/src/VBox/Devices/Audio/AudioMixBuffer.h

    r89314 r89330  
    220220     * @note This also is known as the distance in ring buffer terms. */
    221221    uint32_t                    cUsed;
    222     /** Number of children mix buffers kept in lstChildren. */
    223     uint32_t                    cChildren;
    224     /** List of children mix buffers to keep in sync with (if being a parent buffer). */
    225     RTLISTANCHOR                lstChildren;
    226     /** Pointer to parent buffer (if any). */
    227     PAUDIOMIXBUF                pParent;
    228222    /** Intermediate structure for buffer conversion tasks. */
    229223    PAUDIOSTREAMRATE            pRate;
     
    315309uint32_t AudioMixBufFree(PAUDIOMIXBUF pMixBuf);
    316310uint32_t AudioMixBufFreeBytes(PAUDIOMIXBUF pMixBuf);
    317 bool AudioMixBufIsEmpty(PAUDIOMIXBUF pMixBuf);
    318 int AudioMixBufLinkTo(PAUDIOMIXBUF pMixBuf, PAUDIOMIXBUF pParent);
     311bool AudioMixBufIsEmpty(PCAUDIOMIXBUF pMixBuf);
    319312uint32_t AudioMixBufLive(PAUDIOMIXBUF pMixBuf);
    320 int AudioMixBufMixToParent(PAUDIOMIXBUF pMixBuf, uint32_t cSrcFrames, uint32_t *pcSrcMixed);
    321 int AudioMixBufMixToParentEx(PAUDIOMIXBUF pMixBuf, uint32_t cSrcOffset, uint32_t cSrcFrames, uint32_t *pcSrcMixed);
    322 int AudioMixBufPeekMutable(PAUDIOMIXBUF pMixBuf, uint32_t cFramesToRead, PPDMAUDIOFRAME *ppvSamples, uint32_t *pcFramesRead);
    323313uint32_t AudioMixBufUsed(PAUDIOMIXBUF pMixBuf);
    324314uint32_t AudioMixBufUsedBytes(PAUDIOMIXBUF pMixBuf);
     
    332322uint32_t AudioMixBufSize(PAUDIOMIXBUF pMixBuf);
    333323uint32_t AudioMixBufSizeBytes(PAUDIOMIXBUF pMixBuf);
    334 void AudioMixBufUnlink(PAUDIOMIXBUF pMixBuf);
    335324int         AudioMixBufWriteAt(PAUDIOMIXBUF pMixBuf, uint32_t offSamples, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
    336325int         AudioMixBufWriteAtEx(PAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps, uint32_t offFrames,
  • trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp

    r88923 r89330  
    307307}
    308308
     309#if 0 /* obsolete */
    309310static int tstParentChild(RTTEST hTest)
    310311{
     
    447448    return RTTestSubErrorCount(hTest) ? VERR_GENERAL_FAILURE : VINF_SUCCESS;
    448449}
    449 
    450 
     450#endif
     451
     452
     453#if 0 /** @todo rewrite to non-parent/child setup */
    451454static void tstDownsampling(RTTEST hTest, uint32_t uFromHz, uint32_t uToHz)
    452455{
     
    547550    AudioMixBufDestroy(&Child);
    548551}
     552#endif
    549553
    550554
     
    654658
    655659
     660#if 0 /** @todo rewrite to non-parent/child setup */
    656661/* Test 8-bit sample conversion (8-bit -> internal -> 8-bit). */
    657662static int tstConversion8(RTTEST hTest)
     
    756761    return RTTestSubErrorCount(hTest) ? VERR_GENERAL_FAILURE : VINF_SUCCESS;
    757762}
    758 
     763#endif
     764
     765#if 0 /** @todo rewrite to non-parent/child setup */
    759766/* Test 16-bit sample conversion (16-bit -> internal -> 16-bit). */
    760767static int tstConversion16(RTTEST hTest)
     
    849856    return RTTestSubErrorCount(hTest) ? VERR_GENERAL_FAILURE : VINF_SUCCESS;
    850857}
    851 
     858#endif
     859
     860#if 0 /** @todo rewrite to non-parent/child setup */
    852861/* Test volume control. */
    853862static int tstVolume(RTTEST hTest)
     
    965974    return RTTestSubErrorCount(hTest) ? VERR_GENERAL_FAILURE : VINF_SUCCESS;
    966975}
     976#endif
    967977
    968978int main(int argc, char **argv)
     
    981991    tstBasics(hTest);
    982992    tstSingle(hTest);
    983     tstParentChild(hTest);
    984     tstConversion8(hTest);
    985     tstConversion16(hTest);
    986     tstVolume(hTest);
     993    //tstParentChild(hTest);
     994    //tstConversion8(hTest);
     995    //tstConversion16(hTest);
     996    //tstVolume(hTest);
     997#if 0 /** @todo rewrite to non-parent/child setup */
    987998    tstDownsampling(hTest, 44100, 22050);
    988999    tstDownsampling(hTest, 48000, 44100);
    9891000    tstDownsampling(hTest, 48000, 22050);
    9901001    tstDownsampling(hTest, 48000, 11000);
     1002#endif
    9911003    tstNewPeek(hTest, 48000, 48000);
    9921004    tstNewPeek(hTest, 48000, 11000);
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