VirtualBox

Changeset 64566 in vbox for trunk


Ignore:
Timestamp:
Nov 4, 2016 12:32:36 PM (8 years ago)
Author:
vboxsync
Message:

Audio/AudioMixer: Implemented AudioMixerSinkIsActive() and AudioMixerSinkReset(). AudioMixerSinkGetReadable() and AudioMixerSinkGetWritable() now return bytes since the last call of AudioMixerSinkUpdate(). AudioMixerSinkWrite() now will return the maximum bytes written by all connected mixer streams.

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

Legend:

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

    r64532 r64566  
    780780# error "Implement me!"
    781781#else
    782     cbReadable = pSink->In.cbReadable;
     782    /* Get the time delta and calculate the bytes that need to be processed.
     783     *
     784     * Example for 16 bit, 44.1KhZ, stereo:
     785     * 16 bits per sample x 44.100 samples per second = 705.600 bits per second x 2 channels
     786     *     = 1.411.200 bits per second of stereo.
     787     */
     788    uint64_t tsDeltaMS  = RTTimeMilliTS() - pSink->tsLastUpdatedMS;
     789
     790    cbReadable = (pSink->PCMProps.cbBitrate / 1000 /* s to ms */) * tsDeltaMS;
     791
     792    Log3Func(("[%s] Bitrate is %RU32 bytes/s -> %RU64ms / %RU32 bytes elapsed\n",
     793              pSink->pszName, pSink->PCMProps.cbBitrate, tsDeltaMS, cbReadable));
    783794#endif
    784795
     
    810821    uint32_t cbWritable;
    811822
     823    if (   !(pSink->fStatus & AUDMIXSINK_STS_RUNNING)
     824        || pSink->fStatus & AUDMIXSINK_STS_PENDING_DISABLE)
     825    {
     826        cbWritable = 0;
     827    }
     828    else
     829    {
    812830#ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF
    813831# error "Implement me!"
    814832#else
    815     cbWritable = pSink->Out.cbWritable;
     833        /* Get the time delta and calculate the bytes that need to be processed.
     834         *
     835         * Example for 16 bit, 44.1KhZ, stereo:
     836         * 16 bits per sample x 44.100 samples per second = 705.600 bits per second x 2 channels
     837         *     = 1.411.200 bits per second of stereo.
     838         */
     839        uint64_t tsDeltaMS  = RTTimeMilliTS() - pSink->tsLastUpdatedMS;
     840
     841        cbWritable = (pSink->PCMProps.cbBitrate / 1000 /* s to ms */) * tsDeltaMS;
     842
     843        Log3Func(("[%s] Bitrate is %RU32 bytes/s -> %RU64ms / %RU32 bytes elapsed\n",
     844                  pSink->pszName, pSink->PCMProps.cbBitrate, tsDeltaMS, cbWritable));
    816845#endif
     846    }
    817847
    818848    Log3Func(("[%s] cbWritable=%RU32\n", pSink->pszName, cbWritable));
     
    896926        return AUDMIXSINK_STS_NONE;
    897927
    898     LogFlowFunc(("[%s]: fStatus=0x%x\n", pSink->pszName, pSink->fStatus));
    899 
    900928    /* If the dirty flag is set, there is unprocessed data in the sink. */
    901929    AUDMIXSINKSTS stsSink = pSink->fStatus;
     
    928956
    929957    return cStreams;
     958}
     959
     960/**
     961 * Returns whether the sink is in an active state or not.
     962 * Note: The pending disable state also counts as active.
     963 *
     964 * @returns True if active, false if not.
     965 * @param   pSink               Sink to return active state for.
     966 */
     967bool AudioMixerSinkIsActive(PAUDMIXSINK pSink)
     968{
     969    if (!pSink)
     970        return false;
     971
     972    int rc2 = RTCritSectEnter(&pSink->CritSect);
     973    if (RT_FAILURE(rc2))
     974        return 0;
     975
     976    bool fIsActive = (pSink->fStatus & AUDMIXSINK_STS_RUNNING);
     977
     978    rc2 = RTCritSectLeave(&pSink->CritSect);
     979    AssertRC(rc2);
     980
     981    return fIsActive;
    930982}
    931983
     
    11841236
    11851237/**
     1238 * Resets a sink. This will immediately stop all processing.
     1239 *
     1240 * @param pSink                 Sink to reset.
     1241 */
     1242void AudioMixerSinkReset(PAUDMIXSINK pSink)
     1243{
     1244    if (!pSink)
     1245        return;
     1246
     1247    int rc2 = RTCritSectEnter(&pSink->CritSect);
     1248    AssertRC(rc2);
     1249
     1250    audioMixerSinkReset(pSink);
     1251
     1252    rc2 = RTCritSectLeave(&pSink->CritSect);
     1253    AssertRC(rc2);
     1254}
     1255
     1256/**
    11861257 * Sets the audio format of a mixer sink.
    11871258 *
     
    12871358    /* Number of detected disabled streams of this sink. */
    12881359    uint8_t cStreamsDisabled = 0;
    1289 
    1290     /* Get the time delta and calculate the bytes that need to be processed. */
    1291     uint64_t tsDeltaMS = RTTimeMilliTS() - pSink->tsLastUpdatedMS;
    1292     uint32_t cbDelta   = (pSink->PCMProps.cbBitrate / 1000 /* s to ms */) * tsDeltaMS;
    1293 
    1294     Log3Func(("[%s] Bitrate is %RU32 bytes/s -> %RU64ms / %RU32 bytes elapsed\n",
    1295               pSink->pszName, pSink->PCMProps.cbBitrate, tsDeltaMS, cbDelta));
    1296 
    1297     if (pSink->enmDir == AUDMIXSINKDIR_INPUT)
    1298     {
    1299         pSink->In.cbReadable  = cbDelta;
    1300     }
    1301     else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT)
    1302     {
    1303         pSink->Out.cbWritable = cbDelta;
    1304     }
    1305 
    1306     uint8_t uCurLUN = 0;
    13071360
    13081361    PAUDMIXSTREAM pMixStream, pMixStreamNext;
     
    13251378                if (RT_FAILURE(rc2))
    13261379                {
    1327                     LogFlowFunc(("%s: Failed capturing stream '%s', rc=%Rrc\n", pSink->pszName, pStream->szName, rc2));
     1380                    LogFunc(("%s: Failed capturing stream '%s', rc=%Rrc\n", pSink->pszName, pStream->szName, rc2));
    13281381                    if (RT_SUCCESS(rc))
    13291382                        rc = rc2;
     
    13391392                if (RT_FAILURE(rc2))
    13401393                {
    1341                     LogFlowFunc(("%s: Failed playing stream '%s', rc=%Rrc\n", pSink->pszName, pStream->szName, rc2));
     1394                    LogFunc(("%s: Failed playing stream '%s', rc=%Rrc\n", pSink->pszName, pStream->szName, rc2));
    13421395                    if (RT_SUCCESS(rc))
    13431396                        rc = rc2;
     
    13541407            if (RT_FAILURE(rc2))
    13551408            {
    1356                 LogFlowFunc(("%s: Failed re-iterating stream '%s', rc=%Rrc\n", pSink->pszName, pStream->szName, rc2));
     1409                LogFunc(("%s: Failed re-iterating stream '%s', rc=%Rrc\n", pSink->pszName, pStream->szName, rc2));
    13571410                if (RT_SUCCESS(rc))
    13581411                    rc = rc2;
     
    13681421                cStreamsDisabled++;
    13691422            }
    1370 
    1371             if (pSink->enmDir == AUDMIXSINKDIR_INPUT)
    1372             {
    1373 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF
    1374 # error "Implement me!"
    1375 #else
    1376                 if (uCurLUN == 0)
    1377                 {
    1378                     pSink->In.cbReadable = pConn->pfnStreamGetReadable(pConn, pStream);
    1379                     Log3Func(("\t%s: cbReadable=%RU32\n", pStream->szName, pSink->In.cbReadable));
    1380                     uCurLUN++;
    1381                 }
    1382 #endif
    1383             }
    1384             else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT)
    1385             {
    1386 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF
    1387 # error "Implement me!"
    1388 #else
    1389                 if (uCurLUN == 0)
    1390                 {
    1391                     pSink->Out.cbWritable = pConn->pfnStreamGetWritable(pConn, pStream);
    1392                     Log3Func(("\t%s: cbWritable=%RU32\n", pStream->szName, pSink->Out.cbWritable));
    1393                     uCurLUN++;
    1394                 }
    1395 #endif
    1396             }
    13971423        }
    13981424
    1399         Log3Func(("\t%s: cProc=%RU32, rc2=%Rrc\n", pStream->szName, cProc, rc2));
     1425        Log3Func(("\t%s: cPlayed/cCaptured=%RU32, rc2=%Rrc\n", pStream->szName, cProc, rc2));
    14001426    }
    14011427
     
    14321458    if (RT_FAILURE(rc))
    14331459        return rc;
    1434 
    1435     /*
    1436      * Note: Hz elapsed     = cTicksElapsed / cTimerTicks
    1437      *       Bytes / second = Sample rate (Hz) * Audio channels * Bytes per sample
    1438      */
    1439 //    uint32_t cSamples = (int)((pSink->PCMProps.cChannels * cTicksElapsed * pSink->PCMProps.uHz + cTimerTicks) / cTimerTicks / pSink->PCMProps.cChannels);
    1440 
    1441 //    LogFlowFunc(("[%s]: cTimerTicks=%RU64, cTicksElapsed=%RU64\n", pSink->pszName, cTimerTicks, cTicksElapsed));
    1442 //    LogFlowFunc(("\t%zuHz elapsed, %RU32 samples (%RU32 bytes)\n", cTicksElapsed / cTimerTicks, cSamples, cSamples << 1));
    14431460
    14441461    rc = audioMixerSinkUpdateInternal(pSink);
     
    15181535        return rc;
    15191536
    1520     AssertMsg(pSink->enmDir == AUDMIXSINKDIR_OUTPUT,
    1521               ("Can't write to a sink which is not an output sink\n"));
     1537    AssertMsg(pSink->fStatus & AUDMIXSINK_STS_RUNNING, ("Can't write to a sink which is not running (anymore)\n"));
     1538    AssertMsg(pSink->enmDir == AUDMIXSINKDIR_OUTPUT,   ("Can't write to a sink which is not an output sink\n"));
    15221539
    15231540    Log3Func(("[%s] enmOp=%d, cbBuf=%RU32\n", pSink->pszName, enmOp, cbBuf));
    15241541
    1525     uint32_t cbProcessed;
     1542    uint32_t cbWritten = 0;
    15261543
    15271544    PAUDMIXSTREAM pMixStream;
     
    15301547        if (!(pMixStream->pConn->pfnStreamGetStatus(pMixStream->pConn, pMixStream->pStream) & PDMAUDIOSTRMSTS_FLAG_ENABLED))
    15311548        {
    1532             Log3Func(("\t%s: Stream '%s' disabled, skipping ...\n", pMixStream->pszName, pMixStream->pStream->szName));
     1549            Log3Func(("\t%s: Stream '%s' disabled, skipping ...\n", pMixStream->pszName, pMixStream->pszName));
    15331550            continue;
    15341551        }
    15351552
     1553        uint32_t cbProcessed = 0;
    15361554        int rc2 = pMixStream->pConn->pfnStreamWrite(pMixStream->pConn, pMixStream->pStream, pvBuf, cbBuf, &cbProcessed);
    15371555        if (RT_FAILURE(rc2))
    1538             LogFlowFunc(("[%s] Failed writing to stream '%s': %Rrc\n", pSink->pszName, pMixStream->pStream->szName, rc2));
     1556            LogFunc(("[%s] Failed writing to stream '%s': %Rrc\n", pSink->pszName, pMixStream->pszName, rc2));
    15391557
    15401558        if (cbProcessed < cbBuf)
     1559            LogFunc(("[%s] Only written %RU32/%RU32 bytes for stream '%s', rc=%Rrc\n",
     1560                     pSink->pszName, cbProcessed, cbBuf, pMixStream->pszName, rc2));
     1561
     1562        if (cbProcessed)
    15411563        {
    1542             Log3Func(("[%s] Only written %RU32/%RU32 bytes for stream '%s'\n",
    1543                       pSink->pszName, cbProcessed, cbBuf, pMixStream->pStream->szName));
     1564            /* Set dirty bit. */
     1565            pSink->fStatus |= AUDMIXSINK_STS_DIRTY;
    15441566        }
    1545     }
    1546 
    1547     if (cbBuf)
    1548     {
    1549         /* Set dirty bit. */
    1550         pSink->fStatus |= AUDMIXSINK_STS_DIRTY;
     1567
     1568        Log3Func(("\t%s: cbProcessed=%RU32\n", pMixStream->pszName, cbBuf, cbProcessed));
     1569
     1570        /*
     1571         * Return the maximum bytes processed by all connected streams.
     1572         * Streams which have processed less than the current maximum have to deal with
     1573         * this themselves.
     1574         */
     1575        cbWritten = RT_MAX(cbWritten, cbProcessed);
    15511576    }
    15521577
    15531578    if (pcbWritten)
    1554         *pcbWritten = cbBuf; /* Always report back a complete write for now. */
     1579        *pcbWritten = cbWritten;
    15551580
    15561581    int rc2 = RTCritSectLeave(&pSink->CritSect);
  • trunk/src/VBox/Devices/Audio/AudioMixer.h

    r63615 r64566  
    232232AUDMIXSINKSTS AudioMixerSinkGetStatus(PAUDMIXSINK pSink);
    233233uint8_t AudioMixerSinkGetStreamCount(PAUDMIXSINK pSink);
     234bool AudioMixerSinkIsActive(PAUDMIXSINK pSink);
    234235int AudioMixerSinkRead(PAUDMIXSINK pSink, AUDMIXOP enmOp, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
    235236void AudioMixerSinkRemoveStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
    236237void AudioMixerSinkRemoveAllStreams(PAUDMIXSINK pSink);
     238void AudioMixerSinkReset(PAUDMIXSINK pSink);
    237239int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PPDMAUDIOPCMPROPS pPCMProps);
    238240int AudioMixerSinkSetVolume(PAUDMIXSINK pSink, PPDMAUDIOVOLUME pVol);
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