VirtualBox

Changeset 57451 in vbox


Ignore:
Timestamp:
Aug 19, 2015 9:39:17 AM (10 years ago)
Author:
vboxsync
Message:

Audio: Try to fix chopped off samples when playing short sound files.

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

Legend:

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

    r57397 r57451  
    214214
    215215    return rc;
     216}
     217
     218/**
     219 * Returns available number of samples for reading.
     220 *
     221 * @return  uint32_t                Number of samples available for reading.
     222 * @param   pMixBuf                 Mixing buffer to return value for.
     223 */
     224uint32_t AudioMixBufAvail(PPDMAUDIOMIXBUF pMixBuf)
     225{
     226    AssertPtrReturn(pMixBuf, true);
     227
     228    uint32_t cAvail;
     229    if (pMixBuf->pParent) /* Child */
     230        cAvail = pMixBuf->cMixed;
     231    else
     232        cAvail = pMixBuf->cProcessed;
     233
     234    Assert(cAvail <= pMixBuf->cSamples);
     235    return cAvail;
    216236}
    217237
     
    932952
    933953/**
    934  * Returns the number of audio samples mixed (processed) from
     954 * Returns the number of audio samples mixed (processed) by
    935955 * the parent mixing buffer.
    936956 *
     
    963983    AssertPtrReturn(pDst, VERR_INVALID_POINTER);
    964984    AssertPtrReturn(pSrc, VERR_INVALID_POINTER);
     985    AssertReturn(cSamples, VERR_INVALID_PARAMETER);
    965986    /* pcProcessed is optional. */
    966987
     
    12641285    AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
    12651286    AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
    1266     AssertReturn(cbBuf, VERR_INVALID_PARAMETER);
    12671287    /* pcbRead is optional. */
    12681288
  • trunk/src/VBox/Devices/Audio/AudioMixBuffer.h

    r57397 r57451  
    5151
    5252int AudioMixBufAcquire(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSamplesToRead, PPDMAUDIOSAMPLE *ppvSamples, uint32_t *pcSamplesRead);
     53uint32_t AudioMixBufAvail(PPDMAUDIOMIXBUF pMixBuf);
    5354inline uint32_t AudioMixBufBytesToSamples(PPDMAUDIOMIXBUF pMixBuf);
    5455void AudioMixBufClear(PPDMAUDIOMIXBUF pMixBuf);
  • trunk/src/VBox/Devices/Audio/DrvAudio.cpp

    r57442 r57451  
    444444                if (RT_SUCCESS(rc))
    445445                {
     446                    Assert(!pHstStrmOut->fPendingDisable);
    446447                    pHstStrmOut->fEnabled = true;
     448                    LogFunc(("[%s] Enabled stream\n", pHstStrmOut->MixBuf.pszName));
    447449                }
    448450                else
    449                     LogFlowFunc(("Backend reported an error when opening output stream, rc=%Rrc\n", rc));
     451                    LogFlowFunc(("[%s] Backend reported an error when opening output stream, rc=%Rrc\n",
     452                                 pHstStrmOut->MixBuf.pszName, rc));
    450453            }
    451454            else
     
    462465                if (RT_SUCCESS(rc))
    463466                {
    464                     pHstStrmOut->fEnabled = false;
     467                    pHstStrmOut->fEnabled        = false;
     468                    pHstStrmOut->fPendingDisable = false;
    465469                    AudioMixBufClear(&pHstStrmOut->MixBuf);
     470
     471                    LogFunc(("[%s] Disabled stream\n", pHstStrmOut->MixBuf.pszName));
    466472                }
    467473                else
    468                     LogFlowFunc(("Backend vetoed closing output stream, rc=%Rrc\n", rc));
     474                    LogFlowFunc(("[%s] Backend vetoed closing output stream, rc=%Rrc\n", pHstStrmOut->MixBuf.pszName, rc));
    469475            }
    470476            else
     
    10151021    if (RT_SUCCESS(rc))
    10161022    {
    1017         /* Return the number of samples which actually have been mixed
     1023        /*
     1024         * Return the number of samples which actually have been mixed
    10181025         * down to the parent, regardless how much samples were written
    1019          * into the children buffer. */
     1026         * into the children buffer.
     1027         */
    10201028        if (pcbWritten)
    10211029            *pcbWritten = AUDIOMIXBUF_S2B(&pGstStrmOut->MixBuf, cMixed);
    10221030    }
    10231031
    1024     LogFlowFunc(("%s -> %s: Written pvBuf=%p, cbBuf=%zu, cWritten=%RU32 (%RU32 bytes), cMixed=%RU32, rc=%Rrc\n",
     1032    LogFlowFunc(("%s -> %s: Written pvBuf=%p, cbBuf=%RU32, cWritten=%RU32 (%RU32 bytes), cMixed=%RU32, rc=%Rrc\n",
    10251033                 pGstStrmOut->MixBuf.pszName, pHstStrmOut->MixBuf.pszName, pvBuf, cbBuf, cWritten,
    10261034                 AUDIOMIXBUF_S2B(&pGstStrmOut->MixBuf, cWritten), cMixed, rc));
     
    11471155    while ((pHstStrmOut = drvAudioHstFindAnyEnabledOut(pThis, pHstStrmOut)))
    11481156    {
    1149         uint32_t cStreamsLive;
    1150         cSamplesLive = drvAudioHstOutSamplesLive(pHstStrmOut, &cStreamsLive);
    1151         if (!cStreamsLive)
    1152             cSamplesLive = 0;
     1157        cSamplesLive = drvAudioHstOutSamplesLive(pHstStrmOut);
    11531158
    11541159        /* Has this stream marked as disabled but there still were guest streams relying
    11551160         * on it? Check if this stream now can be closed and do so, if possible. */
    11561161        if (   pHstStrmOut->fPendingDisable
    1157             && !cStreamsLive)
     1162            && !cSamplesLive)
    11581163        {
    11591164            /* Stop playing the current (pending) stream. */
     
    11911196                                                                AudioMixBufFree(&pGstStrmOut->MixBuf)));
    11921197
    1193                 LogFlowFunc(("\t[%s] cbFree=%RU32\n", pGstStrmOut->MixBuf.pszName, cbFree2));
     1198                //LogFlowFunc(("\t[%s] cbFree=%RU32\n", pGstStrmOut->MixBuf.pszName, cbFree2));
    11941199            }
    11951200        }
     
    12941299            cSamplesPlayedMax = RT_MAX(cSamplesPlayed, cSamplesPlayedMax);
    12951300
    1296         LogFlowFunc(("\t[%s] cSamplesPlayed=%RU32, rc=%Rrc\n", pHstStrmOut->MixBuf.pszName, cSamplesPlayed, rc2));
     1301        LogFlowFunc(("\t[%s] cSamplesPlayed=%RU32, cSamplesPlayedMax=%RU32, rc=%Rrc\n",
     1302                     pHstStrmOut->MixBuf.pszName, cSamplesPlayed, cSamplesPlayedMax, rc2));
    12971303
    12981304        bool fNeedsCleanup = false;
     
    15691575        AssertPtr(pHstStrmOut);
    15701576
    1571         if (pGstStrmOut->State.fActive != fEnable)
     1577        if (pGstStrmOut->State.fActive != fEnable) /* Only process real state changes. */
    15721578        {
    15731579            if (fEnable)
     
    15771583                    rc = drvAudioControlHstOut(pThis, pHstStrmOut, PDMAUDIOSTREAMCMD_ENABLE, 0 /* Flags */);
    15781584            }
    1579             else
     1585            else /* Disable */
    15801586            {
    15811587                if (pHstStrmOut->fEnabled)
     
    15831589                    uint32_t cGstStrmsActive = 0;
    15841590
     1591                    /*
     1592                     * Check if there are any active guest streams assigned
     1593                     * to this host stream which still are being marked as active.
     1594                     *
     1595                     * In that case we have to defer closing the host stream and
     1596                     * wait until all guest streams have been finished.
     1597                     */
    15851598                    PPDMAUDIOGSTSTRMOUT pIter;
    15861599                    RTListForEach(&pHstStrmOut->lstGstStrmOut, pIter, PDMAUDIOGSTSTRMOUT, Node)
    15871600                    {
    15881601                        if (pIter->State.fActive)
     1602                        {
    15891603                            cGstStrmsActive++;
     1604                            break; /* At least one assigned & active guest stream is enough. */
     1605                        }
    15901606                    }
    15911607
     1608                    /* Do we need to defer closing the host stream? */
    15921609                    pHstStrmOut->fPendingDisable = cGstStrmsActive >= 1;
     1610
     1611                    /* Can we close the host stream now instead of deferring it? */
     1612                    if (!pHstStrmOut->fPendingDisable)
     1613                        rc = drvAudioControlHstOut(pThis, pHstStrmOut, PDMAUDIOSTREAMCMD_DISABLE, 0 /* Flags */);
    15931614                }
    15941615            }
     
    15971618                pGstStrmOut->State.fActive = fEnable;
    15981619
    1599             LogFlowFunc(("%s: fEnable=%RTbool, rc=%Rrc\n", pGstStrmOut->MixBuf.pszName, fEnable, rc));
     1620            LogFlowFunc(("%s: fEnable=%RTbool, fPendingDisable=%RTbool, rc=%Rrc\n",
     1621                         pGstStrmOut->MixBuf.pszName, fEnable, pHstStrmOut->fPendingDisable, rc));
    16001622        }
    16011623    }
     
    16211643        LogFlowFunc(("%s: fEnable=%RTbool\n", pGstStrmIn->MixBuf.pszName, fEnable));
    16221644
    1623         if (pGstStrmIn->State.fActive != fEnable)
     1645        if (pGstStrmIn->State.fActive != fEnable) /* Only process real state changes. */
    16241646        {
    16251647            rc = drvAudioControlHstIn(pThis, pHstStrmIn,
  • trunk/src/VBox/Devices/Audio/DrvAudio.h

    r57382 r57451  
    147147void drvAudioClearBuf(PPDMPCMPROPS pPCMInfo, void *pvBuf, size_t cbBuf);
    148148void drvAudioDetachCapture(PPDMAUDIOHSTSTRMOUT pHstStrmOut);
    149 uint32_t drvAudioHstOutSamplesLive(PPDMAUDIOHSTSTRMOUT pHstStrmOut, uint32_t *pcStreamsLive);
     149uint32_t drvAudioHstOutSamplesLive(PPDMAUDIOHSTSTRMOUT pHstStrmOut);
    150150
    151151
  • trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp

    r56648 r57451  
    409409
    410410/**
    411  * Returns the minimum number of live samples already written to all associated
    412  * guest output streams of a specific host output stream.
    413  *
    414  * @return  uint32_t                Minimum number of total live samples already written to all
    415  *                                  associated guest output streams, UINT32_MAX if none found.
    416  * @param   pHstStrmOut             Host output stream to search in.
    417  * @param   pcStreamsLive           Returns the number of live guest streams associated to
    418  *                                  this host output stream. Optional.
    419  */
    420 static uint32_t drvAudioHstOutMinSamplesMixed(PPDMAUDIOHSTSTRMOUT pHstStrmOut, uint32_t *pcStreamsLive)
    421 {
    422     AssertPtrReturn(pHstStrmOut, 0);
    423     /* pcStreamsLive is optional. */
    424 
    425     uint32_t cStreamsLive = 0;
    426     uint32_t cMinSamplesMixed = UINT32_MAX;
    427     uint32_t cSamples;
    428 
    429     PPDMAUDIOGSTSTRMOUT pGstStrmOut;
    430     RTListForEach(&pHstStrmOut->lstGstStrmOut, pGstStrmOut, PDMAUDIOGSTSTRMOUT, Node)
    431     {
    432         if (    pGstStrmOut->State.fActive
    433             || !pGstStrmOut->State.fEmpty)
    434         {
    435             cSamples = AudioMixBufMixed(&pGstStrmOut->MixBuf);
    436             cMinSamplesMixed = RT_MIN(cMinSamplesMixed, cSamples);
    437 
    438             cStreamsLive++;
    439         }
    440     }
    441 
    442     if (pcStreamsLive)
    443         *pcStreamsLive = cStreamsLive;
    444 
    445     return cMinSamplesMixed;
    446 }
    447 
    448 /**
    449  * Finds the number of live (guest) samples of a specific host output stream.
     411 * Finds the number of live samples for a specific output stream.
    450412 *
    451413 * @return  uint32_t                Minimum number of live host output samples processed
    452414 *                                  by all connected guest output streams.
    453415 * @param   pHstStrmOut             Host output stream to search in.
    454  * @param   pcStreamsLive           Number of associated guest live streams. Optional.
    455  */
    456 uint32_t drvAudioHstOutSamplesLive(PPDMAUDIOHSTSTRMOUT pHstStrmOut, uint32_t *pcStreamsLive)
     416 */
     417uint32_t drvAudioHstOutSamplesLive(PPDMAUDIOHSTSTRMOUT pHstStrmOut)
    457418{
    458419    AssertPtrReturn(pHstStrmOut, 0);
    459     /* pcStreamsLive is optional. */
    460 
    461     uint32_t cStreamsLive;
    462     uint32_t cSamplesMin = drvAudioHstOutMinSamplesMixed(pHstStrmOut, &cStreamsLive);
    463 
    464     if (pcStreamsLive)
    465         *pcStreamsLive = cStreamsLive;
    466 
    467     if (cStreamsLive) /* Any live streams at all? */
    468     {
    469         if (   cSamplesMin == UINT32_MAX
    470             || cSamplesMin > AudioMixBufSize(&pHstStrmOut->MixBuf))
    471         {
    472             LogFlowFunc(("Error: cSamplesMin=%RU32\n", cSamplesMin));
    473             return 0;
    474         }
    475 
    476         return cSamplesMin;
    477     }
    478 
    479     return 0;
    480 }
    481 
     420
     421    uint32_t cSamplesLive = AudioMixBufAvail(&pHstStrmOut->MixBuf);
     422
     423    LogFlowFunc(("%s: cStreamsLive=%RU32, cSamplesLive=%RU32\n", pHstStrmOut->MixBuf.pszName, cSamplesLive));
     424    return cSamplesLive;
     425}
     426
  • trunk/src/VBox/Devices/Audio/DrvHostALSAAudio.cpp

    r57427 r57451  
    946946                                                 (uint32_t)cAvail), /* cAvail is always >= 0 */
    947947                                 AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf,
    948                                                  drvAudioHstOutSamplesLive(pHstStrmOut, NULL /* pcStreamsLive */)));
     948                                                 drvAudioHstOutSamplesLive(pHstStrmOut)));
    949949        LogFlowFunc(("cbToRead=%zu, cbAvail=%zu\n",
    950950                     cbToRead, AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, cAvail)));
  • trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp

    r56649 r57451  
    14941494    /* Not much else to do here. */
    14951495
    1496     uint32_t cLive = drvAudioHstOutSamplesLive(pHstStrmOut, NULL /* pcStreamsLive */);
     1496    uint32_t cLive = drvAudioHstOutSamplesLive(pHstStrmOut);
    14971497    if (!cLive) /* Not samples to play? Bail out. */
    14981498    {
  • trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp

    r57398 r57451  
    11601160        }
    11611161
    1162         uint32_t csLive = drvAudioHstOutSamplesLive(pHstStrmOut, NULL /* pcStreamsLive */);
     1162        uint32_t csLive = drvAudioHstOutSamplesLive(pHstStrmOut);
    11631163        uint32_t cbLive = csLive << cShift;
    11641164
  • trunk/src/VBox/Devices/Audio/DrvHostNullAudio.cpp

    r56648 r57451  
    153153
    154154    /* Consume as many samples as would be played at the current frequency since last call. */
    155     uint32_t csLive = drvAudioHstOutSamplesLive(pHstStrmOut, NULL /* pcStreamsLive */);
     155    uint32_t csLive = drvAudioHstOutSamplesLive(pHstStrmOut);
    156156    uint64_t u64TicksNow = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns);
    157157    uint64_t u64TicksElapsed = u64TicksNow  - pNullStrmOut->u64TicksLast;
  • trunk/src/VBox/Devices/Audio/DrvHostOSSAudio.cpp

    r57382 r57451  
    776776        size_t cbBuf = AudioMixBufSizeBytes(&pHstStrmOut->MixBuf);
    777777
    778         uint32_t cLive = drvAudioHstOutSamplesLive(pHstStrmOut,
    779                                                    NULL /* pcStreamsLive */);
     778        uint32_t cLive = drvAudioHstOutSamplesLive(pHstStrmOut);
    780779        uint32_t cToRead;
    781780
  • trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp

    r57358 r57451  
    833833    uint32_t cbReadTotal = 0;
    834834
    835     uint32_t cLive = drvAudioHstOutSamplesLive(pHstStrmOut, NULL /* pcStreamsLive */);
     835    uint32_t cLive = drvAudioHstOutSamplesLive(pHstStrmOut);
    836836    if (!cLive)
    837837    {
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