VirtualBox

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


Ignore:
Timestamp:
May 11, 2016 9:13:40 AM (9 years ago)
Author:
vboxsync
Message:

Audio/AC97: Lowered timer to 100Hz and start/stop it only if needed. Should improve overall performance.

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

Legend:

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

    r60925 r60934  
    5151static int audioMixerSinkUpdateVolume(PAUDMIXSINK pSink, const PPDMAUDIOVOLUME pVolMaster);
    5252static void audioMixerSinkRemoveStreamInternal(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
     53static int audioMixerSinkUpdateInternal(PAUDMIXSINK pSink);
    5354
    5455static void audioMixerStreamDestroyInternal(PAUDMIXSTREAM pStream);
     
    516517}
    517518
    518 int AudioMixerSinkUpdate(PAUDMIXSINK pSink)
     519void AudioMixerSinkTimerUpdate(PAUDMIXSINK pSink, uint64_t cTicksPerSec, uint64_t cTicksElapsed, uint32_t *pcbData)
     520{
     521    uint32_t cSamplesMin  = (uint32_t)((2 * cTicksElapsed * pSink->PCMProps.uHz + cTicksPerSec) / cTicksPerSec / 2);
     522    uint32_t cbSamplesMin = cSamplesMin << pSink->PCMProps.cShift;
     523
     524    LogFlowFunc(("%s: cbSamplesMin=%RU32\n", pSink->pszName, cbSamplesMin));
     525
     526    audioMixerSinkUpdateInternal(pSink);
     527
     528    if (pcbData)
     529        *pcbData = cbSamplesMin;
     530}
     531
     532static int audioMixerSinkUpdateInternal(PAUDMIXSINK pSink)
    519533{
    520534    AssertPtrReturn(pSink, VERR_INVALID_POINTER);
     
    532546            || cSamplesLive)
    533547        {
    534             Log3Func(("cbIn=%RU32, cbOut=%RU32, cSamplesLive=%RU32, rc2=%Rrc\n", cbIn, cbOut, cSamplesLive, rc2));
     548            Log3Func(("%s: cbIn=%RU32, cbOut=%RU32, cSamplesLive=%RU32, rc2=%Rrc\n",
     549                      pSink->pszName, cbIn, cbOut, cSamplesLive, rc2));
    535550        }
    536551#endif
     
    551566
    552567    return VINF_SUCCESS;
     568}
     569
     570int AudioMixerSinkUpdate(PAUDMIXSINK pSink)
     571{
     572    return audioMixerSinkUpdateInternal(pSink);
    553573}
    554574
  • trunk/src/VBox/Devices/Audio/AudioMixer.h

    r60925 r60934  
    163163int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PPDMPCMPROPS pPCMProps);
    164164int AudioMixerSinkSetVolume(PAUDMIXSINK pSink, PPDMAUDIOVOLUME pVol);
     165void AudioMixerSinkTimerUpdate(PAUDMIXSINK pSink, uint64_t cTicksPerSec, uint64_t cTicksElapsed, uint32_t *pcbData);
    165166int AudioMixerSinkWrite(PAUDMIXSINK pSink, AUDMIXOP enmOp, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten);
    166167int AudioMixerSinkUpdate(PAUDMIXSINK pSink);
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r60931 r60934  
    5252#define AC97_SSM_VERSION 1
    5353
    54 #define AC97_TIMER_HZ 200
     54#define AC97_TIMER_HZ 100
    5555
    5656#ifdef VBOX
     
    363363    /** Stream state for output. */
    364364    AC97STREAM              StrmStOut;
     365    /** Number of active (running) SDn streams. */
     366    uint8_t                 cStreamsActive;
    365367#ifndef VBOX_WITH_AUDIO_CALLBACKS
    366368    /** The timer for pumping data thru the attached LUN drivers. */
    367369    PTMTIMERR3              pTimer;
    368370# if HC_ARCH_BITS == 32
    369     uint32_t                Alignment1;
     371    uint32_t                Padding0;
    370372# endif
    371373    /** The timer interval for pumping data thru the LUN drivers in timer ticks. */
     
    376378#endif
    377379#ifdef VBOX_WITH_STATISTICS
     380    uint8_t                 Padding1;
    378381    STAMPROFILE             StatTimer;
    379382    STAMCOUNTER             StatBytesRead;
     
    382385    /** List of associated LUN drivers (AC97DRIVER). */
    383386    RTLISTANCHOR            lstDrv;
    384     /** The device' software mixer. */
     387    /** The device's software mixer. */
    385388    R3PTRTYPE(PAUDIOMIXER)  pMixer;
    386389    /** Audio sink for PCM output. */
     
    401404
    402405#ifdef VBOX_WITH_STATISTICS
    403 AssertCompileMemberAlignment(AC97STATE, StatTimer, 8);
     406AssertCompileMemberAlignment(AC97STATE, StatTimer,        8);
     407AssertCompileMemberAlignment(AC97STATE, StatBytesRead,    8);
     408AssertCompileMemberAlignment(AC97STATE, StatBytesWritten, 8);
    404409#endif
    405410
     
    412417static DECLCALLBACK(void) ichac97Reset(PPDMDEVINS pDevIns);
    413418#ifndef VBOX_WITH_AUDIO_CALLBACKS
     419static void ichac97TimerMaybeStart(PAC97STATE pThis);
     420static void ichac97TimerMaybeStop(PAC97STATE pThis);
    414421static DECLCALLBACK(void) ichac97Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser);
    415422#endif
     
    523530    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    524531
    525     LogFlowFunc(("u8Strm=%RU8, fActive=%RTbool\n", pStream->u8Strm, fActive));
     532    if (!fActive)
     533    {
     534        if (pThis->cStreamsActive) /* Disable can be called mupltiple times. */
     535            pThis->cStreamsActive--;
     536
     537#ifndef VBOX_WITH_AUDIO_CALLBACKS
     538        ichac97TimerMaybeStop(pThis);
     539#endif
     540    }
     541    else
     542    {
     543        pThis->cStreamsActive++;
     544#ifndef VBOX_WITH_AUDIO_CALLBACKS
     545        ichac97TimerMaybeStart(pThis);
     546#endif
     547    }
     548
     549    LogFlowFunc(("u8Strm=%RU8, fActive=%RTbool, cStreamsActive=%RU8\n", pStream->u8Strm, fActive, pThis->cStreamsActive));
    526550
    527551    return AudioMixerSinkCtl(ichac97IndexToSink(pThis, pStream->u8Strm),
     
    10231047    PDMAUDIORECSOURCE ars = ichac97IndextoRecSource(rs);
    10241048    PDMAUDIORECSOURCE als = ichac97IndextoRecSource(ls);
    1025     //AUD_set_record_source(&als, &ars);
    10261049    rs = ichac97RecSourceToIndex(ars);
    10271050    ls = ichac97RecSourceToIndex(als);
     
    12801303#ifndef VBOX_WITH_AUDIO_CALLBACKS
    12811304
     1305static void ichac97TimerMaybeStart(PAC97STATE pThis)
     1306{
     1307    LogFlowFunc(("cStreamsActive=%RU8\n", pThis->cStreamsActive));
     1308
     1309    if (pThis->cStreamsActive == 0) /* Only start the timer if there are no active streams. */
     1310        return;
     1311
     1312    if (!pThis->pTimer)
     1313        return;
     1314
     1315    /* Fire off timer. */
     1316    TMTimerSet(pThis->pTimer, TMTimerGet(pThis->pTimer) + pThis->cTimerTicks);
     1317}
     1318
     1319static void ichac97TimerMaybeStop(PAC97STATE pThis)
     1320{
     1321    LogFlowFunc(("cStreamsActive=%RU8\n", pThis->cStreamsActive));
     1322
     1323    if (pThis->cStreamsActive) /* Some streams still active? Bail out. */
     1324        return;
     1325
     1326    if (!pThis->pTimer)
     1327        return;
     1328
     1329    int rc2 = TMTimerStop(pThis->pTimer);
     1330    AssertRC(rc2);
     1331}
     1332
    12821333static DECLCALLBACK(void) ichac97Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
    12831334{
     
    12881339    STAM_PROFILE_START(&pThis->StatTimer, a);
    12891340
    1290     uint32_t cbInMax  = 0;
    1291     uint32_t cbOutMin = UINT32_MAX;
    1292 
    1293 //    PAC97DRIVER pDrv;
    1294 
    12951341    uint64_t cTicksNow     = TMTimerGet(pTimer);
    12961342    uint64_t cTicksElapsed = cTicksNow  - pThis->uTimerTS;
     
    12991345    pThis->uTimerTS = cTicksNow;
    13001346
    1301 #if 0
    1302     /*
    1303      * Calculate the mixer's (fixed) sampling rate.
    1304      */
    1305     AssertPtr(pThis->pMixer);
    1306 
    1307     PDMAUDIOSTREAMCFG mixerStrmCfg;
    1308     int rc = AudioMixerGetDeviceFormat(pThis->pMixer, &mixerStrmCfg);
    1309     AssertRC(rc);
    1310 
    1311     PDMPCMPROPS mixerStrmProps;
    1312     rc = DrvAudioStreamCfgToProps(&mixerStrmCfg, &mixerStrmProps);
    1313     AssertRC(rc);
    1314 
    1315     uint32_t cMixerSamplesMin  = (int)((2 * cTicksElapsed * mixerStrmCfg.uHz + cTicksPerSec) / cTicksPerSec / 2);
    1316     uint32_t cbMixerSamplesMin = cMixerSamplesMin << mixerStrmProps.cShift;
    1317 
    1318     RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
    1319     {
    1320         uint32_t cbIn = 0;
    1321         uint32_t cbOut = 0;
    1322 
    1323         rc = pDrv->pConnector->pfnQueryStatus(pDrv->pConnector,
    1324                                               &cbIn, &cbOut, NULL /* cSamplesLive */);
    1325         if (RT_SUCCESS(rc))
    1326             rc = pDrv->pConnector->pfnPlayOut(pDrv->pConnector, NULL /* cSamplesPlayed */);
    1327 
    1328 #ifdef DEBUG_TIMER
    1329         LogFlowFunc(("LUN#%RU8: rc=%Rrc, cbIn=%RU32, cbOut=%RU32\n", pDrv->uLUN, rc, cbIn, cbOut));
    1330 #endif
    1331         /* If we there was an error handling (available) output or there simply is no output available,
    1332          * then calculate the minimum data rate which must be processed by the device emulation in order
    1333          * to function correctly.
    1334          *
    1335          * This is not the optimal solution, but as we have to deal with this on a timer-based approach
    1336          * (until we have the audio callbacks) we need to have device' DMA engines running. */
    1337         if (!pDrv->pConnector->pfnIsValidOut(pDrv->pConnector, pDrv->Out.pStrmOut))
    1338         {
    1339             /* Use the mixer's (fixed) sampling rate. */
    1340             cbOut = RT_MAX(cbOut, cbMixerSamplesMin);
    1341             continue;
    1342         }
    1343 
    1344         const bool fIsActiveOut = pDrv->pConnector->pfnIsActiveOut(pDrv->pConnector, pDrv->Out.pStrmOut);
    1345         if (   RT_FAILURE(rc)
    1346             || !fIsActiveOut)
    1347         {
    1348             uint32_t cSamplesMin  = (int)((2 * cTicksElapsed * pDrv->Out.pStrmOut->Props.uHz + cTicksPerSec) / cTicksPerSec / 2);
    1349             uint32_t cbSamplesMin = AUDIOMIXBUF_S2B(&pDrv->Out.pStrmOut->MixBuf, cSamplesMin);
    1350 
    1351 #ifdef DEBUG_TIMER
    1352             LogFlowFunc(("\trc=%Rrc, cSamplesMin=%RU32, cbSamplesMin=%RU32\n", rc, cSamplesMin, cbSamplesMin));
    1353 #endif
    1354             cbOut = RT_MAX(cbOut, cbSamplesMin);
    1355         }
    1356 
    1357         cbOutMin = RT_MIN(cbOutMin, cbOut);
    1358         cbInMax  = RT_MAX(cbInMax, cbIn);
    1359     }
    1360 
    1361 #ifdef DEBUG_TIMER
    1362     LogFlowFunc(("cbInMax=%RU32, cbOutMin=%RU32\n", cbInMax, cbOutMin));
    1363 #endif
    1364 
    1365     if (cbOutMin == UINT32_MAX)
    1366         cbOutMin = 0;
    1367 
    1368     /*
    1369      * Playback.
    1370      */
    1371     if (cbOutMin)
    1372     {
    1373         Assert(cbOutMin != UINT32_MAX);
    1374         ichac97TransferAudio(pThis, PO_INDEX, cbOutMin); /** @todo Add rc! */
    1375     }
    1376 
    1377     /*
    1378      * Recording.
    1379      */
    1380     if (cbInMax)
    1381         ichac97TransferAudio(pThis, PI_INDEX, cbInMax); /** @todo Add rc! */
    1382 #else
    1383     AudioMixerSinkUpdate(pThis->pSinkLineIn);
    1384     AudioMixerSinkUpdate(pThis->pSinkMicIn);
    1385     AudioMixerSinkUpdate(pThis->pSinkOutput);
    1386 
    1387     uint32_t cMixerSamplesMin  = (int)((2 * cTicksElapsed *   pThis->pSinkOutput->PCMProps.uHz + cTicksPerSec) / cTicksPerSec / 2);
    1388     uint32_t cbMixerSamplesMin = cMixerSamplesMin <<  pThis->pSinkOutput->PCMProps.cShift;
    1389 
    1390     Log3Func(("cMixerSamplesMin=%RU32, cbMixerSamplesMin=%RU32, mixerHz=%RU32\n",
    1391               cMixerSamplesMin, cbMixerSamplesMin,  pThis->pSinkOutput->PCMProps.uHz));
    1392 
    1393     //uint32_t cbSamplesElapsed = 5120; //((48000 / AC97_TIMER_HZ) * 20) / 8;
    1394 
    1395     uint32_t cMixerSamplesMinIn  = (int)((2 * cTicksElapsed *   pThis->pSinkLineIn->PCMProps.uHz + cTicksPerSec) / cTicksPerSec / 2);
    1396     uint32_t cbMixerSamplesMinIn = cMixerSamplesMinIn <<  pThis->pSinkLineIn->PCMProps.cShift;
    1397 
    1398     ichac97TransferAudio(pThis, &pThis->StrmStLineIn, cMixerSamplesMinIn); /** @todo Add rc! */
    1399     ichac97TransferAudio(pThis, &pThis->StrmStOut,    cbMixerSamplesMin);  /** @todo Add rc! */
    1400 #endif
     1347    uint32_t cbLineIn;
     1348    AudioMixerSinkTimerUpdate(pThis->pSinkLineIn, cTicksPerSec, cTicksElapsed, &cbLineIn);
     1349    if (cbLineIn)
     1350        ichac97TransferAudio(pThis, &pThis->StrmStLineIn, cbLineIn); /** @todo Add rc! */
     1351
     1352    uint32_t cbMicIn;
     1353    AudioMixerSinkTimerUpdate(pThis->pSinkMicIn , cTicksPerSec, cTicksElapsed, &cbMicIn);
     1354
     1355    uint32_t cbOut;
     1356    AudioMixerSinkTimerUpdate(pThis->pSinkOutput, cTicksPerSec, cTicksElapsed, &cbOut);
     1357    if (cbOut)
     1358        ichac97TransferAudio(pThis, &pThis->StrmStOut, cbOut);  /** @todo Add rc! */
    14011359
    14021360    /* Kick the timer again. */
     
    14081366}
    14091367
    1410 #endif
     1368#endif /* !VBOX_WITH_AUDIO_CALLBACKS */
    14111369
    14121370static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbElapsed)
     
    15231481            if (pRegs->civ == pRegs->lvi)
    15241482            {
    1525                 Log3Func(("Underrun civ (%RU8) == lvi (%RU8)\n", pRegs->civ, pRegs->lvi));
     1483                /* Did we run out of data? */
     1484                LogFunc(("Underrun CIV (%RU8) == LVI (%RU8)\n", pRegs->civ, pRegs->lvi));
     1485
    15261486                new_sr |= SR_LVBCI | SR_DCH | SR_CELV;
    15271487                pThis->bup_flag = (pRegs->bd.ctl_len & BD_BUP) ? BUP_LAST : 0;
     
    22602220
    22612221    /*
    2262      * Stop any audio currently playing.
    2263      */
    2264     /*
    22652222     * Stop any audio currently playing and/or recording.
    22662223     */
     
    27552712            LogFunc(("Timer ticks=%RU64 (%RU16 Hz)\n", pThis->cTimerTicks, uTimerHz));
    27562713
    2757             /* Fire off timer. */
    2758             TMTimerSet(pThis->pTimer, TMTimerGet(pThis->pTimer) + pThis->cTimerTicks);
     2714            ichac97TimerMaybeStart(pThis);
    27592715        }
    27602716    }
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