VirtualBox

Changeset 65565 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Feb 1, 2017 2:11:10 PM (8 years ago)
Author:
vboxsync
Message:

Audio: Make use of pvBuf/cbBuf parameters in PDMIHOSTAUDIO::pfnStreamPlay() and PDMIHOSTAUDIO::pfnStreamCapture() to further abstract the backends from the audio connector. The backends now won't be allowed to operate on the audio connector's mixing buffers directly anymore that way.

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

Legend:

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

    r65100 r65565  
    633633    /* No sample buffer size hint given by the backend? Default to some sane value. */
    634634    if (!CfgHostAcq.cSampleBufferSize)
     635    {
    635636        CfgHostAcq.cSampleBufferSize = _1K; /** @todo Make this configurable? */
     637    }
    636638
    637639    PDMAUDIOPCMPROPS PCMProps;
     
    642644    AudioMixBufDestroy(&pHstStream->MixBuf);
    643645
    644     LogFlowFunc(("[%s] cSamples=%RU32\n", pHstStream->szName, CfgHostAcq.cSampleBufferSize * 4));
    645 
    646     rc2 = AudioMixBufInit(&pHstStream->MixBuf, pHstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize * 10);
     646    CfgHostAcq.cSampleBufferSize *= 10; /** @todo Make this configurable. */
     647
     648    LogFlowFunc(("[%s] cSamples=%RU32\n", pHstStream->szName, CfgHostAcq.cSampleBufferSize));
     649
     650    rc2 = AudioMixBufInit(&pHstStream->MixBuf, pHstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize);
    647651    AssertRC(rc2);
    648652
     
    661665    AudioMixBufDestroy(&pGstStream->MixBuf);
    662666
    663     LogFlowFunc(("[%s] cSamples=%RU32\n", pGstStream->szName, CfgHostAcq.cSampleBufferSize * 2));
    664 
    665     rc2 = AudioMixBufInit(&pGstStream->MixBuf, pGstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize * 20);
     667    CfgHostAcq.cSampleBufferSize *= 20; /** @todo Make this configurable. */
     668
     669    LogFlowFunc(("[%s] cSamples=%RU32\n", pGstStream->szName, CfgHostAcq.cSampleBufferSize));
     670
     671    rc2 = AudioMixBufInit(&pGstStream->MixBuf, pGstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize);
    666672    AssertRC(rc2);
    667673
     
    852858#endif
    853859
     860#ifdef LOG_ENABLED
     861    char *pszGstSts = NULL;
     862    char *pszHstSts = NULL;
     863#endif
     864
    854865    do
    855866    {
     
    869880        }
    870881
     882#ifdef LOG_ENABLED
     883        pszHstSts = dbgAudioStreamStatusToStr(pHstStream->fStatus);
     884        AssertPtr(pszHstSts);
     885#endif
    871886        PPDMAUDIOSTREAM pGstStream = pHstStream->pPair;
    872887        AssertPtr(pGstStream);
    873888
    874889#ifdef LOG_ENABLED
    875         char *pszGstSts = dbgAudioStreamStatusToStr(pGstStream->fStatus);
     890        pszGstSts = dbgAudioStreamStatusToStr(pGstStream->fStatus);
     891        AssertPtr(pszGstSts);
     892#endif
     893
     894#ifdef LOG_ENABLED
    876895        AssertMsg(pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED,
    877                   ("Writing to disabled guest output stream \"%s\" not possible (status is %s)\n",
    878                    pGstStream->szName, pszGstSts));
    879         RTStrFree(pszGstSts);
     896                  ("Writing to disabled guest output stream \"%s\" not possible (status is %s, host status %s)\n",
     897                   pGstStream->szName, pszGstSts, pszHstSts));
    880898#endif
    881899        pGstStream->Out.tsLastWriteMS = RTTimeMilliTS();
     
    884902        {
    885903            LogRel2(("Audio: Guest stream '%s' full, expect stuttering audio output\n", pGstStream->szName));
     904
    886905#ifdef DEBUG_andy
    887             AssertMsgFailed(("%s: Guest stream full: cbBuf=%RU32\n", pGstStream->szName, cbBuf));
     906            AssertMsgFailed(("[%s] Failed because guest stream full (guest status %s, host status %s): cbBuf=%RU32\n",
     907                             pGstStream->szName, pszGstSts, pszHstSts, cbBuf));
    888908#endif
    889909            break;
     
    903923            || !csWritten)
    904924        {
    905             AssertMsgFailed(("%s: Write failed: cbBuf=%RU32, csWritten=%RU32, rc=%Rrc\n",
    906                              pGstStream->szName, cbBuf, csWritten, rc));
     925            AssertMsgFailed(("[%s] Write failed (guest status %s, host status %s): cbBuf=%RU32, csWritten=%RU32, rc=%Rrc\n",
     926                             pGstStream->szName, pszGstSts, pszHstSts, cbBuf, csWritten, rc));
    907927        }
    908928#endif
     
    925945                || csMixed < csWritten)
    926946            {
    927                 AssertMsgFailed(("%s: Mixing failed: cbBuf=%RU32, csWritten=%RU32, csMixed=%RU32, rc=%Rrc\n",
    928                                  pGstStream->szName, cbBuf, csWritten, csMixed, rc2));
     947                AssertMsgFailed(("[%s] Mixing failed (guest status %s, host status %s): cbBuf=%RU32, csWritten=%RU32, csMixed=%RU32, rc=%Rrc\n",
     948                                 pGstStream->szName, pszGstSts, pszHstSts, cbBuf, csWritten, csMixed, rc2));
    929949            }
    930950#endif
     
    948968
    949969    } while (0);
     970
     971#ifdef LOG_ENABLED
     972    RTStrFree(pszHstSts);
     973    RTStrFree(pszGstSts);
     974#endif
    950975
    951976    int rc2 = RTCritSectLeave(&pThis->CritSect);
     
    11021127                    else
    11031128                        LogRel2(("Audio: Mixing to guest input stream '%s' failed: %Rrc\n", pGstStream->szName, rc));
    1104 #ifdef DEBUG_andy
     1129#ifdef DEBUG_andy_disabled
    11051130                    AssertFailed();
    11061131#endif
     
    12251250
    12261251        AssertReleaseMsgBreakStmt(pHstStream != NULL,
    1227                                   ("%s: Host stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n",
     1252                                  ("[%s] Host stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n",
    12281253                                   pStream->szName, pStream->cRefs, pStream->fStatus, pStream->enmCtx),
    12291254                                  rc = VERR_NOT_AVAILABLE);
    12301255        AssertReleaseMsgBreakStmt(pGstStream != NULL,
    1231                                   ("%s: Guest stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n",
     1256                                  ("[%s] Guest stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n",
    12321257                                   pStream->szName, pStream->cRefs, pStream->fStatus, pStream->enmCtx),
    12331258                                  rc = VERR_NOT_AVAILABLE);
     
    12491274            && (stsBackend & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE))
    12501275        {
     1276            uint8_t u8Buf[_1K];
     1277
     1278            uint32_t cRead = 0;
     1279            int rc2 = AudioMixBufReadCirc(&pHstStream->MixBuf, u8Buf, sizeof(u8Buf), &cRead);
     1280            AssertRC(rc2);
     1281
     1282            uint32_t cbBuf = AUDIOMIXBUF_S2B(&pHstStream->MixBuf, cRead);
     1283            uint32_t cbPlayed = 0;
     1284
    12511285            AssertPtr(pThis->pHostDrvAudio->pfnStreamPlay);
    1252             rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, NULL /* pvBuf */, 0 /* cbBuf */,
    1253                                                      &csPlayed);
     1286            rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, u8Buf, cbBuf, &cbPlayed);
    12541287            if (RT_SUCCESS(rc))
    12551288            {
     1289                csPlayed = AUDIOMIXBUF_B2S(&pHstStream->MixBuf, cbPlayed);
     1290
     1291                AudioMixBufFinish(&pHstStream->MixBuf, csPlayed);
     1292
    12561293#ifdef VBOX_WITH_STATISTICS
    12571294                STAM_COUNTER_ADD(&pThis->Stats.TotalSamplesOut, csPlayed);
     
    13311368
    13321369        AssertReleaseMsgBreakStmt(pHstStream != NULL,
    1333                                   ("%s: Host stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n",
     1370                                  ("[%s] Host stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n",
    13341371                                   pStream->szName, pStream->cRefs, pStream->fStatus, pStream->enmCtx),
    13351372                                  rc = VERR_NOT_AVAILABLE);
    13361373        AssertReleaseMsgBreakStmt(pGstStream != NULL,
    1337                                   ("%s: Guest stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n",
     1374                                  ("[%s] Guest stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n",
    13381375                                   pStream->szName, pStream->cRefs, pStream->fStatus, pStream->enmCtx),
    13391376                                  rc = VERR_NOT_AVAILABLE);
     
    13481385                && (stsBackend & PDMAUDIOSTRMSTS_FLAG_DATA_READABLE))
    13491386            {
    1350                 rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream, NULL /* pvBuf */, 0 /* cbBuf */,
    1351                                                             &csCaptured);
     1387                uint8_t  auBuf[_1K];
     1388                uint32_t cbCaptured;
     1389
     1390                rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream, auBuf, sizeof(auBuf), &cbCaptured);
    13521391                if (RT_FAILURE(rc))
    13531392                {
     
    13571396                else
    13581397                {
     1398                    Assert(cbCaptured <= sizeof(auBuf));
     1399                    rc = AudioMixBufWriteCirc(&pHstStream->MixBuf, auBuf, cbCaptured, &csCaptured);
     1400                    if (RT_SUCCESS(rc))
     1401                    {
    13591402#ifdef VBOX_WITH_STATISTICS
    1360                     STAM_COUNTER_ADD(&pThis->Stats.TotalSamplesIn,  csCaptured);
    1361                     STAM_COUNTER_ADD(&pHstStream->In.StatSamplesCaptured, csCaptured);
    1362 #endif
    1363                     Log3Func(("[%s] %RU32 samples captured\n", pHstStream->szName, csCaptured));
     1403                        STAM_COUNTER_ADD(&pThis->Stats.TotalSamplesIn,        csCaptured);
     1404                        STAM_COUNTER_ADD(&pHstStream->In.StatSamplesCaptured, csCaptured);
     1405#endif
     1406                        Log3Func(("[%s] %RU32 samples captured\n", pHstStream->szName, csCaptured));
     1407                    }
    13641408                }
    13651409            }
     
    22772321    AssertPtrReturn(pVol,       VERR_INVALID_POINTER);
    22782322
    2279     LogFlowFunc(("%s: volL=%RU32, volR=%RU32, fMute=%RTbool\n", pStream->szName, pVol->uLeft, pVol->uRight, pVol->fMuted));
     2323    LogFlowFunc(("[%s] volL=%RU32, volR=%RU32, fMute=%RTbool\n", pStream->szName, pVol->uLeft, pVol->uRight, pVol->fMuted));
    22802324
    22812325    PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
     
    23022346    PDMAUDIODIR enmDir = pStream->enmDir;
    23032347
    2304     LogFlowFunc(("%s: cRefs=%RU32\n", pStream->szName, pStream->cRefs));
     2348    LogFlowFunc(("[%s] cRefs=%RU32\n", pStream->szName, pStream->cRefs));
    23052349    if (pStream->cRefs > 1)
    23062350        rc = VERR_WRONG_ORDER;
     
    24692513#ifdef LOG_ENABLED
    24702514    char *pszHstSts = dbgAudioStreamStatusToStr(pHstStream->fStatus);
    2471     LogFunc(("%s: fStatus=%s\n", pHstStream->szName, pszHstSts));
     2515    LogFunc(("[%s] fStatus=%s\n", pHstStream->szName, pszHstSts));
    24722516    RTStrFree(pszHstSts);
    24732517#endif /* LOG_ENABLED */
     
    24802524            rc = pThis->pHostDrvAudio->pfnStreamDestroy(pThis->pHostDrvAudio, pHstStream);
    24812525        if (RT_SUCCESS(rc))
     2526        {
    24822527            pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
    2483     }
    2484 
    2485     LogFlowFunc(("%s: Returning %Rrc\n", pHstStream->szName, rc));
     2528            Assert(pHstStream->fStatus == PDMAUDIOSTRMSTS_FLAG_NONE);
     2529        }
     2530    }
     2531
     2532    LogFlowFunc(("[%s] Returning %Rrc\n", pHstStream->szName, rc));
    24862533    return rc;
    24872534}
     
    24992546    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    25002547
    2501     LogFlowFunc(("%s: cRefs=%RU32\n", pStream->szName, pStream->cRefs));
     2548    LogFlowFunc(("[%s] cRefs=%RU32\n", pStream->szName, pStream->cRefs));
    25022549
    25032550    if (pStream->cRefs > 1)
     
    25122559            rc = drvAudioStreamControlInternal(pThis, pStream, PDMAUDIOSTREAMCMD_DISABLE);
    25132560            if (RT_SUCCESS(rc))
     2561            {
    25142562                pStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
     2563                Assert(pStream->fStatus == PDMAUDIOSTRMSTS_FLAG_NONE);
     2564            }
    25152565        }
    25162566    }
  • trunk/src/VBox/Devices/Audio/DrvHostALSAAudio.cpp

    r65100 r65565  
    55
    66/*
    7  * Copyright (C) 2006-2016 Oracle Corporation
     7 * Copyright (C) 2006-2017 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    6060
    6161#include "DrvAudio.h"
    62 #include "AudioMixBuffer.h"
    63 
    6462#include "VBoxDD.h"
    6563
     
    8381     *  Note: Always must come first! */
    8482    PDMAUDIOSTREAM      Stream;
     83    /** The PCM properties of this stream. */
     84    PDMAUDIOPCMPROPS    Props;
    8585    snd_pcm_t          *phPCM;
    8686    void               *pvBuf;
     
    9393     *  Note: Always must come first! */
    9494    PDMAUDIOSTREAM      Stream;
     95    /** The PCM properties of this stream. */
     96    PDMAUDIOPCMPROPS    Props;
    9597    snd_pcm_t          *phPCM;
    9698    void               *pvBuf;
     
    10151017 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
    10161018 */
    1017 static DECLCALLBACK(int) drvHostALSAAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    1018 {
    1019     RT_NOREF(pvBuf, cbBuf);
     1019static DECLCALLBACK(int) drvHostALSAAudioStreamCapture(PPDMIHOSTAUDIO pInterface,
     1020                                                       PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     1021{
    10201022    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    10211023    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     1024    AssertPtrReturn(pvBuf,      VERR_INVALID_POINTER);
     1025    AssertReturn(cbBuf,         VERR_INVALID_PARAMETER);
    10221026    /* pcbRead is optional. */
    10231027
    1024     PALSAAUDIOSTREAMIN pThisStream = (PALSAAUDIOSTREAMIN)pStream;
     1028    PALSAAUDIOSTREAMIN pStreamALSA = (PALSAAUDIOSTREAMIN)pStream;
    10251029
    10261030    snd_pcm_sframes_t cAvail;
    1027     int rc = alsaStreamGetAvail(pThisStream->phPCM, &cAvail);
     1031    int rc = alsaStreamGetAvail(pStreamALSA->phPCM, &cAvail);
    10281032    if (RT_FAILURE(rc))
    10291033    {
     
    10341038    if (!cAvail) /* No data yet? */
    10351039    {
    1036         snd_pcm_state_t state = snd_pcm_state(pThisStream->phPCM);
     1040        snd_pcm_state_t state = snd_pcm_state(pStreamALSA->phPCM);
    10371041        switch (state)
    10381042        {
    10391043            case SND_PCM_STATE_PREPARED:
    1040                 cAvail = AudioMixBufFree(&pStream->MixBuf);
     1044                cAvail = PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, cbBuf);
    10411045                break;
    10421046
    10431047            case SND_PCM_STATE_SUSPENDED:
    10441048            {
    1045                 rc = alsaStreamResume(pThisStream->phPCM);
     1049                rc = alsaStreamResume(pStreamALSA->phPCM);
    10461050                if (RT_FAILURE(rc))
    10471051                    break;
     
    10681072     * the mixer buffer.
    10691073     */
    1070     Assert(cAvail);
    1071     size_t cbMixFree = AudioMixBufFreeBytes(&pStream->MixBuf);
    1072     size_t cbToRead = RT_MIN((size_t)AUDIOMIXBUF_S2B(&pStream->MixBuf, cAvail), cbMixFree);
     1074    size_t cbToRead = RT_MIN((size_t)PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, cAvail), cbBuf);
    10731075
    10741076    LogFlowFunc(("cbToRead=%zu, cAvail=%RI32\n", cbToRead, cAvail));
    10751077
    1076     uint32_t cWrittenTotal = 0;
     1078    uint32_t cbReadTotal = 0;
     1079
    10771080    snd_pcm_uframes_t cToRead;
    10781081    snd_pcm_sframes_t cRead;
     
    10811084           && RT_SUCCESS(rc))
    10821085    {
    1083         cToRead = RT_MIN(AUDIOMIXBUF_B2S(&pStream->MixBuf, cbToRead),
    1084                          AUDIOMIXBUF_B2S(&pStream->MixBuf, pThisStream->cbBuf));
     1086        cToRead = RT_MIN(PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, cbToRead),
     1087                         PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, pStreamALSA->cbBuf));
    10851088        AssertBreakStmt(cToRead, rc = VERR_NO_DATA);
    1086         cRead = snd_pcm_readi(pThisStream->phPCM, pThisStream->pvBuf, cToRead);
     1089        cRead = snd_pcm_readi(pStreamALSA->phPCM, pStreamALSA->pvBuf, cToRead);
    10871090        if (cRead <= 0)
    10881091        {
     
    11091112                case -EPIPE:
    11101113                {
    1111                     rc = alsaStreamRecover(pThisStream->phPCM);
     1114                    rc = alsaStreamRecover(pStreamALSA->phPCM);
    11121115                    if (RT_FAILURE(rc))
    11131116                        break;
     
    11271130        else
    11281131        {
    1129             uint32_t cWritten;
    1130             rc = AudioMixBufWriteCirc(&pStream->MixBuf,
    1131                                       pThisStream->pvBuf, AUDIOMIXBUF_S2B(&pStream->MixBuf, cRead),
    1132                                       &cWritten);
    1133             if (RT_FAILURE(rc))
    1134                 break;
    1135 
    11361132            /*
    11371133             * We should not run into a full mixer buffer or we loose samples and
     
    11391135             * capture device for example).
    11401136             */
    1141             AssertLogRelMsgBreakStmt(cWritten > 0, ("Mixer buffer shouldn't be full at this point!\n"),
    1142                                      rc = VERR_INTERNAL_ERROR);
    1143             uint32_t cbWritten = AUDIOMIXBUF_S2B(&pStream->MixBuf, cWritten);
    1144 
    1145             Assert(cbToRead >= cbWritten);
    1146             cbToRead -= cbWritten;
    1147             cWrittenTotal += cWritten;
     1137            uint32_t cbRead = PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, cRead);
     1138
     1139            memcpy(pvBuf, pStreamALSA->pvBuf, cbRead);
     1140
     1141            Assert(cbToRead >= cbRead);
     1142            cbToRead    -= cbRead;
     1143            cbReadTotal += cbRead;
    11481144        }
    11491145    }
     
    11511147    if (RT_SUCCESS(rc))
    11521148    {
    1153         uint32_t cProcessed = 0;
    1154         if (cWrittenTotal)
    1155             rc = AudioMixBufMixToParent(&pStream->MixBuf, cWrittenTotal,
    1156                                         &cProcessed);
    1157 
    11581149        if (pcbRead)
    1159             *pcbRead = cWrittenTotal;
    1160 
    1161         LogFlowFunc(("cWrittenTotal=%RU32 (%RU32 processed), rc=%Rrc\n",
    1162                      cWrittenTotal, cProcessed, rc));
     1150            *pcbRead = cbReadTotal;
    11631151    }
    11641152
     
    11701158 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
    11711159 */
    1172 static DECLCALLBACK(int) drvHostALSAAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
    1173 {
    1174     RT_NOREF(pvBuf, cbBuf);
     1160static DECLCALLBACK(int) drvHostALSAAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
     1161                                                    const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
     1162{
    11751163    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    11761164    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     1165    AssertPtrReturn(pvBuf,      VERR_INVALID_POINTER);
     1166    AssertReturn(cbBuf,         VERR_INVALID_PARAMETER);
    11771167    /* pcbWritten is optional. */
    11781168
    1179     PALSAAUDIOSTREAMOUT pThisStream = (PALSAAUDIOSTREAMOUT)pStream;
     1169    PALSAAUDIOSTREAMOUT pStreamALSA = (PALSAAUDIOSTREAMOUT)pStream;
    11801170
    11811171    int rc = VINF_SUCCESS;
    1182     uint32_t cbReadTotal = 0;
     1172
     1173    uint32_t cbWrittenTotal = 0;
    11831174
    11841175    do
    11851176    {
    11861177        snd_pcm_sframes_t cAvail;
    1187         rc = alsaStreamGetAvail(pThisStream->phPCM, &cAvail);
     1178        rc = alsaStreamGetAvail(pStreamALSA->phPCM, &cAvail);
    11881179        if (RT_FAILURE(rc))
    11891180        {
     
    11921183        }
    11931184
    1194         size_t cbToRead = RT_MIN(AUDIOMIXBUF_S2B(&pStream->MixBuf,
    1195                                                  (uint32_t)cAvail), /* cAvail is always >= 0 */
    1196                                  AUDIOMIXBUF_S2B(&pStream->MixBuf,
    1197                                                  AudioMixBufLive(&pStream->MixBuf)));
    1198         LogFlowFunc(("cbToRead=%zu, cbAvail=%zu\n",
    1199                      cbToRead, AUDIOMIXBUF_S2B(&pStream->MixBuf, cAvail)));
    1200 
    1201         uint32_t cRead, cbRead;
    1202         snd_pcm_sframes_t cWritten;
    1203         while (cbToRead)
    1204         {
    1205             rc = AudioMixBufReadCirc(&pStream->MixBuf, pThisStream->pvBuf, cbToRead, &cRead);
    1206             if (RT_FAILURE(rc))
    1207                 break;
    1208 
    1209             cbRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, cRead);
    1210             AssertBreak(cbRead);
    1211 
    1212             /* Don't try infinitely on recoverable errors. */
    1213             unsigned iTry;
    1214             for (iTry = 0; iTry < ALSA_RECOVERY_TRIES_MAX; iTry++)
     1185        size_t cbToRead = RT_MIN(PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, cAvail), cbBuf);
     1186        if (!cbToRead)
     1187            break;
     1188
     1189        memcpy(pStreamALSA->pvBuf, pvBuf, cbToRead);
     1190
     1191        snd_pcm_sframes_t cWritten = 0;
     1192
     1193        /* Don't try infinitely on recoverable errors. */
     1194        unsigned iTry;
     1195        for (iTry = 0; iTry < ALSA_RECOVERY_TRIES_MAX; iTry++)
     1196        {
     1197            cWritten = snd_pcm_writei(pStreamALSA->phPCM, pStreamALSA->pvBuf,
     1198                                      PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, cbToRead));
     1199            if (cWritten <= 0)
    12151200            {
    1216                 cWritten = snd_pcm_writei(pThisStream->phPCM, pThisStream->pvBuf, cRead);
    1217                 if (cWritten <= 0)
     1201                switch (cWritten)
    12181202                {
    1219                     switch (cWritten)
     1203                    case 0:
    12201204                    {
    1221                         case 0:
     1205                        LogFunc(("Failed to write %zu bytes\n", cbToRead));
     1206                        rc = VERR_ACCESS_DENIED;
     1207                        break;
     1208                    }
     1209
     1210                    case -EPIPE:
     1211                    {
     1212                        rc = alsaStreamRecover(pStreamALSA->phPCM);
     1213                        if (RT_FAILURE(rc))
     1214                            break;
     1215
     1216                        LogFlowFunc(("Recovered from playback\n"));
     1217                        continue;
     1218                    }
     1219
     1220                    case -ESTRPIPE:
     1221                    {
     1222                        /* Stream was suspended and waiting for a recovery. */
     1223                        rc = alsaStreamResume(pStreamALSA->phPCM);
     1224                        if (RT_FAILURE(rc))
    12221225                        {
    1223                             LogFunc(("Failed to write %RU32 samples\n", cRead));
    1224                             rc = VERR_ACCESS_DENIED;
     1226                            LogRel(("ALSA: Failed to resume output stream\n"));
    12251227                            break;
    12261228                        }
    12271229
    1228                         case -EPIPE:
    1229                         {
    1230                             rc = alsaStreamRecover(pThisStream->phPCM);
    1231                             if (RT_FAILURE(rc))
    1232                                 break;
    1233 
    1234                             LogFlowFunc(("Recovered from playback\n"));
    1235                             continue;
    1236                         }
    1237 
    1238                         case -ESTRPIPE:
    1239                         {
    1240                             /* Stream was suspended and waiting for a recovery. */
    1241                             rc = alsaStreamResume(pThisStream->phPCM);
    1242                             if (RT_FAILURE(rc))
    1243                             {
    1244                                 LogRel(("ALSA: Failed to resume output stream\n"));
    1245                                 break;
    1246                             }
    1247 
    1248                             LogFlowFunc(("Resumed suspended output stream\n"));
    1249                             continue;
    1250                         }
    1251 
    1252                         default:
    1253                             LogFlowFunc(("Failed to write %RI32 output frames, rc=%Rrc\n",
    1254                                          cRead, rc));
    1255                             rc = VERR_GENERAL_FAILURE; /** @todo */
    1256                             break;
     1230                        LogFlowFunc(("Resumed suspended output stream\n"));
     1231                        continue;
    12571232                    }
     1233
     1234                    default:
     1235                        LogFlowFunc(("Failed to write %RU32 bytes, error unknown\n", cbToRead));
     1236                        rc = VERR_GENERAL_FAILURE; /** @todo */
     1237                        break;
    12581238                }
    1259                 else
    1260                     break;
    1261             } /* For number of tries. */
    1262 
    1263             if (   iTry == ALSA_RECOVERY_TRIES_MAX
    1264                 && cWritten <= 0)
    1265                 rc = VERR_BROKEN_PIPE;
    1266 
    1267             if (RT_FAILURE(rc))
     1239            }
     1240            else
    12681241                break;
    1269 
    1270             Assert(cbToRead >= cbRead);
    1271             cbToRead -= cbRead;
    1272             cbReadTotal += cbRead;
    1273         }
    1274     }
    1275     while (0);
     1242        } /* For number of tries. */
     1243
     1244        if (   iTry == ALSA_RECOVERY_TRIES_MAX
     1245            && cWritten <= 0)
     1246            rc = VERR_BROKEN_PIPE;
     1247
     1248        if (RT_FAILURE(rc))
     1249            break;
     1250
     1251        cbWrittenTotal = cbToRead;
     1252
     1253    } while (0);
    12761254
    12771255    if (RT_SUCCESS(rc))
    12781256    {
    1279         uint32_t cReadTotal = AUDIOMIXBUF_B2S(&pStream->MixBuf, cbReadTotal);
    1280         if (cReadTotal)
    1281             AudioMixBufFinish(&pStream->MixBuf, cReadTotal);
    1282 
    12831257        if (pcbWritten)
    1284             *pcbWritten = cReadTotal;
    1285 
    1286         LogFlowFunc(("cReadTotal=%RU32 (%RU32 bytes), rc=%Rrc\n",
    1287                      cReadTotal, cbReadTotal, rc));
     1258            *pcbWritten = cbWrittenTotal;
    12881259    }
    12891260
     
    13331304static int alsaCreateStreamOut(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    13341305{
    1335     PALSAAUDIOSTREAMOUT pThisStream = (PALSAAUDIOSTREAMOUT)pStream;
     1306    PALSAAUDIOSTREAMOUT pStreamALSA = (PALSAAUDIOSTREAMOUT)pStream;
    13361307
    13371308    snd_pcm_t *phPCM = NULL;
     
    13651336        pCfgAcq->cSampleBufferSize = obt.samples * 4;
    13661337
    1367         PDMAUDIOPCMPROPS Props;
    1368         rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &Props);
     1338        rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStreamALSA->Props);
    13691339        if (RT_FAILURE(rc))
    13701340            break;
    13711341
    13721342        AssertBreakStmt(obt.samples, rc = VERR_INVALID_PARAMETER);
    1373         size_t cbBuf = obt.samples * (1 << Props.cShift); /** @todo Get rid of using Props! */
     1343
     1344        size_t cbBuf = obt.samples * PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, 1);
    13741345        AssertBreakStmt(cbBuf, rc = VERR_INVALID_PARAMETER);
    1375         pThisStream->pvBuf = RTMemAlloc(cbBuf);
    1376         if (!pThisStream->pvBuf)
    1377         {
    1378             LogRel(("ALSA: Not enough memory for output DAC buffer (%RU32 samples, each %d bytes)\n",
    1379                     obt.samples, 1 << Props.cShift));
     1346
     1347        pStreamALSA->pvBuf = RTMemAlloc(cbBuf);
     1348        if (!pStreamALSA->pvBuf)
     1349        {
     1350            LogRel(("ALSA: Not enough memory for output DAC buffer (%RU32 samples, %zu bytes)\n", obt.samples, cbBuf));
    13801351            rc = VERR_NO_MEMORY;
    13811352            break;
    13821353        }
    13831354
    1384         pThisStream->cbBuf = cbBuf;
    1385         pThisStream->phPCM = phPCM;
     1355        pStreamALSA->cbBuf = cbBuf;
     1356        pStreamALSA->phPCM = phPCM;
    13861357    }
    13871358    while (0);
  • trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp

    r65100 r65565  
    55
    66/*
    7  * Copyright (C) 2010-2016 Oracle Corporation
     7 * Copyright (C) 2010-2017 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2323
    2424#include "DrvAudio.h"
    25 #include "AudioMixBuffer.h"
    26 
    2725#include "VBoxDD.h"
    2826
  • trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp

    r63714 r65565  
    2828#include <iprt/uuid.h>
    2929
    30 #include "AudioMixBuffer.h"
    3130#include "DrvAudio.h"
    3231#include "VBoxDD.h"
     
    114113    LPDIRECTSOUNDBUFFER8 pDSB;
    115114    DWORD                offPlayWritePos;
    116     DWORD                cMaxSamplesInBuffer;
     115    DWORD                cbPlayBuf;
    117116    bool                 fEnabled;
    118117    bool                 fRestartPlayback;
     
    128127    LPDIRECTSOUNDCAPTURE8       pDSC;
    129128    LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB;
    130     DWORD                       idxSampleCaptureReadPos;
    131     DWORD                       cMaxSamplesInBuffer;
     129    DWORD                       offCaptureBufRead;
     130    DWORD                       cbCaptureBuf;
    132131    HRESULT                     hrLastCapture;
    133132    PDMAUDIORECSOURCE           enmRecSource;
     
    284283        if (SUCCEEDED(hr))
    285284        {
    286             DWORD const cbBuffer = AUDIOMIXBUF_S2B(&pDSoundStream->Stream.MixBuf, pDSoundStream->cMaxSamplesInBuffer);
     285            DWORD const cbBuffer = pDSoundStream->cbPlayBuf;
    287286            if (pdwBuffer)
    288287                *pdwBuffer  = cbBuffer;
     
    604603         *
    605604         * Instead we're specifying DSBCAPS_LOCSOFTWARE, as this fits the bill
    606          * of copying own buffer data (from AudioMixBuf) to our secondary's Direct Sound buffer.
     605         * of copying own buffer data to our secondary's Direct Sound buffer.
    607606         */
    608607        bd.dwFlags     = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCSOFTWARE;
     
    681680         * playback buffer position.
    682681         */
    683         pDSoundStream->cMaxSamplesInBuffer = bc.dwBufferBytes >> pDSoundStream->Props.cShift;
    684         DSLOG(("DSound: cMaxSamplesInBuffer=%RU32\n", pDSoundStream->cMaxSamplesInBuffer));
     682        pDSoundStream->cbPlayBuf = bc.dwBufferBytes;
     683        DSLOG(("DSound: cMaxSamplesInBuffer=%RU32\n", pDSoundStream->cbPlayBuf));
    685684
    686685#ifdef VBOX_WITH_AUDIO_DEVICE_CALLBACKS
     
    745744    AssertPtrReturnVoid(pDSoundStream);
    746745
    747     PPDMAUDIOSTREAM pStream = &pDSoundStream->Stream;
    748 
    749746    PVOID pv1, pv2;
    750747    DWORD cb1, cb2;
    751748    HRESULT hr = directSoundPlayLock(pThis, pDSoundStream->pDSB, &pDSoundStream->Props,
    752                                      0 /* dwOffset */, AUDIOMIXBUF_S2B(&pStream->MixBuf, pDSoundStream->cMaxSamplesInBuffer),
     749                                     0 /* dwOffset */,
     750                                     &pDSoundStream->Props, pDSoundStream->cbPlayBuf,
    753751                                     &pv1, &pv2, &cb1, &cb2, DSBLOCK_ENTIREBUFFER);
    754752    if (SUCCEEDED(hr))
    755753    {
    756         DWORD len1 = AUDIOMIXBUF_B2S(&pStream->MixBuf, cb1);
    757         DWORD len2 = AUDIOMIXBUF_B2S(&pStream->MixBuf, cb2);
     754        DWORD len1 = PDMAUDIOPCMPROPS_B2S(&pDSoundStream->Props, cb1);
     755        DWORD len2 = PDMAUDIOPCMPROPS_B2S(&pDSoundStream->Props, cb2);
    758756
    759757        if (pv1 && len1)
     
    11481146
    11491147        /* Initial state: reading at the initial capture position, no error. */
    1150         pDSoundStream->idxSampleCaptureReadPos = offByteReadPos >> pDSoundStream->Props.cShift;
    1151         pDSoundStream->cMaxSamplesInBuffer     = bc.dwBufferBytes >> pDSoundStream->Props.cShift;
    1152         pDSoundStream->hrLastCapture           = S_OK;
    1153 
    1154         DSLOG(("DSound: idxSampleCaptureReadPos=%RU32, cMaxSamplesInBuffer=%RU32\n",
    1155                      pDSoundStream->idxSampleCaptureReadPos, pDSoundStream->cMaxSamplesInBuffer));
     1148        pDSoundStream->offCaptureBufRead = offByteReadPos;
     1149        pDSoundStream->cbCaptureBuf      = bc.dwBufferBytes;
     1150
     1151        pDSoundStream->hrLastCapture     = S_OK;
     1152
     1153        DSLOG(("DSound: offCaptureBufRead=%RU32, cbCaptureBuf=%RU32\n",
     1154               pDSoundStream->offCaptureBufRead, pDSoundStream->cbCaptureBuf));
    11561155
    11571156    } while (0);
     
    14571456        pDSoundStream->offPlayWritePos = 0;
    14581457        pDSoundStream->fRestartPlayback = true;
    1459         pDSoundStream->cMaxSamplesInBuffer = 0;
     1458        pDSoundStream->cbPlayBuf = 0;
    14601459
    14611460        if (pCfgAcq)
     
    15281527 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
    15291528 */
    1530 int drvHostDSoundStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
    1531 {
    1532     RT_NOREF2(pvBuf, cbBuf);
    1533 
     1529int drvHostDSoundStreamPlay(PPDMIHOSTAUDIO pInterface,
     1530                            PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
     1531{
    15341532    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    15351533    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     1534    AssertPtrReturn(pvBuf,      VERR_INVALID_POINTER);
     1535    AssertReturn(cbBuf,         VERR_INVALID_PARAMETER);
    15361536    /* pcbRead is optional. */
    15371537
     
    15401540
    15411541    int rc = VINF_SUCCESS;
    1542     uint32_t cReadTotal = 0;
     1542
     1543    uint32_t cbWrittenTotal = 0;
    15431544
    15441545#ifdef DEBUG_andy
     
    15571558         * i.e. always leave a free space for 1 audio sample.
    15581559         */
    1559         const DWORD cbSample = AUDIOMIXBUF_S2B(&pStream->MixBuf, 1);
     1560        const DWORD cbSample = PDMAUDIOPCMPROPS_S2B(&pDSoundStream->Props, 1);
    15601561        if (cbFree <= cbSample)
    15611562            break;
    15621563        cbFree     -= cbSample;
    15631564
    1564         uint32_t cLive  = AudioMixBufLive(&pStream->MixBuf);
    1565         uint32_t cbLive = AUDIOMIXBUF_S2B(&pStream->MixBuf, cLive);
     1565        uint32_t cbLive = cbBuf;
    15661566
    15671567        /* Do not write more than available space in the DirectSound playback buffer. */
     
    15891589
    15901590        /** @todo r=bird: Can pv1/cb1 really be NULL? Docs says they're always set
    1591          *        and pv2/cb2 only used when there is a buffer wrap araound. */
    1592 
    1593         DWORD cSamplesIn1 = AUDIOMIXBUF_B2S(&pStream->MixBuf, cb1);
     1591         *        and pv2/cb2 only used when there is a buffer wrap around. */
     1592
     1593        DWORD cSamplesIn1 = PDMAUDIOPCMPROPS_B2S(&pDSoundStream->Props, cb1);
    15941594        uint32_t cRead = 0;
    15951595
    15961596        if (pv1 && cb1)
    15971597        {
    1598             rc = AudioMixBufReadCirc(&pStream->MixBuf, pv1, cb1, &cRead);
    1599             if (RT_SUCCESS(rc))
    1600                 cReadTotal += cRead;
    1601         }
    1602 
    1603         if (   RT_SUCCESS(rc)
    1604             && cReadTotal == cSamplesIn1
    1605             && pv2 && cb2)
    1606         {
    1607             rc = AudioMixBufReadCirc(&pStream->MixBuf, pv2, cb2, &cRead);
    1608             if (RT_SUCCESS(rc))
    1609                 cReadTotal += cRead;
     1598            memcpy(pv1, pvBuf, cb1);
     1599            cbWrittenTotal += cb1;
     1600        }
     1601
     1602        if (pv2 && cb2)
     1603        {
     1604            memcpy(pv2, (uint8_t *)pvBuf + cb1, cb2);
     1605            cbWrittenTotal += cb2;
    16101606        }
    16111607
    16121608        directSoundPlayUnlock(pThis, pDSB, pv1, pv2, cb1, cb2);
    16131609
    1614         pDSoundStream->offPlayWritePos = (pDSoundStream->offPlayWritePos + AUDIOMIXBUF_S2B(&pStream->MixBuf, cReadTotal))
     1610        pDSoundStream->offPlayWritePos = (pDSoundStream->offPlayWritePos + PDMAUDIOPCMPROPS_S2B(&pDSoundStream->Props, cbWrittenTotal))
    16151611                                       % cbBuffer;
    16161612
    1617         DSLOGF(("DSound: %RU32 (%RU32 samples) out of %RU32%s, buffer write pos %ld, rc=%Rrc\n",
    1618                 AUDIOMIXBUF_S2B(&pStream->MixBuf, cReadTotal), cReadTotal, cbLive,
    1619                 cbLive != AUDIOMIXBUF_S2B(&pStream->MixBuf, cReadTotal) ? " !!!": "",
     1613        DSLOGF(("DSound: %RU32/%RU32, buffer write pos %ld, rc=%Rrc\n",
     1614                PDMAUDIOPCMPROPS_S2B(&pDSoundStream->Props, cbWrittenTotal), cbLive,
    16201615                pDSoundStream->offPlayWritePos, rc));
    1621 
    1622         if (cReadTotal)
    1623         {
    1624             AudioMixBufFinish(&pStream->MixBuf, cReadTotal);
    1625             rc = VINF_SUCCESS; /* Played something. */
    1626         }
    1627 
    1628         if (RT_FAILURE(rc))
    1629             break;
    16301616
    16311617        if (pDSoundStream->fRestartPlayback)
     
    16681654        dsoundUpdateStatusInternal(pThis);
    16691655    else if (pcbWritten)
    1670         *pcbWritten = cReadTotal;
    1671 
    1672     LogFlowFuncLeaveRC(rc);
     1656        *pcbWritten = cbWrittenTotal;
     1657
    16731658    return rc;
    16741659}
     
    16811666    directSoundPlayClose(pThis, pDSoundStream);
    16821667
    1683     pDSoundStream->offPlayWritePos      = 0;
    1684     pDSoundStream->fRestartPlayback     = true;
    1685     pDSoundStream->cMaxSamplesInBuffer  = 0;
     1668    pDSoundStream->offPlayWritePos  = 0;
     1669    pDSoundStream->fRestartPlayback = true;
     1670    pDSoundStream->cbPlayBuf        = 0;
    16861671
    16871672    RT_ZERO(pDSoundStream->streamCfg);
     
    17041689    {
    17051690        /* Init the stream structure and save relevant information to it. */
    1706         pDSoundStream->idxSampleCaptureReadPos    = 0;
    1707         pDSoundStream->cMaxSamplesInBuffer = 0;
     1691        pDSoundStream->offCaptureBufRead    = 0;
     1692        pDSoundStream->cbPlayBuf = 0;
    17081693        pDSoundStream->pDSC                = NULL;
    17091694        pDSoundStream->pDSCB               = NULL;
     
    17811766 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
    17821767 */
    1783 int drvHostDSoundStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    1784 {
    1785     RT_NOREF2(pvBuf, cbBuf);
     1768int drvHostDSoundStreamCapture(PPDMIHOSTAUDIO pInterface,
     1769                               PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     1770{
     1771
     1772    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     1773    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     1774    AssertPtrReturn(pvBuf,      VERR_INVALID_POINTER);
     1775    AssertReturn(cbBuf,         VERR_INVALID_PARAMETER);
    17861776
    17871777    PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
     
    17921782    int rc = VINF_SUCCESS;
    17931783
    1794     uint32_t cSamplesProcessed = 0;
     1784    uint32_t cbReadTotal = 0;
    17951785
    17961786    do
     
    18031793
    18041794        /* Get DirectSound capture position in bytes. */
    1805         DWORD offByteReadPos;
    1806         HRESULT hr = IDirectSoundCaptureBuffer_GetCurrentPosition(pDSCB, NULL, &offByteReadPos);
     1795        DWORD offCurPos;
     1796        HRESULT hr = IDirectSoundCaptureBuffer_GetCurrentPosition(pDSCB, NULL, &offCurPos);
    18071797        if (FAILED(hr))
    18081798        {
     
    18191809        pDSoundStream->hrLastCapture = hr;
    18201810
    1821         if (offByteReadPos & pDSoundStream->Props.uAlign)
    1822             DSLOGF(("DSound: Misaligned capture read position %ld (alignment: %RU32)\n", offByteReadPos, pDSoundStream->Props.uAlign));
    1823 
    1824         /* Capture position in samples. */
    1825         DWORD idxSampleReadPos = offByteReadPos >> pDSoundStream->Props.cShift;
     1811        if (offCurPos & pDSoundStream->Props.uAlign)
     1812            DSLOGF(("DSound: Misaligned capture read position %ld (alignment: %RU32)\n", offCurPos, pDSoundStream->Props.uAlign));
    18261813
    18271814        /* Number of samples available in the DirectSound capture buffer. */
    1828         DWORD cSamplesToCapture = dsoundRingDistance(idxSampleReadPos, pDSoundStream->idxSampleCaptureReadPos,
    1829                                                      pDSoundStream->cMaxSamplesInBuffer);
    1830         if (cSamplesToCapture == 0)
    1831             break;
    1832 
    1833         /* Get number of free samples in the mix buffer and check that is has free space */
    1834         uint32_t cFreeMixSamples = AudioMixBufFree(&pStream->MixBuf);
    1835         if (cFreeMixSamples == 0)
     1815        DWORD cbToCapture = dsoundRingDistance(offCurPos, pDSoundStream->offCaptureBufRead, pDSoundStream->cbCaptureBuf);
     1816        if (cbToCapture == 0)
     1817            break;
     1818
     1819        if (cbBuf == 0)
    18361820        {
    18371821            DSLOGF(("DSound: Capture buffer full\n"));
     
    18391823        }
    18401824
    1841         DSLOGF(("DSound: Capture cFreeMixSamples=%RU32, idxSampleReadPos=%u, idxSampleCaptureReadPos=%u, cSamplesToCapture=%u\n",
    1842                 cFreeMixSamples, idxSampleReadPos, pDSoundStream->idxSampleCaptureReadPos, cSamplesToCapture));
     1825        DSLOGF(("DSound: Capture cbBuf=%RU32, offCurPos=%ld, offCaptureBufRead=%ld, cbToCapture=%ld\n",
     1826                cbBuf, offCurPos, pDSoundStream->offCaptureBufRead, cbToCapture));
    18431827
    18441828        /* No need to fetch more samples than mix buffer can receive. */
    1845         cSamplesToCapture = RT_MIN(cSamplesToCapture, cFreeMixSamples);
     1829        cbToCapture = RT_MIN(cbToCapture, cbBuf);
    18461830
    18471831        /* Lock relevant range in the DirectSound capture buffer. */
     
    18491833        DWORD cb1, cb2;
    18501834        hr = directSoundCaptureLock(pDSCB, &pDSoundStream->Props,
    1851                                     AUDIOMIXBUF_S2B(&pStream->MixBuf, pDSoundStream->idxSampleCaptureReadPos), /* dwOffset */
    1852                                     AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesToCapture),                      /* dwBytes */
     1835                                    pDSoundStream->offCaptureBufRead, /* dwOffset */
     1836                                    cbToCapture,                      /* dwBytes */
    18531837                                    &pv1, &pv2, &cb1, &cb2,
    1854                                     0 /* dwFlags */);
     1838                                    0                                 /* dwFlags */);
    18551839        if (FAILED(hr))
    18561840        {
     
    18591843        }
    18601844
    1861         DWORD len1 = AUDIOMIXBUF_B2S(&pStream->MixBuf, cb1);
    1862         DWORD len2 = AUDIOMIXBUF_B2S(&pStream->MixBuf, cb2);
    1863 
    1864         uint32_t cSamplesWrittenTotal = 0;
    1865         uint32_t cSamplesWritten;
    1866         if (pv1 && len1)
    1867         {
    1868             rc = AudioMixBufWriteCirc(&pStream->MixBuf, pv1, cb1, &cSamplesWritten);
    1869             if (RT_SUCCESS(rc))
    1870                 cSamplesWrittenTotal += cSamplesWritten;
    1871         }
    1872 
    1873         if (   RT_SUCCESS(rc)
    1874             && cSamplesWrittenTotal == len1
    1875             && pv2 && len2)
    1876         {
    1877             rc = AudioMixBufWriteCirc(&pStream->MixBuf, pv2, cb2, &cSamplesWritten);
    1878             if (RT_SUCCESS(rc))
    1879                 cSamplesWrittenTotal += cSamplesWritten;
     1845        if (pv1 && cb1)
     1846        {
     1847            memcpy((uint8_t *)pvBuf + cbReadTotal, pv1, cb1);
     1848            cbReadTotal += cb1;
     1849        }
     1850
     1851        if (pv2 && cb2)
     1852        {
     1853            memcpy((uint8_t *)pvBuf + cbReadTotal, pv2, cb2);
     1854            cbReadTotal += cb2;
    18801855        }
    18811856
    18821857        directSoundCaptureUnlock(pDSCB, pv1, pv2, cb1, cb2);
    18831858
    1884         if (cSamplesWrittenTotal) /* Captured something? */
    1885             rc = AudioMixBufMixToParent(&pStream->MixBuf, cSamplesWrittenTotal, &cSamplesProcessed);
    1886 
    18871859        if (RT_SUCCESS(rc))
    18881860        {
    1889             pDSoundStream->idxSampleCaptureReadPos = (pDSoundStream->idxSampleCaptureReadPos + cSamplesProcessed)
    1890                                                    % pDSoundStream->cMaxSamplesInBuffer;
    1891             DSLOGF(("DSound: Capture %u (%u+%u), processed %RU32/%RU32\n",
    1892                     cSamplesToCapture, len1, len2, cSamplesProcessed, cSamplesWrittenTotal));
     1861            pDSoundStream->offCaptureBufRead = (pDSoundStream->offCaptureBufRead + cbReadTotal)
     1862                                             % pDSoundStream->cbCaptureBuf;
     1863            DSLOGF(("DSound: Captured %ld bytes (%RU32 total)\n", cbToCapture, cbReadTotal));
    18931864        }
    18941865
    18951866    } while (0);
    18961867
    1897     if (RT_FAILURE(rc))
     1868    if (RT_SUCCESS(rc))
     1869    {
     1870        if (pcbRead)
     1871            *pcbRead = cbReadTotal;
     1872    }
     1873    else
    18981874        dsoundUpdateStatusInternal(pThis);
    1899     else if (pcbRead)
    1900         *pcbRead = cSamplesProcessed;
    1901 
    1902     LogFlowFuncLeaveRC(rc);
     1875
    19031876    return rc;
    19041877}
     
    19101883    directSoundCaptureClose(pDSoundStream);
    19111884
    1912     pDSoundStream->idxSampleCaptureReadPos = 0;
    1913     pDSoundStream->cMaxSamplesInBuffer = 0;
     1885    pDSoundStream->offCaptureBufRead = 0;
     1886    pDSoundStream->cbCaptureBuf      = 0;
     1887
    19141888    RT_ZERO(pDSoundStream->streamCfg);
    19151889
  • trunk/src/VBox/Devices/Audio/DrvHostDebugAudio.cpp

    r63711 r65565  
    66
    77/*
    8  * Copyright (C) 2016 Oracle Corporation
     8 * Copyright (C) 2016-2017 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2626
    2727#include "DrvAudio.h"
    28 #include "AudioMixBuffer.h"
    2928#include "VBoxDD.h"
    3029
     
    5049            /** Timestamp of last played samples. */
    5150            uint64_t   tsLastPlayed;
    52             uint64_t   cMaxSamplesInPlayBuffer;
    5351            uint8_t   *pu8PlayBuffer;
     52            size_t     cbPlayBuffer;
    5453        } Out;
    5554    };
     55    PDMAUDIOPCMPROPS   Props;
    5656
    5757} DEBUGAUDIOSTREAM, *PDEBUGAUDIOSTREAM;
     
    128128    RT_NOREF(pInterface, pStream);
    129129
     130    PDEBUGAUDIOSTREAM pDbgStream = (PDEBUGAUDIOSTREAM)pStream;
     131
    130132    /* Just adopt the wanted stream configuration. */
    131     PDMAUDIOPCMPROPS Props;
    132     int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &Props);
     133    int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pDbgStream->Props);
    133134    if (RT_SUCCESS(rc))
    134135    {
     
    145146                                PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    146147{
    147     NOREF(pInterface);
     148    RT_NOREF(pInterface);
    148149
    149150    PDEBUGAUDIOSTREAM pDbgStream = (PDEBUGAUDIOSTREAM)pStream;
    150151
    151152    /* Just adopt the wanted stream configuration. */
    152     PDMAUDIOPCMPROPS Props;
    153     int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &Props);
     153    int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pDbgStream->Props);
    154154    if (RT_SUCCESS(rc))
    155155    {
    156         pDbgStream->Out.tsLastPlayed            = 0;
    157         pDbgStream->Out.cMaxSamplesInPlayBuffer = _1K;
    158         pDbgStream->Out.pu8PlayBuffer           = (uint8_t *)RTMemAlloc(pDbgStream->Out.cMaxSamplesInPlayBuffer << Props.cShift);
     156        pDbgStream->Out.tsLastPlayed  = 0;
     157        pDbgStream->Out.cbPlayBuffer  = _1K * PDMAUDIOPCMPROPS_S2B(&pDbgStream->Props, 1); /** @todo Make this configurable? */
     158        pDbgStream->Out.pu8PlayBuffer = (uint8_t *)RTMemAlloc(pDbgStream->Out.cbPlayBuffer);
    159159        if (!pDbgStream->Out.pu8PlayBuffer)
    160160            rc = VERR_NO_MEMORY;
     
    174174                rc = DrvAudioHlpWAVFileOpen(&pDbgStream->File, szFile,
    175175                                            RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE,
    176                                             &Props, PDMAUDIOFILEFLAG_NONE);
     176                                            &pDbgStream->Props, PDMAUDIOFILEFLAG_NONE);
    177177                if (RT_FAILURE(rc))
    178178                    LogRel(("DebugAudio: Creating output file '%s' failed with %Rrc\n", szFile, rc));
     
    188188    {
    189189        if (pCfgAcq)
    190             pCfgAcq->cSampleBufferSize = pDbgStream->Out.cMaxSamplesInPlayBuffer;
     190            pCfgAcq->cSampleBufferSize = PDMAUDIOPCMPROPS_B2S(&pDbgStream->Props, pDbgStream->Out.cbPlayBuffer);
    191191    }
    192192
     
    247247        cSamplesPlayed = cLive;*/
    248248
    249     uint32_t cSamplesPlayed = 0;
    250     uint32_t cSamplesAvail  = RT_MIN(AudioMixBufUsed(&pStream->MixBuf), pDbgStream->Out.cMaxSamplesInPlayBuffer);
    251     while (cSamplesAvail)
    252     {
    253         uint32_t cSamplesRead = 0;
    254         int rc2 = AudioMixBufReadCirc(&pStream->MixBuf, pDbgStream->Out.pu8PlayBuffer,
    255                                       AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesAvail), &cSamplesRead);
    256 
    257         if (RT_FAILURE(rc2))
    258             LogRel(("DebugAudio: Reading output failed with %Rrc\n", rc2));
    259 
    260         if (!cSamplesRead)
    261             break;
     249    uint32_t cbWritten = 0;
     250
     251    uint32_t cbAvail  = RT_MIN(cbBuf, pDbgStream->Out.cbPlayBuffer);
     252    while (cbAvail)
     253    {
     254        uint32_t cbChunk = cbAvail; /** @todo Use chunks? */
     255
     256        memcpy(pDbgStream->Out.pu8PlayBuffer, pvBuf, cbChunk);
    262257#if 0
    263258        RTFILE fh;
    264259        RTFileOpen(&fh, "/tmp/AudioDebug-Output.pcm",
    265260                   RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    266         RTFileWrite(fh, pDbgStream->Out.pu8PlayBuffer, AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesRead), NULL);
     261        RTFileWrite(fh, pDbgStream->Out.pu8PlayBuffer, cbChunk, NULL);
    267262        RTFileClose(fh);
    268263#endif
    269         rc2 = DrvAudioHlpWAVFileWrite(&pDbgStream->File,
    270                                       pDbgStream->Out.pu8PlayBuffer, AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesRead),
    271                                       0 /* fFlags */);
     264        int rc2 = DrvAudioHlpWAVFileWrite(&pDbgStream->File,
     265                                          pDbgStream->Out.pu8PlayBuffer, cbChunk, 0 /* fFlags */);
    272266        if (RT_FAILURE(rc2))
     267        {
    273268            LogRel(("DebugAudio: Writing output failed with %Rrc\n", rc2));
    274 
    275         AudioMixBufFinish(&pStream->MixBuf, cSamplesRead);
    276 
    277         Assert(cSamplesAvail >= cSamplesRead);
    278         cSamplesAvail -= cSamplesRead;
    279 
    280         cSamplesPlayed += cSamplesRead;
     269            break;
     270        }
     271
     272        Assert(cbAvail >= cbAvail);
     273        cbAvail   -= cbChunk;
     274
     275        cbWritten += cbChunk;
    281276    }
    282277
     
    285280
    286281    if (pcbWritten)
    287         *pcbWritten = cSamplesPlayed;
     282        *pcbWritten = cbWritten;
    288283
    289284    return VINF_SUCCESS;
  • trunk/src/VBox/Devices/Audio/DrvHostNullAudio.cpp

    r63711 r65565  
    66
    77/*
    8  * Copyright (C) 2006-2016 Oracle Corporation
     8 * Copyright (C) 2006-2017 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5454
    5555#include "DrvAudio.h"
    56 #include "AudioMixBuffer.h"
    5756#include "VBoxDD.h"
    5857
     
    6867    PDMAUDIOPCMPROPS    Props;
    6968    uint64_t            u64TicksLast;
    70     uint64_t            cMaxSamplesInPlayBuffer;
    71     uint8_t            *pbPlayBuffer;
    7269} NULLAUDIOSTREAMOUT;
    7370typedef NULLAUDIOSTREAMOUT *PNULLAUDIOSTREAMOUT;
     
    150147 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
    151148 */
    152 static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
     149static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
     150                                                    const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
    153151{
    154152    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    155153    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    156 
    157     RT_NOREF2(pvBuf, cbBuf);
     154    AssertPtrReturn(pvBuf,      VERR_INVALID_POINTER);
     155    AssertReturn(cbBuf,         VERR_INVALID_PARAMETER);
    158156
    159157    PDRVHOSTNULLAUDIO   pDrv        = RT_FROM_MEMBER(pInterface, DRVHOSTNULLAUDIO, IHostAudio);
     
    161159
    162160    /* Consume as many samples as would be played at the current frequency since last call. */
    163     uint32_t cLive           = AudioMixBufLive(&pStream->MixBuf);
     161    uint32_t csLive          = PDMAUDIOPCMPROPS_B2S(&pNullStream->Props, cbBuf);
    164162
    165163    uint64_t u64TicksNow     = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns);
     
    174172     * If rounding is not taken into account then the playback rate will be consistently lower that expected.
    175173     */
    176     uint64_t cSamplesPlayed = (2 * u64TicksElapsed * pNullStream->Props.uHz + u64TicksFreq) / u64TicksFreq / 2;
     174    uint64_t csPlayed = (2 * u64TicksElapsed * pNullStream->Props.uHz + u64TicksFreq) / u64TicksFreq / 2;
    177175
    178176    /* Don't play more than available. */
    179     if (cSamplesPlayed > cLive)
    180         cSamplesPlayed = cLive;
    181 
    182     cSamplesPlayed = RT_MIN(cSamplesPlayed, pNullStream->cMaxSamplesInPlayBuffer);
    183 
    184     uint32_t cSamplesToRead = 0;
    185     AudioMixBufReadCirc(&pStream->MixBuf, pNullStream->pbPlayBuffer,
    186                         AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesPlayed), &cSamplesToRead);
    187     AudioMixBufFinish(&pStream->MixBuf, cSamplesToRead);
     177    if (csPlayed > csLive)
     178        csPlayed = csLive;
     179
     180    /* Note: No copying of samples needed here, as this a NULL backend. */
    188181
    189182    if (pcbWritten)
    190         *pcbWritten = cSamplesToRead;
     183        *pcbWritten = PDMAUDIOPCMPROPS_S2B(&pNullStream->Props, csPlayed);
    191184
    192185    return VINF_SUCCESS;
     
    197190 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
    198191 */
    199 static DECLCALLBACK(int) drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    200 {
    201     RT_NOREF4(pInterface, pStream, pvBuf, cbBuf);
    202 
    203     /* Never capture anything. */
     192static DECLCALLBACK(int) drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface,
     193                                                       PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     194{
     195    RT_NOREF(pInterface, pStream);
     196
     197    RT_BZERO(pvBuf, cbBuf);
     198
     199    /* Return silent audio. */
    204200    if (pcbRead)
    205         *pcbRead = 0;
     201        *pcbRead = cbBuf;
    206202
    207203    return VINF_SUCCESS;
     
    221217    }
    222218
    223     LogFlowFuncLeaveRC(rc);
    224219    return rc;
    225220}
     
    235230    {
    236231        pNullStream->u64TicksLast  = 0;
    237         pNullStream->cMaxSamplesInPlayBuffer = _1K;
    238 
    239         pNullStream->pbPlayBuffer = (uint8_t *)RTMemAlloc(_1K << pNullStream->Props.cShift);
    240         if (pNullStream->pbPlayBuffer)
    241         {
    242             if (pCfgAcq)
    243                 pCfgAcq->cSampleBufferSize = pNullStream->cMaxSamplesInPlayBuffer;
    244         }
    245         else
    246             rc = VERR_NO_MEMORY;
     232
     233        if (pCfgAcq)
     234            pCfgAcq->cSampleBufferSize = _1K; /** @todo Make this configurable. */
    247235    }
    248236
    249     LogFlowFuncLeaveRC(rc);
    250237    return rc;
    251238}
     
    255242 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
    256243 */
    257 static DECLCALLBACK(int) drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     244static DECLCALLBACK(int) drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
     245                                                      PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    258246{
    259247    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    281269static int nullDestroyStreamOut(PPDMAUDIOSTREAM pStream)
    282270{
    283     PNULLAUDIOSTREAMOUT pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMOUT, Stream);
    284     if (   pNullStream
    285         && pNullStream->pbPlayBuffer)
    286     {
    287         RTMemFree(pNullStream->pbPlayBuffer);
    288         pNullStream->pbPlayBuffer = NULL;
    289     }
    290 
    291     LogFlowFuncLeaveRC(VINF_SUCCESS);
     271    RT_NOREF(pStream);
    292272    return VINF_SUCCESS;
    293273}
  • trunk/src/VBox/Devices/Audio/DrvHostOSSAudio.cpp

    r65037 r65565  
    55
    66/*
    7  * Copyright (C) 2014-2016 Oracle Corporation
     7 * Copyright (C) 2014-2017 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3131
    3232#include "DrvAudio.h"
    33 #include "AudioMixBuffer.h"
    34 
    3533#include "VBoxDD.h"
    3634
     
    373371        {
    374372            DrvAudioHlpClearBuf(&pStreamOut->Props, pStreamOut->pvBuf, pStreamOut->cbBuf,
    375                                 AUDIOMIXBUF_B2S(&pStream->MixBuf, pStreamOut->cbBuf));
     373                                PDMAUDIOPCMPROPS_B2S(&pStreamOut->Props, pStreamOut->cbBuf));
    376374
    377375            int mask = PCM_ENABLE_OUTPUT;
     
    431429    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    432430
    433     POSSAUDIOSTREAMIN pStrm = (POSSAUDIOSTREAMIN)pStream;
     431    POSSAUDIOSTREAMIN pStreamOSS = (POSSAUDIOSTREAMIN)pStream;
    434432
    435433    int rc = VINF_SUCCESS;
    436     size_t cbToRead = RT_MIN(pStrm->cbBuf,
    437                              AudioMixBufFreeBytes(&pStream->MixBuf));
    438 
    439     LogFlowFunc(("cbToRead=%zu\n", cbToRead));
    440 
    441     uint32_t cWrittenTotal = 0;
     434
     435    size_t cbToRead = RT_MIN(pStreamOSS->cbBuf, cbBuf);
     436
     437    LogFlowFunc(("cbToRead=%zi\n", cbToRead));
     438
     439    uint32_t cbReadTotal = 0;
    442440    uint32_t cbTemp;
    443441    ssize_t  cbRead;
     
    446444    while (cbToRead)
    447445    {
    448         cbTemp = RT_MIN(cbToRead, pStrm->cbBuf);
     446        cbTemp = RT_MIN(cbToRead, pStreamOSS->cbBuf);
    449447        AssertBreakStmt(cbTemp, rc = VERR_NO_DATA);
    450         cbRead = read(pStrm->hFile, (uint8_t *)pStrm->pvBuf + offWrite, cbTemp);
     448        cbRead = read(pStreamOSS->hFile, (uint8_t *)pStreamOSS->pvBuf, cbTemp);
    451449
    452450        LogFlowFunc(("cbRead=%zi, cbTemp=%RU32, cbToRead=%zu\n", cbRead, cbTemp, cbToRead));
     
    479477        else if (cbRead)
    480478        {
    481             uint32_t cWritten;
    482             rc = AudioMixBufWriteCirc(&pStream->MixBuf, pStrm->pvBuf, cbRead, &cWritten);
    483             if (RT_FAILURE(rc))
    484                 break;
    485 
    486             uint32_t cbWritten = AUDIOMIXBUF_S2B(&pStream->MixBuf, cWritten);
    487 
    488             Assert(cbToRead >= cbWritten);
    489             cbToRead      -= cbWritten;
    490             offWrite      += cbWritten;
    491             cWrittenTotal += cWritten;
     479            memcpy((uint8_t *)pvBuf + offWrite, pStreamOSS->pvBuf, cbRead);
     480
     481            Assert((ssize_t)cbToRead >= cbRead);
     482            cbToRead    -= cbRead;
     483            offWrite    += cbRead;
     484            cbReadTotal += cbRead;
    492485        }
    493486        else /* No more data, try next round. */
     
    500493    if (RT_SUCCESS(rc))
    501494    {
    502         uint32_t cProcessed = 0;
    503         if (cWrittenTotal)
    504             rc = AudioMixBufMixToParent(&pStream->MixBuf, cWrittenTotal, &cProcessed);
    505 
    506495        if (pcbRead)
    507             *pcbRead = cWrittenTotal;
    508 
    509         LogFlowFunc(("cWrittenTotal=%RU32 (%RU32 processed), rc=%Rrc\n",
    510                      cWrittenTotal, cProcessed, rc));
    511     }
    512 
    513     LogFlowFuncLeaveRC(rc);
     496            *pcbRead = cbReadTotal;
     497    }
     498
    514499    return rc;
    515500}
     
    859844    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    860845
    861     POSSAUDIOSTREAMOUT pStrm = (POSSAUDIOSTREAMOUT)pStream;
     846    POSSAUDIOSTREAMOUT pStreamOSS = (POSSAUDIOSTREAMOUT)pStream;
    862847
    863848    int rc = VINF_SUCCESS;
     
    870855    do
    871856    {
    872         size_t cbBufSize = AudioMixBufSizeBytes(&pStream->MixBuf);
    873 
    874         uint32_t csLive = AudioMixBufLive(&pStream->MixBuf);
    875         uint32_t csToRead;
     857        uint32_t cbAvail = PDMAUDIOPCMPROPS_S2B(&pStreamOSS->Props, cbBuf);
     858        uint32_t cbToRead;
    876859
    877860#ifndef RT_OS_L4
    878         if (pStrm->fMMIO)
     861        if (pStreamOSS->fMMIO)
    879862        {
    880863            /* Get current playback pointer. */
    881             int rc2 = ioctl(pStrm->hFile, SNDCTL_DSP_GETOPTR, &cntinfo);
     864            int rc2 = ioctl(pStreamOSS->hFile, SNDCTL_DSP_GETOPTR, &cntinfo);
    882865            if (!rc2)
    883866            {
     
    888871
    889872            /* Nothing to play? */
    890             if (cntinfo.ptr == pStrm->old_optr)
     873            if (cntinfo.ptr == pStreamOSS->old_optr)
    891874                break;
    892875
    893876            int cbData;
    894             if (cntinfo.ptr > pStrm->old_optr)
    895                 cbData = cntinfo.ptr - pStrm->old_optr;
     877            if (cntinfo.ptr > pStreamOSS->old_optr)
     878                cbData = cntinfo.ptr - pStreamOSS->old_optr;
    896879            else
    897                 cbData = cbBufSize + cntinfo.ptr - pStrm->old_optr;
    898             Assert(cbData);
    899 
    900             csToRead = RT_MIN((uint32_t)AUDIOMIXBUF_B2S(&pStream->MixBuf, cbData),
    901                              csLive);
     880                cbData = cbBuf + cntinfo.ptr - pStreamOSS->old_optr;
     881            Assert(cbData >= 0);
     882
     883            cbToRead = RT_MIN((unsigned)cbData, cbAvail);
    902884        }
    903885        else
     
    905887#endif
    906888            audio_buf_info abinfo;
    907             int rc2 = ioctl(pStrm->hFile, SNDCTL_DSP_GETOSPACE, &abinfo);
     889            int rc2 = ioctl(pStreamOSS->hFile, SNDCTL_DSP_GETOSPACE, &abinfo);
    908890            if (rc2 < 0)
    909891            {
     
    913895            }
    914896
    915             if ((size_t)abinfo.bytes > cbBufSize)
    916             {
    917                 LogRel2(("OSS: Warning: Too big output size (%d > %zu), limiting to %zu\n", abinfo.bytes, cbBufSize, cbBufSize));
    918                 abinfo.bytes = cbBufSize;
     897            if ((size_t)abinfo.bytes > cbBuf)
     898            {
     899                LogRel2(("OSS: Warning: Too big output size (%d > %RU32), limiting to %RU32\n", abinfo.bytes, cbBuf, cbBuf));
     900                abinfo.bytes = cbBuf;
    919901                /* Keep going. */
    920902            }
     
    922904            if (abinfo.bytes < 0)
    923905            {
    924                 LogRel2(("OSS: Warning: Invalid available size (%d vs. %zu)\n", abinfo.bytes, cbBufSize));
     906                LogRel2(("OSS: Warning: Invalid available size (%d vs. %RU32)\n", abinfo.bytes, cbBuf));
    925907                rc = VERR_INVALID_PARAMETER;
    926908                break;
    927909            }
    928910
    929             csToRead = RT_MIN((uint32_t)AUDIOMIXBUF_B2S(&pStream->MixBuf, abinfo.fragments * abinfo.fragsize), csLive);
    930             if (!csToRead)
    931                 break;
     911            cbToRead = RT_MIN(unsigned(abinfo.fragments * abinfo.fragsize), cbAvail);
    932912#ifndef RT_OS_L4
    933913        }
    934914#endif
    935         size_t cbToRead = RT_MIN(AUDIOMIXBUF_S2B(&pStream->MixBuf, csToRead), pStrm->cbBuf);
    936 
    937         uint32_t csRead, cbRead;
    938915        while (cbToRead)
    939916        {
    940             rc = AudioMixBufReadCirc(&pStream->MixBuf, pStrm->pvBuf, cbToRead, &csRead);
    941             if (RT_FAILURE(rc))
    942                 break;
    943 
    944             cbRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, csRead);
     917            uint32_t cbRead     = cbToRead;
     918
     919            memcpy(pStreamOSS->pvBuf, pvBuf, cbRead);
    945920
    946921            uint32_t cbChunk    = cbRead;
     
    948923            while (cbChunk)
    949924            {
    950                 ssize_t cbChunkWritten = write(pStrm->hFile, (uint8_t *)pStrm->pvBuf + cbChunkOff,
     925                ssize_t cbChunkWritten = write(pStreamOSS->hFile, (uint8_t *)pStreamOSS->pvBuf + cbChunkOff,
    951926                                               RT_MIN(cbChunk, (unsigned)s_OSSConf.fragsize));
    952927                if (cbChunkWritten < 0)
     
    957932                }
    958933
    959                 if (cbChunkWritten & pStrm->Props.uAlign)
     934                if (cbChunkWritten & pStreamOSS->Props.uAlign)
    960935                {
    961936                    LogRel(("OSS: Misaligned write (written %z, expected %RU32)\n", cbChunkWritten, cbChunk));
     
    976951#ifndef RT_OS_L4
    977952        /* Update read pointer. */
    978         if (pStrm->fMMIO)
    979             pStrm->old_optr = cntinfo.ptr;
     953        if (pStreamOSS->fMMIO)
     954            pStreamOSS->old_optr = cntinfo.ptr;
    980955#endif
    981956
     
    984959    if (RT_SUCCESS(rc))
    985960    {
    986         uint32_t cWrittenTotal = AUDIOMIXBUF_B2S(&pStream->MixBuf, cbWrittenTotal);
    987         if (cWrittenTotal)
    988             AudioMixBufFinish(&pStream->MixBuf, cWrittenTotal);
    989 
    990961        if (pcbWritten)
    991962            *pcbWritten = cbWrittenTotal;
    992963    }
    993964
    994     LogFlowFuncLeaveRC(rc);
    995965    return rc;
    996966}
  • trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp

    r65147 r65565  
    55
    66/*
    7  * Copyright (C) 2006-2016 Oracle Corporation
     7 * Copyright (C) 2006-2017 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3838
    3939#include "DrvAudio.h"
    40 #include "AudioMixBuffer.h"
    41 
    4240#include "VBoxDD.h"
    4341
     
    10199     *  Note: Always must come first! */
    102100    PDMAUDIOSTREAM         Stream;
     101    PDMAUDIOPCMPROPS       Props;
    103102    /** Pointer to driver instance. */
    104103    PDRVHOSTPULSEAUDIO     pDrv;
    105     /** DAC/ADC buffer. */
    106     void                  *pvPCMBuf;
    107     /** Size (in bytes) of DAC/ADC buffer. */
    108     uint32_t               cbPCMBuf;
    109104    /** Pointer to opaque PulseAudio stream. */
    110105    pa_stream             *pPAStream;
     
    657652                             PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    658653{
    659     PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
    660     PPULSEAUDIOSTREAM  pStrm = (PPULSEAUDIOSTREAM)pStream;
     654    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
     655    PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
    661656
    662657    LogFlowFuncEnter();
    663658
    664     pStrm->pDrainOp            = NULL;
    665 
    666     pStrm->SampleSpec.format   = paFmtToPulse(pCfgReq->enmFormat);
    667     pStrm->SampleSpec.rate     = pCfgReq->uHz;
    668     pStrm->SampleSpec.channels = pCfgReq->cChannels;
     659    pStreamPA->pDrainOp            = NULL;
     660
     661    pStreamPA->SampleSpec.format   = paFmtToPulse(pCfgReq->enmFormat);
     662    pStreamPA->SampleSpec.rate     = pCfgReq->uHz;
     663    pStreamPA->SampleSpec.channels = pCfgReq->cChannels;
    669664
    670665    /* Note that setting maxlength to -1 does not work on PulseAudio servers
    671666     * older than 0.9.10. So use the suggested value of 3/2 of tlength */
    672     pStrm->BufAttr.tlength     =   (pa_bytes_per_second(&pStrm->SampleSpec)
     667    pStreamPA->BufAttr.tlength     =   (pa_bytes_per_second(&pStreamPA->SampleSpec)
    673668                                        * s_pulseCfg.buffer_msecs_out) / 1000;
    674     pStrm->BufAttr.maxlength   = (pStrm->BufAttr.tlength * 3) / 2;
    675     pStrm->BufAttr.prebuf      = -1; /* Same as tlength */
    676     pStrm->BufAttr.minreq      = -1;
     669    pStreamPA->BufAttr.maxlength   = (pStreamPA->BufAttr.tlength * 3) / 2;
     670    pStreamPA->BufAttr.prebuf      = -1; /* Same as tlength */
     671    pStreamPA->BufAttr.minreq      = -1;
    677672
    678673    /* Note that the struct BufAttr is updated to the obtained values after this call! */
    679     int rc = paStreamOpen(pThis, false /* fIn */, "PulseAudio (Out)", &pStrm->SampleSpec, &pStrm->BufAttr, &pStrm->pPAStream);
     674    int rc = paStreamOpen(pThis, false /* fIn */, "PulseAudio (Out)", &pStreamPA->SampleSpec, &pStreamPA->BufAttr, &pStreamPA->pPAStream);
    680675    if (RT_FAILURE(rc))
    681676        return rc;
    682677
    683     rc = paPulseToFmt(pStrm->SampleSpec.format,
     678    rc = paPulseToFmt(pStreamPA->SampleSpec.format,
    684679                      &pCfgAcq->enmFormat, &pCfgAcq->enmEndianness);
    685680    if (RT_FAILURE(rc))
    686681    {
    687         LogRel(("PulseAudio: Cannot find audio output format %ld\n", pStrm->SampleSpec.format));
     682        LogRel(("PulseAudio: Cannot find audio output format %ld\n", pStreamPA->SampleSpec.format));
    688683        return rc;
    689684    }
    690685
    691     pCfgAcq->uHz       = pStrm->SampleSpec.rate;
    692     pCfgAcq->cChannels = pStrm->SampleSpec.channels;
    693 
    694     PDMAUDIOPCMPROPS Props;
    695     rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &Props);
     686    pCfgAcq->uHz       = pStreamPA->SampleSpec.rate;
     687    pCfgAcq->cChannels = pStreamPA->SampleSpec.channels;
     688
     689    rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStreamPA->Props);
    696690    if (RT_SUCCESS(rc))
    697691    {
    698         uint32_t cbBuf  = RT_MIN(pStrm->BufAttr.tlength * 2,
    699                                  pStrm->BufAttr.maxlength); /** @todo Make this configurable! */
     692        uint32_t cbBuf  = RT_MIN(pStreamPA->BufAttr.tlength * 2,
     693                                 pStreamPA->BufAttr.maxlength); /** @todo Make this configurable! */
    700694        if (cbBuf)
    701695        {
    702             pStrm->pvPCMBuf = RTMemAllocZ(cbBuf);
    703             if (pStrm->pvPCMBuf)
    704             {
    705                 pStrm->cbPCMBuf = cbBuf;
    706                 pStrm->pDrv     = pThis;
    707 
    708                 pCfgAcq->cSampleBufferSize = cbBuf >> Props.cShift;
    709             }
    710             else
    711                 rc = VERR_NO_MEMORY;
     696            pStreamPA->pDrv     = pThis;
     697
     698            pCfgAcq->cSampleBufferSize = PDMAUDIOPCMPROPS_B2S(&pStreamPA->Props, cbBuf);
    712699        }
    713700        else
     
    723710                            PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    724711{
    725     PDRVHOSTPULSEAUDIO pThis   = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
    726     PPULSEAUDIOSTREAM  pPAStrm = (PPULSEAUDIOSTREAM)pStream;
    727 
    728     pPAStrm->SampleSpec.format   = paFmtToPulse(pCfgReq->enmFormat);
    729     pPAStrm->SampleSpec.rate     = pCfgReq->uHz;
    730     pPAStrm->SampleSpec.channels = pCfgReq->cChannels;
     712    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
     713    PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
     714
     715    pStreamPA->SampleSpec.format   = paFmtToPulse(pCfgReq->enmFormat);
     716    pStreamPA->SampleSpec.rate     = pCfgReq->uHz;
     717    pStreamPA->SampleSpec.channels = pCfgReq->cChannels;
    731718
    732719    /** @todo Check these values! */
    733     pPAStrm->BufAttr.fragsize    = (pa_bytes_per_second(&pPAStrm->SampleSpec) * s_pulseCfg.buffer_msecs_in) / 1000;
    734     pPAStrm->BufAttr.maxlength   = (pPAStrm->BufAttr.fragsize * 3) / 2;
     720    pStreamPA->BufAttr.fragsize    = (pa_bytes_per_second(&pStreamPA->SampleSpec) * s_pulseCfg.buffer_msecs_in) / 1000;
     721    pStreamPA->BufAttr.maxlength   = (pStreamPA->BufAttr.fragsize * 3) / 2;
    735722
    736723    /* Note: Other members of BufAttr are ignored for record streams. */
    737     int rc = paStreamOpen(pThis, true /* fIn */, "PulseAudio (In)", &pPAStrm->SampleSpec, &pPAStrm->BufAttr,
    738                           &pPAStrm->pPAStream);
     724    int rc = paStreamOpen(pThis, true /* fIn */, "PulseAudio (In)", &pStreamPA->SampleSpec, &pStreamPA->BufAttr,
     725                          &pStreamPA->pPAStream);
    739726    if (RT_FAILURE(rc))
    740727        return rc;
    741728
    742     rc = paPulseToFmt(pPAStrm->SampleSpec.format, &pCfgAcq->enmFormat,
    743                       &pCfgAcq->enmEndianness);
     729    rc = paPulseToFmt(pStreamPA->SampleSpec.format, &pCfgAcq->enmFormat, &pCfgAcq->enmEndianness);
    744730    if (RT_FAILURE(rc))
    745731    {
    746         LogRel(("PulseAudio: Cannot find audio capture format %ld\n", pPAStrm->SampleSpec.format));
     732        LogRel(("PulseAudio: Cannot find audio capture format %ld\n", pStreamPA->SampleSpec.format));
    747733        return rc;
    748734    }
    749735
    750     PDMAUDIOPCMPROPS Props;
    751     rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &Props);
     736    rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStreamPA->Props);
    752737    if (RT_SUCCESS(rc))
    753738    {
    754         pPAStrm->pDrv       = pThis;
    755         pPAStrm->pu8PeekBuf = NULL;
    756 
    757         pCfgAcq->uHz               = pPAStrm->SampleSpec.rate;
    758         pCfgAcq->cChannels         = pPAStrm->SampleSpec.channels;
    759         pCfgAcq->cSampleBufferSize = RT_MIN(pPAStrm->BufAttr.fragsize * 10, pPAStrm->BufAttr.maxlength) >> Props.cShift;
     739        pStreamPA->pDrv       = pThis;
     740        pStreamPA->pu8PeekBuf = NULL;
     741
     742        pCfgAcq->uHz               = pStreamPA->SampleSpec.rate;
     743        pCfgAcq->cChannels         = pStreamPA->SampleSpec.channels;
     744        pCfgAcq->cSampleBufferSize = PDMAUDIOPCMPROPS_B2S(&pStreamPA->Props,
     745                                                          RT_MIN(pStreamPA->BufAttr.fragsize * 10, pStreamPA->BufAttr.maxlength));
    760746    }
    761747
     
    774760    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    775761    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     762    AssertPtrReturn(pvBuf,      VERR_INVALID_POINTER);
     763    AssertReturn(cbBuf,         VERR_INVALID_PARAMETER);
    776764    /* pcbRead is optional. */
    777765
    778     PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
    779     PPULSEAUDIOSTREAM  pStrm = (PPULSEAUDIOSTREAM)pStream;
     766    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
     767    PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
    780768
    781769    /* We should only call pa_stream_readable_size() once and trust the first value. */
    782770    pa_threaded_mainloop_lock(pThis->pMainLoop);
    783     size_t cbAvail = pa_stream_readable_size(pStrm->pPAStream);
     771    size_t cbAvail = pa_stream_readable_size(pStreamPA->pPAStream);
    784772    pa_threaded_mainloop_unlock(pThis->pMainLoop);
    785773
    786774    if (cbAvail == (size_t)-1)
    787         return paError(pStrm->pDrv, "Failed to determine input data size");
     775        return paError(pStreamPA->pDrv, "Failed to determine input data size");
    788776
    789777    /* If the buffer was not dropped last call, add what remains. */
    790     if (pStrm->pu8PeekBuf)
    791     {
    792         Assert(pStrm->cbPeekBuf >= pStrm->offPeekBuf);
    793         cbAvail += (pStrm->cbPeekBuf - pStrm->offPeekBuf);
     778    if (pStreamPA->pu8PeekBuf)
     779    {
     780        Assert(pStreamPA->cbPeekBuf >= pStreamPA->offPeekBuf);
     781        cbAvail += (pStreamPA->cbPeekBuf - pStreamPA->offPeekBuf);
    794782    }
    795783
     
    805793    int rc = VINF_SUCCESS;
    806794
    807     size_t cbToRead = RT_MIN(cbAvail, AudioMixBufFreeBytes(&pStream->MixBuf));
     795    size_t cbToRead = RT_MIN(cbAvail, cbBuf);
    808796
    809797    Log3Func(("cbToRead=%zu, cbAvail=%zu, offPeekBuf=%zu, cbPeekBuf=%zu\n",
    810               cbToRead, cbAvail, pStrm->offPeekBuf, pStrm->cbPeekBuf));
    811 
    812     uint32_t cWrittenTotal = 0;
     798              cbToRead, cbAvail, pStreamPA->offPeekBuf, pStreamPA->cbPeekBuf));
     799
     800    uint32_t cbReadTotal = 0;
    813801
    814802    while (cbToRead)
    815803    {
    816804        /* If there is no data, do another peek. */
    817         if (!pStrm->pu8PeekBuf)
     805        if (!pStreamPA->pu8PeekBuf)
    818806        {
    819807            pa_threaded_mainloop_lock(pThis->pMainLoop);
    820             pa_stream_peek(pStrm->pPAStream,
    821                            (const void**)&pStrm->pu8PeekBuf, &pStrm->cbPeekBuf);
     808            pa_stream_peek(pStreamPA->pPAStream,
     809                           (const void**)&pStreamPA->pu8PeekBuf, &pStreamPA->cbPeekBuf);
    822810            pa_threaded_mainloop_unlock(pThis->pMainLoop);
    823811
    824             pStrm->offPeekBuf = 0;
     812            pStreamPA->offPeekBuf = 0;
    825813
    826814            /* No data anymore?
    827815             * Note: If there's a data hole (cbPeekBuf then contains the length of the hole)
    828816             *       we need to drop the stream lateron. */
    829             if (   !pStrm->pu8PeekBuf
    830                 && !pStrm->cbPeekBuf)
     817            if (   !pStreamPA->pu8PeekBuf
     818                && !pStreamPA->cbPeekBuf)
    831819            {
    832820                break;
     
    834822        }
    835823
    836         Assert(pStrm->cbPeekBuf >= pStrm->offPeekBuf);
    837         size_t cbToWrite = RT_MIN(pStrm->cbPeekBuf - pStrm->offPeekBuf, cbToRead);
     824        Assert(pStreamPA->cbPeekBuf >= pStreamPA->offPeekBuf);
     825        size_t cbToWrite = RT_MIN(pStreamPA->cbPeekBuf - pStreamPA->offPeekBuf, cbToRead);
    838826
    839827        Log3Func(("cbToRead=%zu, cbToWrite=%zu, offPeekBuf=%zu, cbPeekBuf=%zu, pu8PeekBuf=%p\n",
    840828                  cbToRead, cbToWrite,
    841                   pStrm->offPeekBuf, pStrm->cbPeekBuf, pStrm->pu8PeekBuf));
     829                  pStreamPA->offPeekBuf, pStreamPA->cbPeekBuf, pStreamPA->pu8PeekBuf));
    842830
    843831        if (cbToWrite)
    844832        {
    845             uint32_t cWritten;
    846             rc = AudioMixBufWriteCirc(&pStream->MixBuf,
    847                                       pStrm->pu8PeekBuf + pStrm->offPeekBuf,
    848                                       cbToWrite, &cWritten);
    849             if (RT_FAILURE(rc))
    850                 break;
    851 
    852             uint32_t cbWritten = AUDIOMIXBUF_S2B(&pStream->MixBuf, cWritten);
    853 
    854             Assert(cbToRead >= cbWritten);
    855             cbToRead -= cbWritten;
    856             cWrittenTotal += cWritten;
    857             pStrm->offPeekBuf += cbWritten;
     833            memcpy((uint8_t *)pvBuf + cbReadTotal, pStreamPA->pu8PeekBuf + pStreamPA->offPeekBuf, cbToWrite);
     834
     835            Assert(cbToRead >= cbToWrite);
     836            cbToRead          -= cbToWrite;
     837            cbReadTotal       += cbToWrite;
     838
     839            pStreamPA->offPeekBuf += cbToWrite;
     840            Assert(pStreamPA->offPeekBuf <= pStreamPA->cbPeekBuf);
    858841        }
    859842
     
    861844               !cbToWrite
    862845            /* Was there a hole in the peeking buffer? Drop it. */
    863             || !pStrm->pu8PeekBuf
     846            || !pStreamPA->pu8PeekBuf
    864847            /* If the buffer is done, drop it. */
    865             || pStrm->offPeekBuf == pStrm->cbPeekBuf)
     848            || pStreamPA->offPeekBuf == pStreamPA->cbPeekBuf)
    866849        {
    867850            pa_threaded_mainloop_lock(pThis->pMainLoop);
    868             pa_stream_drop(pStrm->pPAStream);
     851            pa_stream_drop(pStreamPA->pPAStream);
    869852            pa_threaded_mainloop_unlock(pThis->pMainLoop);
    870853
    871             pStrm->pu8PeekBuf = NULL;
     854            pStreamPA->pu8PeekBuf = NULL;
    872855        }
    873856    }
     
    875858    if (RT_SUCCESS(rc))
    876859    {
    877         uint32_t cProcessed = 0;
    878         if (cWrittenTotal)
    879             rc = AudioMixBufMixToParent(&pStream->MixBuf, cWrittenTotal, &cProcessed);
    880 
    881860        if (pcbRead)
    882             *pcbRead = cWrittenTotal;
    883 
    884         Log3Func(("cWrittenTotal=%RU32 (%RU32 processed), rc=%Rrc\n",
    885                   cWrittenTotal, cProcessed, rc));
    886     }
    887 
    888     if (RT_FAILURE(rc))
    889         LogFunc(("Failed with %Rrc\n", rc));
     861            *pcbRead = cbReadTotal;
     862    }
    890863
    891864    return rc;
     
    903876    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    904877    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     878    AssertPtrReturn(pvBuf,      VERR_INVALID_POINTER);
     879    AssertReturn(cbBuf,         VERR_INVALID_PARAMETER);
    905880    /* pcbWritten is optional. */
    906881
     
    909884
    910885    int rc = VINF_SUCCESS;
    911     uint32_t cbReadTotal = 0;
    912 
    913     uint32_t cLive = AudioMixBufUsed(&pStream->MixBuf);
    914     if (!cLive)
    915     {
    916         Log3Func(("No live samples, skipping\n"));
    917         if (pcbWritten)
    918             *pcbWritten = 0;
    919         return VINF_SUCCESS;
    920     }
     886
     887    uint32_t cbWrittenTotal = 0;
    921888
    922889    pa_threaded_mainloop_lock(pThis->pMainLoop);
     
    931898        }
    932899
    933         size_t cbLive   = AUDIOMIXBUF_S2B(&pStream->MixBuf, cLive);
    934         size_t cbToRead = RT_MIN(cbWriteable, cbLive);
    935 
    936         Log3Func(("cbToRead=%zu, cbWriteable=%zu, cbLive=%zu\n",
    937                   cbToRead, cbWriteable, cbLive));
    938 
    939         uint32_t cRead, cbRead;
    940         while (cbToRead)
    941         {
    942             rc = AudioMixBufReadCirc(&pStream->MixBuf, pPAStream->pvPCMBuf,
    943                                      RT_MIN(cbToRead, pPAStream->cbPCMBuf), &cRead);
    944             if (   !cRead
    945                 || RT_FAILURE(rc))
    946             {
    947                 break;
    948             }
    949 
    950             cbRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, cRead);
    951             if (pa_stream_write(pPAStream->pPAStream, pPAStream->pvPCMBuf, cbRead, NULL /* Cleanup callback */,
     900        size_t cbToWrite = RT_MIN(cbWriteable, cbBuf);
     901
     902        uint32_t cbWritten;
     903        while (cbToWrite)
     904        {
     905            cbWritten = cbToWrite;
     906            if (pa_stream_write(pPAStream->pPAStream, (uint8_t *)pvBuf + cbWrittenTotal, cbWritten, NULL /* Cleanup callback */,
    952907                                0, PA_SEEK_RELATIVE) < 0)
    953908            {
     
    956911            }
    957912
    958             Assert(cbToRead >= cbRead);
    959             cbToRead    -= cbRead;
    960             cbReadTotal += cbRead;
    961 
    962             Log3Func(("\tcRead=%RU32 (%zu bytes) cbReadTotal=%RU32, cbToRead=%RU32\n",
    963                       cRead, AUDIOMIXBUF_S2B(&pStream->MixBuf, cRead), cbReadTotal, cbToRead));
     913            Assert(cbToWrite >= cbWritten);
     914            cbToWrite      -= cbWritten;
     915            cbWrittenTotal += cbWritten;
    964916        }
    965917
     
    970922    if (RT_SUCCESS(rc))
    971923    {
    972         uint32_t cReadTotal = AUDIOMIXBUF_B2S(&pStream->MixBuf, cbReadTotal);
    973         if (cReadTotal)
    974             AudioMixBufFinish(&pStream->MixBuf, cReadTotal);
    975 
    976924        if (pcbWritten)
    977             *pcbWritten = cReadTotal;
    978 
    979         Log3Func(("cReadTotal=%RU32 (%RU32 bytes), rc=%Rrc\n", cReadTotal, cbReadTotal, rc));
    980     }
    981 
    982     if (RT_FAILURE(rc))
    983         LogFunc(("Failed with %Rrc\n", rc));
     925            *pcbWritten = cbWrittenTotal;
     926    }
    984927
    985928    return rc;
     
    12301173
    12311174        pa_threaded_mainloop_unlock(pThis->pMainLoop);
    1232     }
    1233 
    1234     if (pStrm->pvPCMBuf)
    1235     {
    1236         RTMemFree(pStrm->pvPCMBuf);
    1237         pStrm->pvPCMBuf = NULL;
    1238         pStrm->cbPCMBuf = 0;
    12391175    }
    12401176
  • trunk/src/VBox/Devices/Audio/DrvHostValidationKit.cpp

    r64510 r65565  
    55
    66/*
    7  * Copyright (C) 2016 Oracle Corporation
     7 * Copyright (C) 2016-2017 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2525
    2626#include "DrvAudio.h"
    27 #include "AudioMixBuffer.h"
    2827#include "VBoxDD.h"
    2928
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