VirtualBox

Changeset 73569 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 8, 2018 3:20:23 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
124206
Message:

Audio/DrvAudio: Use capturing mixing buffers the same way as the playback ones: The child buffer (host side) is being used as intermediate buffer for conversion, whereas the parent buffer (guest side) will act as the actual ring buffer for the device emulation. For playback it's the other way around.

File:
1 edited

Legend:

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

    r73559 r73569  
    11231123    do
    11241124    {
    1125         uint32_t cfMixed = 0;
    1126 
    11271125        rc = pThis->pHostDrvAudio->pfnStreamIterate(pThis->pHostDrvAudio, pStream->pvBackend);
    11281126        if (RT_FAILURE(rc))
    11291127            break;
    11301128
    1131         if (pStream->enmDir == PDMAUDIODIR_IN)
    1132         {
    1133             /* Has the host captured any frames which were not mixed to the guest side yet? */
    1134             uint32_t cfCaptured = AudioMixBufUsed(&pStream->Host.MixBuf);
    1135             if (cfCaptured)
    1136             {
    1137                 /* When capturing frames, the guest is the parent while the host is the child.
    1138                  * So try mixing not yet mixed host-side frames to the guest-side buffer. */
    1139                 rc = AudioMixBufMixToParent(&pStream->Host.MixBuf, cfCaptured, &cfMixed);
    1140                 if (RT_FAILURE(rc))
    1141                 {
    1142                     if (rc == VERR_BUFFER_OVERFLOW)
    1143                         LogRel2(("Audio: Guest input stream '%s' full\n", pStream->szName));
    1144                     else
    1145                         LogRel2(("Audio: Mixing to guest input stream '%s' failed: %Rrc\n", pStream->szName, rc));
    1146 #ifdef DEBUG_andy_disabled
    1147                     AssertFailed();
    1148 #endif
    1149                 }
    1150 
    1151 #ifdef VBOX_WITH_STATISTICS
    1152                 STAM_COUNTER_ADD(&pThis->Stats.TotalFramesMixedIn, cfMixed);
    1153                 Assert(cfCaptured >= cfMixed);
    1154                 STAM_COUNTER_ADD(&pThis->Stats.TotalFramesLostIn,  cfCaptured - cfMixed);
    1155 #endif
    1156                 Log3Func(("[%s] %RU32/%RU32 input frames mixed, rc=%Rrc\n", pStream->szName, cfMixed, cfCaptured, rc));
    1157             }
    1158             else
    1159             {
    1160                 /* No audio frames to transfer host to the guest (anymore)?
    1161                  * Then try closing this stream if marked so in the next block. */
    1162                 fTryClosePending = true;
    1163             }
    1164         }
    1165         else if (pStream->enmDir == PDMAUDIODIR_OUT)
     1129        if (pStream->enmDir == PDMAUDIODIR_OUT)
    11661130        {
    11671131            /* No audio frames to transfer from guest to host (anymore)?
     
    11711135            Log3Func(("[%s] fTryClosePending=%RTbool, cfLive=%RU32\n", pStream->szName, fTryClosePending, cfLive));
    11721136        }
    1173         else
    1174             AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
    11751137
    11761138        /* Has the host stream marked as pending to disable?
     
    16661628        else if (cbCaptured)
    16671629        {
    1668             if (pThis->In.Cfg.Dbg.fEnabled)
    1669                 DrvAudioHlpFileWrite(pStream->In.Dbg.pFileCaptureNonInterleaved, auBuf, cbCaptured, 0 /* fFlags */);
    1670 
    16711630            Assert(cbCaptured <= cbBuf);
    16721631            if (cbCaptured > cbBuf) /* Paranoia. */
    16731632                cbCaptured = (uint32_t)cbBuf;
    16741633
    1675             uint32_t cfCaptured = 0;
    1676             rc = AudioMixBufWriteCirc(&pStream->Host.MixBuf, auBuf, cbCaptured, &cfCaptured);
    1677             if (RT_SUCCESS(rc))
    1678                 cfCapturedTotal += cfCaptured;
     1634            /* We use the host side mixing buffer as an intermediate buffer to do some
     1635             * (first) processing (if needed), so always write the incoming data at offset 0. */
     1636            uint32_t cfHstWritten = 0;
     1637            rc = AudioMixBufWriteAt(&pStream->Host.MixBuf, 0 /* offFrames */, auBuf, cbCaptured, &cfHstWritten);
     1638            if (   RT_FAILURE(rc)
     1639                || !cfHstWritten)
     1640            {
     1641                AssertMsgFailed(("[%s] Write failed: cbCaptured=%RU32, cfHstWritten=%RU32, rc=%Rrc\n",
     1642                                 pStream->szName, cbCaptured, cfHstWritten, rc));
     1643                break;
     1644            }
     1645
     1646            if (pThis->In.Cfg.Dbg.fEnabled)
     1647                DrvAudioHlpFileWrite(pStream->In.Dbg.pFileCaptureNonInterleaved, auBuf, cbCaptured, 0 /* fFlags */);
     1648
     1649            uint32_t cfHstMixed = 0;
     1650            if (cfHstWritten)
     1651            {
     1652                int rc2 = AudioMixBufMixToParentEx(&pStream->Host.MixBuf, 0 /* cSrcOffset */, cfHstWritten /* cSrcFrames */,
     1653                                                   &cfHstMixed /* pcSrcMixed */);
     1654                Log3Func(("[%s] cbCaptured=%RU32, cfWritten=%RU32, cfMixed=%RU32, rc=%Rrc\n",
     1655                          pStream->szName, cbCaptured, cfHstWritten, cfHstMixed, rc2));
     1656                AssertRC(rc2);
     1657            }
     1658
     1659            cfCapturedTotal += cfHstMixed;
    16791660        }
    16801661        else /* Nothing captured -- bail out. */
     
    17991780    uint32_t cfCaptured = 0;
    18001781
     1782#ifdef LOG_ENABLED
     1783    char *pszStreamSts = dbgAudioStreamStatusToStr(pStream->fStatus);
     1784    Log3Func(("[%s] fStatus=%s\n", pStream->szName, pszStreamSts));
     1785    RTStrFree(pszStreamSts);
     1786#endif /* LOG_ENABLED */
     1787
    18011788    do
    18021789    {
    18031790        if (!pThis->pHostDrvAudio)
     1791        {
     1792            rc = VERR_AUDIO_STREAM_NOT_READY;
    18041793            break;
    1805 
    1806         /*
    1807          * Check if the backend is ready to operate.
    1808          */
    1809 
    1810         PDMAUDIOSTREAMSTS stsStream = pStream->fStatus;
    1811 #ifdef LOG_ENABLED
    1812         char *pszStreamSts = dbgAudioStreamStatusToStr(stsStream);
    1813         Log3Func(("[%s] Start: fStatus=%s\n", pStream->szName, pszStreamSts));
    1814         RTStrFree(pszStreamSts);
    1815 #endif /* LOG_ENABLED */
    1816         if (!(stsStream & PDMAUDIOSTREAMSTS_FLAG_ENABLED)) /* Stream disabled? Bail out. */
     1794        }
     1795
     1796        if (   !pThis->In.fEnabled
     1797            || !DrvAudioHlpStreamStatusCanRead(pStream->fStatus))
     1798        {
     1799            rc = VERR_AUDIO_STREAM_NOT_READY;
    18171800            break;
     1801        }
    18181802
    18191803        /*
     
    18381822            pThis->pHostDrvAudio->pfnStreamCaptureEnd(pThis->pHostDrvAudio, pStream->pvBackend);
    18391823
    1840 #ifdef LOG_ENABLED
    1841         pszStreamSts = dbgAudioStreamStatusToStr(stsStream);
    1842         Log3Func(("[%s] End: fStatus=%s, cfCaptured=%RU32, rc=%Rrc\n",
    1843                   pStream->szName, pszStreamSts, cfCaptured, rc));
    1844         RTStrFree(pszStreamSts);
    1845 #endif /* LOG_ENABLED */
    1846 
    18471824        if (RT_SUCCESS(rc))
    18481825        {
     
    18501827
    18511828#ifdef VBOX_WITH_STATISTICS
    1852             STAM_COUNTER_ADD(&pThis->Stats.TotalFramesIn,        cfCaptured);
     1829            STAM_COUNTER_ADD(&pThis->Stats.TotalFramesIn,       cfCaptured);
    18531830            STAM_COUNTER_ADD(&pStream->In.Stats.FramesCaptured, cfCaptured);
    18541831#endif
     
    23182295    do
    23192296    {
    2320         if (!pThis->In.fEnabled)
    2321         {
    2322             /* If the stream is not enabled, return silence. */
    2323             DrvAudioHlpClearBuf(&pStream->Guest.Cfg.Props, pvBuf, cbBuf,
    2324                                 PDMAUDIOPCMPROPS_B2F(&pStream->Guest.Cfg.Props, cbBuf));
    2325             cbReadTotal = cbBuf;
     2297        if (   !pThis->In.fEnabled
     2298            || !DrvAudioHlpStreamStatusCanRead(pStream->fStatus))
     2299        {
     2300            rc = VERR_AUDIO_STREAM_NOT_READY;
    23262301            break;
    23272302        }
     
    23312306            && pThis->pHostDrvAudio->pfnGetStatus(pThis->pHostDrvAudio, PDMAUDIODIR_IN) != PDMAUDIOBACKENDSTS_RUNNING)
    23322307        {
    2333             rc = VERR_NOT_AVAILABLE;
     2308            rc = VERR_AUDIO_STREAM_NOT_READY;
    23342309            break;
    23352310        }
     
    23412316        uint32_t cfReadTotal = 0;
    23422317
    2343         uint32_t cfToRead = RT_MIN(AUDIOMIXBUF_B2F(&pStream->Guest.MixBuf, cbBuf), AudioMixBufUsed(&pStream->Guest.MixBuf));
     2318        uint32_t cfToRead = RT_MIN(AUDIOMIXBUF_B2F(&pStream->Guest.MixBuf, cbBuf), AudioMixBufLive(&pStream->Guest.MixBuf));
    23442319        while (cfToRead)
    23452320        {
     
    27722747    AssertMsg(pStream->enmDir == PDMAUDIODIR_IN, ("Can't read from a non-input stream\n"));
    27732748
    2774     const uint32_t cfReadable = AudioMixBufLive(&pStream->Guest.MixBuf);
    2775 
    2776     Log3Func(("[%s] cfReadable=%RU32 (%zu bytes)\n", pStream->szName, cfReadable,
    2777               AUDIOMIXBUF_F2B(&pStream->Guest.MixBuf, cfReadable)));
    2778 
    2779     uint32_t cbReadable = AUDIOMIXBUF_F2B(&pStream->Guest.MixBuf, cfReadable);
     2749    uint32_t cbReadable = 0;
     2750
     2751    if (DrvAudioHlpStreamStatusCanRead(pStream->fStatus))
     2752    {
     2753        const uint32_t cfReadable = AudioMixBufLive(&pStream->Guest.MixBuf);
     2754
     2755        Log3Func(("[%s] cfReadable=%RU32 (%zu bytes)\n", pStream->szName, cfReadable,
     2756                  AUDIOMIXBUF_F2B(&pStream->Guest.MixBuf, cfReadable)));
     2757
     2758        cbReadable = AUDIOMIXBUF_F2B(&pStream->Guest.MixBuf, cfReadable);
     2759    }
    27802760
    27812761    rc2 = RTCritSectLeave(&pThis->CritSect);
Note: See TracChangeset for help on using the changeset viewer.

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