VirtualBox

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


Ignore:
Timestamp:
Sep 15, 2015 10:20:11 AM (9 years ago)
Author:
vboxsync
Message:

DrvHostDSound: start playback when first audio samples are copied to the sound buffer.

File:
1 edited

Legend:

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

    r57736 r57752  
    6565    DWORD                cbPlayWritePos;
    6666    DWORD                csPlaybackBufferSize;
    67     bool                 fReinitPlayPos;
     67    bool                 fRestartPlayback;
    6868    PDMAUDIOSTREAMCFG    streamCfg;
    6969} DSOUNDSTREAMOUT, *PDSOUNDSTREAMOUT;
     
    560560        LogFlowFunc(("Playback stopped\n"));
    561561
     562        /* @todo Wait until all data in the buffer has been played. */
    562563        HRESULT hr = IDirectSoundBuffer8_Stop(pDSoundStrmOut->pDSB);
    563564        if (SUCCEEDED(hr))
     
    590591                dsoundPlayClearSamples(pDSoundStrmOut);
    591592
    592                 pDSoundStrmOut->fReinitPlayPos = true;
     593                pDSoundStrmOut->fRestartPlayback = true;
    593594
    594595                LogFlowFunc(("Playback started\n"));
    595596
    596                 HRESULT hr = IDirectSoundBuffer8_Play(pDSoundStrmOut->pDSB, 0, 0, DSBPLAY_LOOPING);
    597                 if (FAILED(hr))
    598                 {
    599                     LogRelMax(s_cMaxRelLogEntries, ("DSound: Error starting playback: %Rhrc\n", hr));
    600                     rc = VERR_NOT_SUPPORTED;
    601                 }
     597                /* The actual IDirectSoundBuffer8_Play call will be made in drvHostDSoundPlayOut,
     598                 * because it is necessary to put some samples into the buffer first.
     599                 */
    602600            }
    603601        }
     
    10381036        pDSoundStrmOut->pDSB = NULL;
    10391037        pDSoundStrmOut->cbPlayWritePos = 0;
    1040         pDSoundStrmOut->fReinitPlayPos = true;
     1038        pDSoundStrmOut->fRestartPlayback = true;
    10411039        pDSoundStrmOut->csPlaybackBufferSize = 0;
    10421040
     
    11261124        DWORD cbBuffer = pDSoundStrmOut->csPlaybackBufferSize << cShift;
    11271125
    1128         DWORD cbPlayPos, cbWritePos;
    1129         HRESULT hr = IDirectSoundBuffer8_GetCurrentPosition(pDSB, &cbPlayPos, &cbWritePos);
     1126        /* Get the current play position which is used for calculating the free space in the buffer. */
     1127        DWORD cbPlayPos;
     1128        HRESULT hr = IDirectSoundBuffer8_GetCurrentPosition(pDSB, &cbPlayPos, NULL);
    11301129        if (hr == DSERR_BUFFERLOST)
    11311130        {
     
    11341133                break;
    11351134
    1136             hr = IDirectSoundBuffer8_GetCurrentPosition(pDSB, &cbPlayPos, &cbWritePos);
     1135            hr = IDirectSoundBuffer8_GetCurrentPosition(pDSB, &cbPlayPos, NULL);
    11371136            if (hr == DSERR_BUFFERLOST) /* Avoid log flooding if the error is still there. */
    11381137                break;
     
    11451144        }
    11461145
    1147         DWORD cbFree;
    1148         DWORD cbPlayWritePos;
    1149         if (pDSoundStrmOut->fReinitPlayPos)
    1150         {
    1151             pDSoundStrmOut->fReinitPlayPos = false;
    1152 
    1153             pDSoundStrmOut->cbPlayWritePos = cbWritePos;
    1154 
    1155             cbPlayWritePos = pDSoundStrmOut->cbPlayWritePos;
    1156             cbFree = cbBuffer - dsoundRingDistance(cbWritePos, cbPlayPos, cbBuffer);
    1157         }
    1158         else
    1159         {
    1160             /* Full buffer? */
    1161             if (pDSoundStrmOut->cbPlayWritePos == cbPlayPos)
    1162                 break;
    1163 
    1164             cbPlayWritePos = pDSoundStrmOut->cbPlayWritePos;
    1165             cbFree         = dsoundRingDistance(cbPlayPos, cbPlayWritePos, cbBuffer);
    1166         }
     1146        DWORD cbFree = cbBuffer - dsoundRingDistance(pDSoundStrmOut->cbPlayWritePos, cbPlayPos, cbBuffer);
     1147
     1148        /* Check for full buffer, do not allow the cbPlayWritePos to catch cbPlayPos during playback,
     1149         * i.e. always leave a free space for 1 audio sample.
     1150         */
     1151        if (cbFree <= (1U << cShift))
     1152            break;
     1153        cbFree -= (1U << cShift);
    11671154
    11681155        uint32_t csLive = drvAudioHstOutSamplesLive(pHstStrmOut);
     
    11761163        {
    11771164            LogFlowFunc(("cbLive=%RU32, cbBuffer=%ld, cbPlayWritePos=%ld, cbPlayPos=%ld\n",
    1178                          cbLive, cbBuffer, cbPlayWritePos, cbPlayPos));
     1165                         cbLive, cbBuffer, pDSoundStrmOut->cbPlayWritePos, cbPlayPos));
    11791166            break;
    11801167        }
     
    11821169        LPVOID pv1, pv2;
    11831170        DWORD cb1, cb2;
    1184         rc = dsoundLockOutput(pDSB, &pHstStrmOut->Props, cbPlayWritePos, cbLive,
     1171        rc = dsoundLockOutput(pDSB, &pHstStrmOut->Props, pDSoundStrmOut->cbPlayWritePos, cbLive,
    11851172                              &pv1, &pv2, &cb1, &cb2, 0 /* dwFlags */);
    11861173        if (RT_FAILURE(rc))
     
    12101197        dsoundUnlockOutput(pDSB, pv1, pv2, cb1, cb2);
    12111198
    1212         pDSoundStrmOut->cbPlayWritePos = (cbPlayWritePos + (cReadTotal << cShift)) % cbBuffer;
    1213 
    1214         LogFlowFunc(("%RU32 (%RU32 samples) out of %RU32%s, buffer write pos %ld -> %ld, rc=%Rrc\n",
     1199        pDSoundStrmOut->cbPlayWritePos = (pDSoundStrmOut->cbPlayWritePos + (cReadTotal << cShift)) % cbBuffer;
     1200
     1201        LogFlowFunc(("%RU32 (%RU32 samples) out of %RU32%s, buffer write pos %ld, rc=%Rrc\n",
    12151202                     AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, cReadTotal), cReadTotal, cbLive,
    12161203                     cbLive != AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, cReadTotal) ? " !!!": "",
    1217                      cbPlayWritePos, pDSoundStrmOut->cbPlayWritePos, rc));
     1204                     pDSoundStrmOut->cbPlayWritePos, rc));
    12181205
    12191206        if (cReadTotal)
     
    12231210        }
    12241211
     1212        if (pDSoundStrmOut->fRestartPlayback)
     1213        {
     1214            /* The playback has been just started.
     1215             * Some samples of the new sound have been copied to the buffer
     1216             * and it can start playing.
     1217             */
     1218            pDSoundStrmOut->fRestartPlayback = false;
     1219            HRESULT hr = IDirectSoundBuffer8_Play(pDSoundStrmOut->pDSB, 0, 0, DSBPLAY_LOOPING);
     1220            if (FAILED(hr))
     1221            {
     1222                LogRelMax(s_cMaxRelLogEntries, ("DSound: Error starting playback: %Rhrc\n", hr));
     1223                rc = VERR_NOT_SUPPORTED;
     1224            }
     1225        }
    12251226    } while (0);
    12261227
     
    12391240
    12401241    pDSoundStrmOut->cbPlayWritePos = 0;
    1241     pDSoundStrmOut->fReinitPlayPos = true;
     1242    pDSoundStrmOut->fRestartPlayback = true;
    12421243    pDSoundStrmOut->csPlaybackBufferSize = 0;
    12431244    RT_ZERO(pDSoundStrmOut->streamCfg);
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