VirtualBox

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


Ignore:
Timestamp:
Dec 18, 2015 2:27:15 PM (9 years ago)
Author:
vboxsync
Message:

DevSB16.cpp: Use the time at the start of the sb16TimerIO callback when rescheduling it. Use the TMTimerGet* functions instead of the PDMDevHlp variants. Some documentation amendments. Use newly introduced RTLISTNODER3 to avoid padding unions in cross context code.

File:
1 edited

Legend:

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

    r58983 r59188  
    8787typedef struct SB16DRIVER
    8888{
    89     union
    90     {
    91         /** Node for storing this driver in our device driver
    92          *  list of SB16STATE. */
    93         RTLISTNODE                     Node;
    94         struct
    95         {
    96             R3PTRTYPE(void *)          dummy1;
    97             R3PTRTYPE(void *)          dummy2;
    98         } dummy;
    99     };
    100 
     89    /** Node for storing this driver in our device driver list of SB16STATE. */
     90    RTLISTNODER3                       Node;
    10191    /** Pointer to SB16 controller (state). */
    10292    R3PTRTYPE(PSB16STATE)              pSB16State;
     
    180170    R3PTRTYPE(PAUDMIXSINK)         pSinkOutput;
    181171#ifndef VBOX_WITH_AUDIO_CALLBACKS
    182     /** The emulation timer for handling I/O of the attached LUN drivers. */
     172    /** The timer for pumping data thru the attached LUN drivers. */
    183173    PTMTIMERR3                     pTimerIO;
    184     /** Timer ticks for handling the LUN drivers. */
    185     uint64_t                       uTimerTicksIO;
    186     /** Timestamp (delta) since last timer call. */
     174    /** The timer interval for pumping data thru the LUN drivers in timer ticks. */
     175    uint64_t                       cTimerTicksIO;
     176    /** Timestamp of the last timer callback (sb16TimerIO).
     177     * Used to calculate the time actually elapsed between two timer callbacks. */
    187178    uint64_t                       uTimerTSIO;
    188179#endif
     
    16521643static DECLCALLBACK(void) sb16TimerIO(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
    16531644{
    1654     PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE);
    1655     AssertPtrReturnVoid(pThis);
     1645    PSB16STATE pThis = (PSB16STATE)pvUser;
     1646    Assert(pThis == PDMINS_2_DATA(pDevIns, PSB16STATE));
     1647    AssertPtr(pThis);
    16561648
    16571649    int rc = VINF_SUCCESS;
     
    16621654    PSB16DRIVER pDrv;
    16631655
    1664     uint32_t cbIn, cbOut;
    1665 
    1666     uint64_t uTicksNow     = PDMDevHlpTMTimeVirtGet(pDevIns);
    1667     uint64_t uTicksElapsed = uTicksNow  - pThis->uTimerTSIO;
    1668     uint64_t uTicksPerSec  = PDMDevHlpTMTimeVirtGetFreq(pDevIns);
    1669 
    1670     pThis->uTimerTSIO = uTicksNow;
     1656    uint64_t cTicksNow     = TMTimerGet(pTimer);
     1657    uint64_t cTicksElapsed = cTicksNow  - pThis->uTimerTSIO;
     1658    uint64_t cTicksPerSec  = TMTimerGetFreq(pTimer);
     1659
     1660    pThis->uTimerTSIO = cTicksNow;
    16711661
    16721662    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
    16731663    {
    1674         cbIn = cbOut = 0;
     1664        uint32_t cbIn = 0;
     1665        uint32_t cbOut = 0;
     1666
    16751667        rc = pDrv->pConnector->pfnQueryStatus(pDrv->pConnector,
    16761668                                              &cbIn, &cbOut, NULL /* cSamplesLive */);
     
    16781670            rc = pDrv->pConnector->pfnPlayOut(pDrv->pConnector, NULL /* cSamplesPlayed */);
    16791671
    1680         uint32_t cSamplesMin  = (int)((2 * uTicksElapsed * pDrv->Out.pStrmOut->Props.uHz + uTicksPerSec) / uTicksPerSec / 2);
    1681         uint32_t cbSamplesMin = AUDIOMIXBUF_S2B(&pDrv->Out.pStrmOut->MixBuf, cSamplesMin);
    1682 
    1683         LogFlowFunc(("LUN#%RU8: rc=%Rrc, cbOut=%RU32, cSamplesMin=%RU32, cbSamplesMin=%RU32\n",
    1684                      pDrv->uLUN, rc, cbOut, cSamplesMin, cbSamplesMin));
    1685 
     1672        Log2Func(("LUN#%RU8: rc=%Rrc, cbIn=%RU32, cbOut=%RU32\n", pDrv->uLUN, rc, cbIn, cbOut));
     1673
     1674        const bool fIsActiveOut = pDrv->pConnector->pfnIsActiveOut(pDrv->pConnector, pDrv->Out.pStrmOut);
     1675
     1676        /* If we there was an error handling (available) output or there simply is no output available,
     1677         * then calculate the minimum data rate which must be processed by the device emulation in order
     1678         * to function correctly.
     1679         *
     1680         * This is not the optimal solution, but as we have to deal with this on a timer-based approach
     1681         * (until we have the audio callbacks) we need to have device' DMA engines running. */
    16861682        if (   RT_FAILURE(rc)
    1687             && cbSamplesMin > cbOut)
     1683            || !fIsActiveOut)
    16881684        {
    1689             LogFlowFunc(("LUN#%RU8: Adj: %RU32 -> %RU32\n", pDrv->uLUN, cbOut, cbSamplesMin));
    1690             cbOut = cbSamplesMin;
     1685            uint32_t cSamplesMin  = (int)((2 * cTicksElapsed * pDrv->Out.pStrmOut->Props.uHz + cTicksPerSec) / cTicksPerSec / 2);
     1686            uint32_t cbSamplesMin = AUDIOMIXBUF_S2B(&pDrv->Out.pStrmOut->MixBuf, cSamplesMin);
     1687
     1688            Log2Func(("\trc=%Rrc, cSamplesMin=%RU32, cbSamplesMin=%RU32\n", rc, cSamplesMin, cbSamplesMin));
     1689
     1690            cbOut = RT_MAX(cbOut, cbSamplesMin);
    16911691        }
    16921692
     
    16951695    }
    16961696
    1697 #ifdef DEBUG_TIMER
    1698     LogFlowFunc(("cbInMax=%RU32, cbOutMin=%RU32\n", cbInMax, cbOutMin));
    1699 #endif
     1697    Log2Func(("cbInMax=%RU32, cbOutMin=%RU32\n", cbInMax, cbOutMin));
    17001698
    17011699    if (cbOutMin == UINT32_MAX)
     
    17181716    /** @todo Implement recording. */
    17191717
    1720     TMTimerSet(pThis->pTimerIO, TMTimerGet(pThis->pTimerIO) + pThis->uTimerTicksIO);
     1718    /* Kick the timer again. */
     1719    uint64_t cTicks = pThis->cTimerTicksIO;
     1720    /** @todo adjust cTicks down by now much cbOutMin represents. */
     1721    TMTimerSet(pThis->pTimerIO, cTicksNow + cTicks);
    17211722}
    17221723
     
    21792180        else
    21802181        {
    2181             pThis->uTimerTicksIO = PDMDevHlpTMTimeVirtGetFreq(pDevIns) / 200; /** Hz. @todo Make this configurable! */
    2182             pThis->uTimerTSIO    = PDMDevHlpTMTimeVirtGet(pDevIns);
    2183             if (pThis->uTimerTicksIO < 100)
    2184                 pThis->uTimerTicksIO = 100;
    2185             LogFunc(("I/O timer ticks=%RU64\n", pThis->uTimerTicksIO));
     2182            pThis->cTimerTicksIO = TMTimerGetFreq(pThis->pTimerIO) / 200; /** @todo Make this configurable! */
     2183            pThis->uTimerTSIO    = TMTimerGet(pThis->pTimerIO);
     2184            LogFunc(("Timer ticks=%RU64\n", pThis->cTimerTicksIO));
    21862185
    21872186            /* Fire off timer. */
    2188             TMTimerSet(pThis->pTimerIO, TMTimerGet(pThis->pTimerIO) + pThis->uTimerTicksIO);
     2187            TMTimerSet(pThis->pTimerIO, TMTimerGet(pThis->pTimerIO) + pThis->cTimerTicksIO);
    21892188        }
    21902189    }
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