Changeset 65740 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Feb 10, 2017 4:16:21 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 113455
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r65699 r65740 1316 1316 break; 1317 1317 1318 Assert (cbPlayed <= cbRead);1318 AssertMsg(cbPlayed <= cbRead, ("Played more than available (%RU32 available but got %RU32)\n", cbRead, cbPlayed)); 1319 1319 AssertMsg(cbPlayed % 2 == 0, 1320 1320 ("Backend for stream '%s' returned uneven played bytes count (csRead=%RU32, cbPlayed=%RU32)\n", … … 1548 1548 } 1549 1549 1550 static int drvAudioStreamCaptureNonInterleaved(PDRVAUDIO pThis, PPDMAUDIOSTREAM pHstStream, uint32_t *pcsCaptured) 1551 { 1552 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1553 AssertPtrReturn(pHstStream, VERR_INVALID_POINTER); 1554 /* pcsCaptured is optional. */ 1555 1556 /* Sanity. */ 1557 Assert(pHstStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 1558 Assert(pHstStream->enmDir == PDMAUDIODIR_IN); 1559 Assert(pHstStream->Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED); 1560 1561 int rc = VINF_SUCCESS; 1562 1563 uint32_t csCapturedTotal = 0; 1564 1565 AssertPtr(pThis->pHostDrvAudio->pfnStreamGetReadable); 1566 1567 uint8_t auBuf[_1K]; /** @todo Get rid of this. */ 1568 size_t cbBuf = sizeof(auBuf); 1569 1570 for (;;) 1571 { 1572 uint32_t cbReadable = pThis->pHostDrvAudio->pfnStreamGetReadable(pThis->pHostDrvAudio, pHstStream->pvBackend); 1573 if (!cbReadable) 1574 break; 1575 1576 uint32_t cbFree = AUDIOMIXBUF_S2B(&pHstStream->MixBuf, AudioMixBufFree(&pHstStream->MixBuf)); 1577 if (!cbFree) 1578 break; 1579 1580 if (cbFree < cbReadable) /* More data captured than we can read? */ 1581 { 1582 /** @todo Warn? */ 1583 } 1584 1585 if (cbFree > cbBuf) /* Limit to buffer size. */ 1586 cbFree = cbBuf; 1587 1588 uint32_t cbCaptured; 1589 rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream->pvBackend, 1590 auBuf, cbFree, &cbCaptured); 1591 if (RT_FAILURE(rc)) 1592 { 1593 int rc2 = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 1594 AssertRC(rc2); 1595 } 1596 else if (cbCaptured) 1597 { 1598 Assert(cbCaptured <= cbBuf); 1599 if (cbCaptured > cbBuf) /* Paranoia. */ 1600 cbCaptured = cbBuf; 1601 1602 uint32_t csCaptured = 0; 1603 rc = AudioMixBufWriteCirc(&pHstStream->MixBuf, auBuf, cbCaptured, &csCaptured); 1604 if (RT_SUCCESS(rc)) 1605 csCapturedTotal += csCaptured; 1606 } 1607 else /* Nothing captured -- bail out. */ 1608 { 1609 #ifdef VBOX_STRICT 1610 AssertMsgFailed(("[%s] Captured anything, even if announced readable data (%RU32 captured samples so far) -- backend buggy?\n", 1611 pHstStream->szName, csCapturedTotal)); 1612 #endif 1613 break; 1614 } 1615 1616 if (RT_FAILURE(rc)) 1617 break; 1618 } 1619 1620 Log2Func(("[%s] %RU32 samples captured, rc=%Rrc\n", pHstStream->szName, csCapturedTotal, rc)); 1621 1622 if (pcsCaptured) 1623 *pcsCaptured = csCapturedTotal; 1624 1625 return rc; 1626 } 1627 1628 static int drvAudioStreamCaptureRaw(PDRVAUDIO pThis, PPDMAUDIOSTREAM pHstStream, uint32_t *pcsCaptured) 1629 { 1630 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1631 AssertPtrReturn(pHstStream, VERR_INVALID_POINTER); 1632 /* pcsCaptured is optional. */ 1633 1634 /* Sanity. */ 1635 Assert(pHstStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 1636 Assert(pHstStream->enmDir == PDMAUDIODIR_IN); 1637 Assert(pHstStream->Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_RAW); 1638 1639 int rc = VINF_SUCCESS; 1640 1641 uint32_t csCapturedTotal = 0; 1642 1643 AssertPtr(pThis->pHostDrvAudio->pfnStreamGetReadable); 1644 1645 for (;;) 1646 { 1647 uint32_t csReadable = pThis->pHostDrvAudio->pfnStreamGetReadable(pThis->pHostDrvAudio, pHstStream->pvBackend); 1648 if (!csReadable) 1649 break; 1650 1651 uint32_t csFree = AudioMixBufFree(&pHstStream->MixBuf); 1652 if (!csFree) 1653 break; 1654 1655 if (csFree < csReadable) /* More data captured than we can read? */ 1656 { 1657 /** @todo Warn? */ 1658 } 1659 1660 PPDMAUDIOSAMPLE paSamples; 1661 uint32_t csWritable; 1662 rc = AudioMixBufPeekMutable(&pHstStream->MixBuf, csReadable, &paSamples, &csWritable); 1663 if (RT_FAILURE(rc)) 1664 break; 1665 1666 uint32_t csCaptured; 1667 rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream->pvBackend, 1668 paSamples, csWritable, &csCaptured); 1669 if (RT_FAILURE(rc)) 1670 { 1671 int rc2 = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 1672 AssertRC(rc2); 1673 } 1674 else if (csCaptured) 1675 { 1676 Assert(csCaptured <= csWritable); 1677 if (csCaptured > csWritable) /* Paranoia. */ 1678 csCaptured = csWritable; 1679 1680 csCapturedTotal += csCaptured; 1681 } 1682 else /* Nothing captured -- bail out. */ 1683 { 1684 #ifdef VBOX_STRICT 1685 AssertMsgFailed(("[%s] Captured anything, even if announced readable data (%RU32 captured samples so far) -- backend buggy?\n", 1686 pHstStream->szName, csCapturedTotal)); 1687 #endif 1688 break; 1689 } 1690 1691 if (RT_FAILURE(rc)) 1692 break; 1693 } 1694 1695 Log2Func(("[%s] %RU32 samples captured, rc=%Rrc\n", pHstStream->szName, csCapturedTotal, rc)); 1696 1697 if (pcsCaptured) 1698 *pcsCaptured = csCapturedTotal; 1699 1700 return rc; 1701 } 1702 1550 1703 /** 1551 1704 * @interface_method_impl{PDMIAUDIOCONNECTOR,pfnStreamCapture} … … 1597 1750 1598 1751 /* 1599 * Check how much audio data the backend has captured so far.1752 * Do the actual capturing. 1600 1753 */ 1601 1754 1602 AssertPtr(pThis->pHostDrvAudio->pfnStreamGetReadable); 1603 uint32_t cbReadable = pThis->pHostDrvAudio->pfnStreamGetReadable(pThis->pHostDrvAudio, pHstStream->pvBackend); 1604 if (!cbReadable) /* Nothing captured? Bail out. */ 1605 break; 1606 1607 /* 1608 * Check if we have space and limit. 1609 */ 1610 1611 uint32_t csFree = AudioMixBufFree(&pHstStream->MixBuf); 1612 if (csFree) 1613 break; 1614 1615 if (csFree < AUDIOMIXBUF_B2S(&pHstStream->MixBuf, cbReadable)) /* More data captured than we can read? */ 1616 { 1617 /** @todo Warn? */ 1618 } 1619 1620 uint8_t auBuf[_1K]; /** @todo Get rid of this. */ 1621 1622 uint32_t cbCaptured; 1623 rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream->pvBackend, 1624 auBuf, sizeof(auBuf), &cbCaptured); 1625 if (RT_FAILURE(rc)) 1626 { 1627 int rc2 = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 1628 AssertRC(rc2); 1755 if (RT_LIKELY(pHstStream->Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED)) 1756 { 1757 rc = drvAudioStreamCaptureNonInterleaved(pThis, pHstStream, &csCaptured); 1758 } 1759 else if (pHstStream->Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_RAW) 1760 { 1761 rc = drvAudioStreamCaptureRaw(pThis, pHstStream, &csCaptured); 1629 1762 } 1630 1763 else 1631 { 1632 Assert(cbCaptured <= sizeof(auBuf)); 1633 rc = AudioMixBufWriteCirc(&pHstStream->MixBuf, auBuf, cbCaptured, &csCaptured); 1634 if (RT_SUCCESS(rc)) 1635 { 1764 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED); 1765 1766 #ifdef LOG_ENABLED 1767 pszBackendSts = dbgAudioStreamStatusToStr(stsBackend); 1768 Log3Func(("[%s] End: stsBackend=%s, csCaptured=%RU32, rc=%Rrc\n", 1769 pHstStream->szName, pszBackendSts, csCaptured, rc)); 1770 RTStrFree(pszBackendSts); 1771 #endif /* LOG_ENABLED */ 1772 1773 if (RT_SUCCESS(rc)) 1774 { 1636 1775 #ifdef VBOX_WITH_STATISTICS 1637 1638 1639 #endif 1640 Log3Func(("[%s] %RU32 samples captured\n", pHstStream->szName, csCaptured));1641 }1642 }1776 STAM_COUNTER_ADD(&pThis->Stats.TotalSamplesIn, csCaptured); 1777 STAM_COUNTER_ADD(&pHstStream->In.StatSamplesCaptured, csCaptured); 1778 #endif 1779 } 1780 else 1781 LogRel2(("Audio: Capturing stream '%s' failed with %Rrc\n", pHstStream->szName, rc)); 1643 1782 1644 1783 } while (0); 1645 1784 1646 if (RT_SUCCESS(rc)) 1647 { 1648 if (pcSamplesCaptured) 1649 *pcSamplesCaptured = csCaptured; 1650 } 1651 else 1652 LogFunc(("Failed with %Rrc\n", rc)); 1785 if (pcSamplesCaptured) 1786 *pcSamplesCaptured = csCaptured; 1653 1787 1654 1788 int rc2 = RTCritSectLeave(&pThis->CritSect); … … 2684 2818 if (RT_FAILURE(rc)) 2685 2819 { 2686 LogRel 2(("Audio: Creating stream '%s' with an invalid backend configuration not possible, skipping\n",2687 2820 LogRel(("Audio: Creating stream '%s' with an invalid backend configuration not possible, skipping\n", 2821 pHstStream->szName)); 2688 2822 return rc; 2689 2823 } … … 2692 2826 if (RT_FAILURE(rc)) 2693 2827 { 2694 LogRel 2(("Audio: Creating stream '%s' in backend failed with %Rrc\n", pHstStream->szName, rc));2828 LogRel(("Audio: Creating stream '%s' in backend failed with %Rrc\n", pHstStream->szName, rc)); 2695 2829 return rc; 2696 2830 } … … 2699 2833 if (!DrvAudioHlpStreamCfgIsValid(&CfgAcq)) 2700 2834 { 2701 LogRel 2(("Audio: Creating stream '%s' returned an invalid backend configuration, skipping\n", pHstStream->szName));2835 LogRel(("Audio: Creating stream '%s' returned an invalid backend configuration, skipping\n", pHstStream->szName)); 2702 2836 return VERR_INVALID_PARAMETER; 2703 2837 }
Note:
See TracChangeset
for help on using the changeset viewer.