Changeset 89883 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Jun 24, 2021 11:13:31 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHdaStream.cpp
r89880 r89883 25 25 #include <iprt/mem.h> 26 26 #include <iprt/semaphore.h> 27 #include <iprt/zero.h> 27 28 28 29 #include <VBox/AssertGuest.h> … … 1416 1417 * The DMA copy loop. 1417 1418 * 1418 */ 1419 uint8_t abBounce[4096 + 128]; /* Most guest does at most 4KB BDLE. So, 4KB + space for a partial frame to reduce loops. */ 1420 uint32_t cbBounce = 0; /* in case of incomplete frames between buffer segments */ 1419 * Note! Unaligned BDLEs shouldn't be a problem since the circular buffer 1420 * doesn't care about alignment. Only, we have to read the rest 1421 * of the incomplete frame from it ASAP. 1422 */ 1421 1423 PRTCIRCBUF pCircBuf = pStreamR3->State.pCircBuf; 1422 1424 uint32_t cbLeft = cbToConsume; … … 1434 1436 RTGCPHYS GCPhys = hdaStreamDmaBufGet(pStreamShared, &cbChunk); 1435 1437 1438 if (cbChunk <= cbLeft) 1439 { /* very likely */ } 1440 else 1441 cbChunk = cbLeft; 1442 1436 1443 /* If we're writing silence. */ 1437 1444 uint32_t cbWritten = 0; 1438 1445 if (!fWriteSilence) 1439 1446 { 1440 if (cbChunk <= cbLeft)1441 { /* very likely */ }1442 else1443 cbChunk = cbLeft;1444 1445 1447 /* 1446 1448 * Write the host data directly into the guest buffers. … … 1480 1482 } 1481 1483 /* 1482 * We've got some initial silence to write, or we need to do 1483 * channel mapping. We produce guest output into the bounce buffer, 1484 * which is then copied into guest memory. The bounce buffer may keep 1485 * partial frames there for the next BDLE, if an BDLE isn't frame aligned. 1486 * 1487 * Note! cbLeft is relative to the input (host) frame size. 1488 * cbChunk OTOH is relative to output (guest) size. 1484 * Write silence. Since we only do signed formats, we can use the zero 1485 * buffers from IPRT as source here. 1489 1486 */ 1490 1487 else 1491 1488 { 1492 /** @todo clean up host/guest props distinction, they're the same now w/o the 1493 * mapping done by the mixer rather than us. */ 1494 PCPDMAUDIOPCMPROPS pGuestProps = &pStreamShared->State.Cfg.Props; 1495 Assert(PDMAudioPropsIsSizeAligned(&pStreamShared->State.Cfg.Props, cbLeft)); 1496 uint32_t const cbLeftGuest = PDMAudioPropsFramesToBytes(pGuestProps, 1497 PDMAudioPropsBytesToFrames(&pStreamShared->State.Cfg.Props, 1498 cbLeft)); 1499 if (cbChunk <= cbLeftGuest) 1500 { /* very likely */ } 1501 else 1502 cbChunk = cbLeftGuest; 1503 1504 /* 1505 * Work till we've covered the chunk. 1506 */ 1507 Log5Func(("loop0: GCPhys=%RGp cbChunk=%#x + cbBounce=%#x\n", GCPhys, cbChunk, cbBounce)); 1489 Assert(PDMAudioPropsIsSigned(&pStreamShared->State.Cfg.Props)); 1508 1490 while (cbChunk > 0) 1509 1491 { 1510 /* Figure out how much we need to convert into the bounce buffer: */1511 uint32_t cbGuest = PDMAudioPropsRoundUpBytesToFrame(pGuestProps, cbChunk - cbBounce);1512 uint32_t cFrames = PDMAudioPropsBytesToFrames(pGuestProps, RT_MIN(cbGuest, sizeof(abBounce) - cbBounce));1513 1514 cbGuest = PDMAudioPropsFramesToBytes(pGuestProps, cFrames);1515 PDMAudioPropsClearBuffer(pGuestProps, &abBounce[cbBounce], cbGuest, cFrames);1516 cbGuest += cbBounce;1517 1518 1492 /* Write it to the guest buffer. */ 1519 uint32_t cb GuestActual = RT_MIN(cbGuest, cbChunk);1520 int rc2 = PDMDevHlpPCIPhysWrite(pDevIns, GCPhys, abBounce, cbGuestActual);1493 uint32_t cbToWrite = RT_MIN(sizeof(g_abRTZero64K), cbChunk); 1494 int rc2 = PDMDevHlpPCIPhysWrite(pDevIns, GCPhys, g_abRTZero64K, cbToWrite); 1521 1495 AssertRC(rc2); 1522 STAM_COUNTER_ADD(&pThis->StatBytesWritten, cb GuestActual);1496 STAM_COUNTER_ADD(&pThis->StatBytesWritten, cbToWrite); 1523 1497 1524 1498 /* advance */ 1525 cbWritten += cbGuestActual; 1526 cbChunk -= cbGuestActual; 1527 GCPhys += cbGuestActual; 1528 pStreamShared->State.offCurBdle += cbGuestActual; 1529 1530 cbBounce = cbGuest - cbGuestActual; 1531 if (cbBounce) 1532 memmove(abBounce, &abBounce[cbGuestActual], cbBounce); 1533 1534 Log5Func((" loop1: GCPhys=%RGp cbGuestActual=%#x cbBounce=%#x cFrames=%#x\n", GCPhys, cbGuestActual, cbBounce, cFrames)); 1499 cbWritten += cbToWrite; 1500 cbChunk -= cbToWrite; 1501 GCPhys += cbToWrite; 1502 pStreamShared->State.offCurBdle += cbToWrite; 1535 1503 } 1536 Log5Func(("loop0: GCPhys=%RGp cbBounce=%#x cbLeft=%#x\n", GCPhys, cbBounce, cbLeft - cbWritten));1537 1504 } 1538 1505 … … 1554 1521 1555 1522 Assert(cbLeft == 0); /* There shall be no break statements in the above loop, so cbLeft is always zero here! */ 1556 AssertMsg(cbBounce == 0, ("%#x\n", cbBounce));1557 1523 1558 1524 /*
Note:
See TracChangeset
for help on using the changeset viewer.