Changeset 89691 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Jun 14, 2021 8:01:32 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145139
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r89687 r89691 832 832 * @param pStreamCC The AC'97 stream, ring-3 state. 833 833 * 834 * @remark Updates CIV, PIV, BD and PICB. 834 * @remarks Updates CIV, PIV, BD and PICB. 835 * 836 * @note Both PIV and CIV will be zero after a stream reset, so the first 837 * time we advance the buffer position afterwards, CIV will remain zero 838 * and PIV becomes 1. Thus we will start processing from BDLE00 and 839 * not BDLE01 as CIV=0 may lead you to think. 835 840 */ 836 841 static uint32_t ichac97R3StreamFetchNextBdle(PPDMDEVINS pDevIns, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC) … … 845 850 { 846 851 /* Advance the buffer. */ 847 pStream->Regs.civ = pStream->Regs.piv ;852 pStream->Regs.civ = pStream->Regs.piv % AC97_MAX_BDLE /* (paranoia) */; 848 853 pStream->Regs.piv = (pStream->Regs.piv + 1) % AC97_MAX_BDLE; 849 854 … … 873 878 if (pStream->Regs.picb) 874 879 break; 875 if (pStream->Regs.civ == pStream->Regs.lvi)880 if (pStream->Regs.civ == (pStream->Regs.lvi % AC97_MAX_BDLE /* (paranoia) */)) 876 881 { 877 882 LogFunc(("BDLE%02u is zero length! Can't skip (CIV=LVI). %#RX32 %#RX32\n", pStream->Regs.civ, Bdle.addr, Bdle.ctl_len)); … … 1088 1093 1089 1094 pRegs->picb = 0; 1090 pRegs->piv = 0; 1095 pRegs->piv = 0; /* Note! Because this is also zero, we will actually start transferring with BDLE00. */ 1091 1096 pRegs->cr = pRegs->cr & AC97_CR_DONT_CLEAR_MASK; 1092 1097 pRegs->bd_valid = 0; … … 1885 1890 * up to and we cannot really make much of a plan out of it. 1886 1891 */ 1887 /** @todo This is wrong! The valid range is CVI thru LVI. However, CVI is1888 * typically reset to zero, I guess... */1889 1892 AC97BDLE aBdl[AC97_MAX_BDLE]; 1890 1893 RT_ZERO(aBdl); 1891 unsigned const cBuffers = pStream->Regs.lvi + 1; 1892 PDMDevHlpPCIPhysRead(pDevIns, pStream->Regs.bdbar, aBdl, sizeof(aBdl[0]) * cBuffers); 1893 1894 uint32_t cSamplesMax = 0; 1895 uint32_t cSamplesMin = UINT32_MAX; 1896 uint32_t cSamplesCur = 0; 1897 uint32_t cSamplesTotal = 0; 1898 for (unsigned i = 0; i < cBuffers; i++) 1899 { 1900 cSamplesCur += aBdl[0].ctl_len & AC97_BD_LEN_MASK; 1901 cSamplesTotal += aBdl[0].ctl_len & AC97_BD_LEN_MASK; 1902 if (aBdl[0].ctl_len & AC97_BD_IOC) 1894 PDMDevHlpPCIPhysRead(pDevIns, pStream->Regs.bdbar, aBdl, sizeof(aBdl)); 1895 1896 uint8_t const bLvi = pStream->Regs.lvi % AC97_MAX_BDLE /* paranoia */; 1897 uint8_t const bCiv = pStream->Regs.civ % AC97_MAX_BDLE /* paranoia */; 1898 uint32_t cSamplesMax = 0; 1899 uint32_t cSamplesMin = UINT32_MAX; 1900 uint32_t cSamplesCur = 0; 1901 uint32_t cSamplesTotal = 0; 1902 uint32_t cBuffers = 1; 1903 for (uintptr_t i = bCiv; ; cBuffers++) 1904 { 1905 cSamplesTotal += aBdl[i].ctl_len & AC97_BD_LEN_MASK; 1906 cSamplesCur += aBdl[i].ctl_len & AC97_BD_LEN_MASK; 1907 if (aBdl[i].ctl_len & AC97_BD_IOC) 1903 1908 { 1904 1909 if (cSamplesCur > cSamplesMax) … … 1908 1913 cSamplesCur = 0; 1909 1914 } 1910 } 1911 1912 if (cSamplesCur && cSamplesMax != 0) 1913 { 1914 LogFlowFunc(("Tail buffer w/o IOC, loops.\n")); 1915 for (unsigned i = 0; i < cBuffers; i++) 1916 { 1917 cSamplesCur += aBdl[0].ctl_len & AC97_BD_LEN_MASK; 1918 if (aBdl[0].ctl_len & AC97_BD_IOC) 1919 { 1920 if (cSamplesCur > cSamplesMax) 1921 cSamplesMax = cSamplesCur; 1922 if (cSamplesCur < cSamplesMin) 1923 cSamplesMin = cSamplesCur; 1924 cSamplesCur = 0; 1925 break; 1926 } 1927 } 1928 } 1915 1916 /* Advance. */ 1917 if (i != bLvi) 1918 i = (i + 1) % RT_ELEMENTS(aBdl); 1919 else 1920 break; 1921 } 1922 if (!cSamplesCur) 1923 { /* likely */ } 1924 else if (!cSamplesMax) 1925 { 1926 LogFlowFunc(("%u buffers without IOC set, assuming %#x samples as the IOC period.\n", cBuffers, cSamplesMax)); 1927 cSamplesMin = cSamplesMax = cSamplesCur; 1928 } 1929 else if (cSamplesCur > cSamplesMax) 1930 { 1931 LogFlowFunc(("final buffer is without IOC, using open period as max (%#x vs current max %#x).\n", cSamplesCur, cSamplesMax)); 1932 cSamplesMax = cSamplesCur; 1933 } 1934 else 1935 LogFlowFunc(("final buffer is without IOC, ignoring (%#x vs current max %#x).\n", cSamplesCur, cSamplesMax)); 1929 1936 1930 1937 uint32_t const cbDmaMinBuf = cSamplesMax * PDMAudioPropsSampleSize(&Cfg.Props) * 3; /* see further down */ 1931 1938 uint32_t const cMsDmaMinBuf = PDMAudioPropsBytesToMilli(&Cfg.Props, cbDmaMinBuf); 1932 1939 LogRel3(("AC97: [SD%RU8] buffer length stats: total=%#x in %u buffers, min=%#x, max=%#x => min DMA buffer %u ms / %#x bytes\n", 1933 1940 pStream->u8SD, cSamplesTotal, cBuffers, cSamplesMin, cSamplesMax, cMsDmaMinBuf, cbDmaMinBuf)); 1934 1941 1935 1942 /* … … 3664 3671 bool const fValid = bCiv <= bLvi 3665 3672 ? i >= bCiv && i <= bLvi 3666 : (i >= bCiv && i < RT_ELEMENTS(aBdl))|| i <= bLvi;3673 : i >= bCiv || i <= bLvi; 3667 3674 3668 3675 uint32_t const cb = (aBdl[i].ctl_len & AC97_BD_LEN_MASK) * PDMAudioPropsSampleSize(&Props); /** @todo or frame size? OSDev says frame... */
Note:
See TracChangeset
for help on using the changeset viewer.