VirtualBox

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


Ignore:
Timestamp:
Aug 14, 2018 11:46:40 AM (6 years ago)
Author:
vboxsync
Message:

Audio/AC97: Make sure to process as much data as needed, depending on the device Hertz rate and the stream's current PCM parameters. This is needed to keep the DMA running at a constant rate, which in turn will also affect the guest.

File:
1 edited

Legend:

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

    r73649 r73650  
    324324    /** Timestamp (in ns) of last DMA buffer read / write. */
    325325    uint64_t              tsLastReadWriteNs;
     326    /** Timestamp (in ns) of last stream update. */
     327    uint64_t              tsLastUpdateNs;
    326328} AC97STREAMSTATE;
    327329AssertCompileSizeAlignment(AC97STREAMSTATE, 8);
     
    14381440    if (pStream->u8SD == AC97SOUNDSOURCE_PO_INDEX) /* Output (SDO). */
    14391441    {
    1440         /* Is the AC'97 stream ready to be written (guest output data) to? If so, by how much? */
    1441         const uint32_t cbFree = ichac97R3StreamGetFree(pStream);
     1442        const uint64_t deltaLastUpdateNs = RTTimeNanoTS() - pStream->State.tsLastUpdateNs;
     1443
     1444        pStream->State.tsLastUpdateNs = RTTimeNanoTS();
     1445
     1446        PPDMAUDIOPCMPROPS pProps = &pStream->State.Cfg.Props;
     1447
     1448        /* Make sure that we don't transfer more than we need for this slot. */
     1449        uint32_t cbToTransfer = DrvAudioHlpMilliToBytes(pStream->State.Cfg.Device.uSchedulingHintMs, pProps);
     1450
     1451        /* Make sure that the transfer is frame-aligned.
     1452         * Add one additional frame to not transfer too little because of the alignment;
     1453         * ichac97R3StreamTransfer() will take care of clamping to the correct value then. */
     1454        cbToTransfer = DrvAudioHlpBytesAlign(cbToTransfer, pProps) + PDMAUDIOPCMPROPS_F2B(pProps, 1 /* Frame */);
     1455
     1456        Log3Func(("[SD%RU8] cbToTransfer=%RU32, deltaLastUpdateNs=%RU64\n", pStream->u8SD, cbToTransfer, deltaLastUpdateNs / RT_NS_1MS));
    14421457
    14431458        if (   fInTimer
    1444             && cbFree)
    1445         {
    1446             Log3Func(("[SD%RU8] cbFree=%RU32\n", pStream->u8SD, cbFree));
    1447 
     1459            && cbToTransfer)
     1460        {
    14481461            /* Do the DMA transfer. */
    1449             rc2 = ichac97R3StreamTransfer(pThis, pStream, cbFree);
     1462            rc2 = ichac97R3StreamTransfer(pThis, pStream, cbToTransfer);
    14501463            AssertRC(rc2);
    14511464        }
    14521465
    1453         /* How much (guest output) data is available at the moment for the AC'97 stream? */
    1454         uint32_t cbUsed = ichac97R3StreamGetUsed(pStream);
     1466        /* Make sure that we don't write more than we need for this slot. */
     1467        uint32_t cbToWrite = RT_MIN(cbToTransfer, ichac97R3StreamGetUsed(pStream));
     1468
     1469        /* Make sure that the write is byte-aligned. */
     1470        cbToWrite = DrvAudioHlpBytesAlign(cbToWrite, pProps);
     1471
     1472        Log3Func(("[SD%RU8] cbToWrite=%RU32, deltaLastUpdateNs=%RU64\n", pStream->u8SD, cbToWrite, deltaLastUpdateNs / RT_NS_1MS));
    14551473
    14561474# ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
    14571475        if (   fInTimer
    1458             && cbUsed)
     1476            && cbToWrite)
    14591477        {
    14601478            rc2 = ichac97R3StreamAsyncIONotify(pThis, pStream);
     
    14641482# endif
    14651483        {
    1466             const uint32_t cbSinkWritable = AudioMixerSinkGetWritable(pSink);
    1467 
    1468             /* Do not write more than the sink can hold at the moment.
    1469              * The host sets the overall pace. */
    1470             if (cbUsed > cbSinkWritable)
    1471                 cbUsed = cbSinkWritable;
    1472 
    1473             if (cbUsed)
     1484            if (cbToWrite)
    14741485            {
    14751486                /* Read (guest output) data and write it to the stream's sink. */
    14761487                uint32_t cbRead;
    1477                 rc2 = ichac97R3StreamRead(pThis, pStream, pSink, cbUsed, &cbRead);
     1488                rc2 = ichac97R3StreamRead(pThis, pStream, pSink, cbToWrite, &cbRead);
    14781489                AssertRC(rc2);
    14791490            }
     
    15041515
    15051516            /* How much (guest input) data is free at the moment? */
    1506             uint32_t cbFree = ichac97R3StreamGetFree(pStream);
    1507 
    1508             Log3Func(("[SD%RU8] cbReadable=%RU32, cbFree=%RU32\n", pStream->u8SD, cbReadable, cbFree));
     1517            uint32_t cbToTransfer = ichac97R3StreamGetFree(pStream);
     1518
     1519            Log3Func(("[SD%RU8] cbReadable=%RU32, cbFree=%RU32\n", pStream->u8SD, cbReadable, cbToTransfer));
    15091520
    15101521            /* Do not read more than the sink can provide at the moment.
    15111522             * The host sets the overall pace. */
    1512             if (cbFree > cbReadable)
    1513                 cbFree = cbReadable;
    1514 
    1515             if (cbFree)
     1523            if (cbToTransfer > cbReadable)
     1524                cbToTransfer = cbReadable;
     1525
     1526            if (cbToTransfer)
    15161527            {
    15171528                /* Write (guest input) data to the stream which was read from stream's sink before. */
    1518                 rc2 = ichac97R3StreamWrite(pThis, pStream, pSink, cbFree, NULL /* pcbWritten */);
     1529                rc2 = ichac97R3StreamWrite(pThis, pStream, pSink, cbToTransfer, NULL /* pcbWritten */);
    15191530                AssertRC(rc2);
    15201531            }
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