VirtualBox

Changeset 65660 in vbox for trunk/src


Ignore:
Timestamp:
Feb 7, 2017 1:53:14 PM (8 years ago)
Author:
vboxsync
Message:

Audio: Added PDMAUDIOSTREAMLAYOUT_RAW to pass the raw audio data to the VRDP backend.

Location:
trunk/src/VBox
Files:
2 edited

Legend:

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

    r65627 r65660  
    599599                                      PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgHost, PPDMAUDIOSTREAMCFG pCfgGuest)
    600600{
    601     AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
    602     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
     601    AssertPtrReturn(pThis,     VERR_INVALID_POINTER);
     602    AssertPtrReturn(pStream,   VERR_INVALID_POINTER);
     603    AssertPtrReturn(pCfgHost,  VERR_INVALID_POINTER);
     604    AssertPtrReturn(pCfgGuest, VERR_INVALID_POINTER);
    603605
    604606    PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
     
    609611     * Init host stream.
    610612     */
     613
     614    /* Set the host's default audio data layout. */
     615    pCfgHost->enmLayout = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    611616
    612617#ifdef DEBUG
     
    631636#else
    632637    LogRel2(("Audio: Acquired %s host format for '%s': %RU32Hz, %RU8%s, %RU8 %s\n",
    633              pCfgGuest->enmDir == PDMAUDIODIR_IN ? "recording" : "playback",  pStream->szName,
    634              pCfgHost->Props.uHz, pCfgHost->Props.cBits, pCfgHost->Props.fSigned ? "S" : "U",
     638             CfgHostAcq.enmDir == PDMAUDIODIR_IN ? "recording" : "playback",  pStream->szName,
     639             CfgHostAcq.Props.uHz, CfgHostAcq.Props.cBits, CfgHostAcq.Props.fSigned ? "S" : "U",
    635640             CfgHostAcq.Props.cChannels, CfgHostAcq.Props.cChannels == 0 ? "Channel" : "Channels"));
    636641#endif
     
    658663
    659664    /* Make a copy of the acquired host stream configuration. */
    660     rc2 = DrvAudioHlpStreamCfgCopy(&pHstStream->Cfg, pCfgHost);
     665    rc2 = DrvAudioHlpStreamCfgCopy(&pHstStream->Cfg, &CfgHostAcq);
    661666    AssertRC(rc2);
    662667
     
    667672    /* Destroy any former mixing buffer. */
    668673    AudioMixBufDestroy(&pGstStream->MixBuf);
     674
     675    /* Set the guests's default audio data layout. */
     676    pCfgHost->enmLayout = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    669677
    670678    /* Make sure to (re-)set the guest buffer's shift size. */
     
    13051313            && (stsBackend & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE))
    13061314        {
    1307             uint8_t u8Buf[_4K]; /** @todo Get rid of this here. */
    1308 
    1309             uint32_t cRead = 0;
    1310             int rc2 = AudioMixBufReadCirc(&pHstStream->MixBuf, u8Buf, sizeof(u8Buf), &cRead);
    1311             AssertRC(rc2);
    1312 
    1313             uint32_t cbBuf = AUDIOMIXBUF_S2B(&pHstStream->MixBuf, cRead);
    13141315            uint32_t cbPlayed = 0;
    13151316
    13161317            AssertPtr(pThis->pHostDrvAudio->pfnStreamPlay);
    1317             rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream->pvBackend, u8Buf, cbBuf, &cbPlayed);
     1318
     1319            if (RT_LIKELY(pHstStream->Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED))
     1320            {
     1321                uint8_t u8Buf[_4K]; /** @todo Get rid of this here. */
     1322
     1323                uint32_t csRead = 0;
     1324                int rc2 = AudioMixBufReadCirc(&pHstStream->MixBuf, u8Buf, sizeof(u8Buf), &csRead);
     1325                AssertRC(rc2);
     1326
     1327                rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream->pvBackend,
     1328                                                         u8Buf, AUDIOMIXBUF_S2B(&pHstStream->MixBuf, csRead),
     1329                                                         &cbPlayed);
     1330                AssertMsg(cbPlayed % 2 == 0,
     1331                          ("Backend for stream '%s' returned uneven played bytes count (csRead=%RU32, cbPlayed=%RU32)\n",
     1332                           pHstStream->szName, csRead, cbPlayed));
     1333
     1334                csPlayed = AUDIOMIXBUF_B2S(&pHstStream->MixBuf, cbPlayed);
     1335            }
     1336            else if (pHstStream->Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_RAW)
     1337            {
     1338                PDMAUDIOSAMPLE aSampleBuf[128]; /** @todo Get rid of this here. */
     1339
     1340                uint32_t csRead = 0;
     1341                int rc2 = AudioMixBufPeek(&pHstStream->MixBuf, csLive, aSampleBuf,
     1342                                          RT_MIN(csLive, RT_ELEMENTS(aSampleBuf)), &csRead);
     1343                AssertRC(rc2);
     1344
     1345                Assert(csRead <= RT_ELEMENTS(aSampleBuf));
     1346
     1347                rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream->pvBackend,
     1348                                                         aSampleBuf, csRead, &csPlayed);
     1349            }
     1350            else
     1351                AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
     1352
    13181353            if (RT_SUCCESS(rc))
    13191354            {
    1320                 AssertMsg(cbPlayed % 2 == 0,
    1321                           ("Backend for stream '%s' returned uneven played bytes count (%RU32)\n", pHstStream->szName, cbPlayed));
    1322 
    1323                 csPlayed = AUDIOMIXBUF_B2S(&pHstStream->MixBuf, cbPlayed);
    1324 
    13251355                AudioMixBufFinish(&pHstStream->MixBuf, csPlayed);
    13261356
  • trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp

    r65624 r65660  
    8282} VRDESTREAM, *PVRDESTREAM;
    8383
     84/* Sanity. */
     85AssertCompileSize(PDMAUDIOSAMPLE, sizeof(int64_t) * 2 /* st_sample_t using by VRDP server */);
    8486
    8587static int vrdeCreateStreamIn(PVRDESTREAM pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     
    9193    {
    9294        if (pCfgAcq)
     95        {
     96            /*
     97             * Because of historical reasons the VRDP server operates on st_sample_t structures internally,
     98             * which is 2 * int64_t for left/right (stereo) channels.
     99             *
     100             * As the audio connector also uses this format, set the layout to "raw" and just let pass through
     101             * the data without any layout modification needed.
     102             */
     103            pCfgAcq->enmLayout         = PDMAUDIOSTREAMLAYOUT_RAW;
    93104            pCfgAcq->cSampleBufferHint = pStreamVRDE->In.cSamplesMax;
     105        }
    94106    }
    95107
     
    103115
    104116    if (pCfgAcq)
     117    {
     118        /*
     119         * Because of historical reasons the VRDP server operates on st_sample_t structures internally,
     120         * which is 2 * int64_t for left/right (stereo) channels.
     121         *
     122         * As the audio connector also uses this format, set the layout to "raw" and just let pass through
     123         * the data without any layout modification needed.
     124         */
     125        pCfgAcq->enmLayout         = PDMAUDIOSTREAMLAYOUT_RAW;
    105126        pCfgAcq->cSampleBufferHint = _4K; /** @todo Make this configurable. */
     127    }
    106128
    107129    return VINF_SUCCESS;
     
    241263    PVRDESTREAM   pStreamVRDE = (PVRDESTREAM)pStream;
    242264
    243     uint32_t cbLive           = cbBuf;
     265    /* Note: We get the number of *samples* in cbBuf
     266     *       (since we specified PDMAUDIOSTREAMLAYOUT_RAW as the audio data layout) on stream creation. */
     267    uint32_t csLive           = cbBuf;
    244268
    245269    uint64_t now              = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns);
     
    250274
    251275    /* Minimize the rounding error: samples = int((ticks * freq) / ticks_per_second + 0.5). */
    252     uint32_t cbToWrite = (int)((2 * ticks * pProps->uHz + ticks_per_second) / ticks_per_second / 2);
     276    uint32_t csToWrite = (int)((2 * ticks * pProps->uHz + ticks_per_second) / ticks_per_second / 2);
    253277
    254278    /* Remember when samples were consumed. */
     
    260284                                                 pProps->fSigned);
    261285
    262     Log2Func(("uFreq=%RU32, cChan=%RU8, cBits=%RU8, fSigned=%RTbool, enmFormat=%ld, cbLive=%RU32, cbToWrite=%RU32\n",
    263               pProps->uHz,   pProps->cChannels, pProps->cBits, pProps->fSigned, format, cbLive, cbToWrite));
     286    Log3Func(("uFreq=%RU32, cChan=%RU8, cBits=%RU8 (%d BPP), fSigned=%RTbool, enmFormat=%ld, csLive=%RU32, csToWrite=%RU32\n",
     287              pProps->uHz, pProps->cChannels, pProps->cBits, VRDE_AUDIO_FMT_BYTES_PER_SAMPLE(format),
     288              pProps->fSigned, format, csLive, csToWrite));
    264289
    265290    /* Don't play more than available. */
    266     if (cbToWrite > cbLive)
    267         cbToWrite = cbLive;
     291    if (csToWrite > csLive)
     292        csToWrite = csLive;
    268293
    269294    int rc = VINF_SUCCESS;
     
    272297     * Call the VRDP server with the data.
    273298     */
    274     uint32_t cbWritten = 0;
    275     while (cbToWrite)
    276     {
    277         /* Make sure that this is even, as we send the number of samples to the VRDP server. */
    278         uint32_t cbChunk = (cbToWrite % 2 == 0) ? cbToWrite : cbToWrite - 1; /** @todo For now write all at once. */
    279         Assert(cbChunk % 2 == 0);
    280 
    281         if (!cbChunk) /* Nothing to send. Bail out. */
     299    uint32_t csWritten = 0;
     300    while (csToWrite)
     301    {
     302        uint32_t csChunk = csToWrite; /** @todo For now write all at once. */
     303
     304        if (!csChunk) /* Nothing to send. Bail out. */
    282305            break;
    283306
    284         pDrv->pConsoleVRDPServer->SendAudioSamples((uint8_t *)pvBuf + cbWritten,
    285                                                    PDMAUDIOSTREAMCFG_B2S(pStreamVRDE->pCfg, cbChunk) /* Samples */, format);
    286         cbWritten += cbChunk;
    287         Assert(cbWritten <= cbBuf);
    288 
    289         Assert(cbToWrite >= cbChunk);
    290         cbToWrite -= cbChunk;
     307        /* Note: The VRDP server expects int64_t samples per channel, regardless of the actual
     308         *       sample bits (e.g 8 or 16 bits). */
     309        pDrv->pConsoleVRDPServer->SendAudioSamples((PPDMAUDIOSAMPLE)pvBuf + csWritten, csChunk /* Samples */, format);
     310
     311        csWritten += csChunk;
     312        Assert(csWritten <= csLive);
     313
     314        Assert(csToWrite >= csChunk);
     315        csToWrite -= csChunk;
    291316    }
    292317
    293318    if (RT_SUCCESS(rc))
    294319    {
    295         Assert(cbWritten % 2 == 0); /* Paranoia. */
    296 
     320        /* Return samples instead of bytes here
     321         * (since we specified PDMAUDIOSTREAMLAYOUT_RAW as the audio data layout). */
    297322        if (pcbWritten)
    298             *pcbWritten = cbWritten;
     323            *pcbWritten = csWritten;
    299324    }
    300325
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