- Timestamp:
- Dec 14, 2017 3:40:51 PM (7 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r70121 r70132 1376 1376 hdaStreamAsyncIOEnable(pStream, false /* fEnable */); 1377 1377 # endif 1378 /* Make sure to remove the run bit before doing the actual stream reset. */ 1379 HDA_STREAM_REG(pThis, CTL, uSD) &= ~HDA_SDCTL_RUN; 1380 1378 1381 hdaStreamReset(pThis, pStream, pStream->u8SD); 1379 1382 … … 1445 1448 } 1446 1449 1447 DEVHDA_UNLOCK_BOTH(pThis);1448 1449 1450 int rc2 = hdaRegWriteU24(pThis, iReg, u32Value); 1450 1451 AssertRC(rc2); 1452 1453 DEVHDA_UNLOCK_BOTH(pThis); 1451 1454 1452 1455 return VINF_SUCCESS; /* Always return success to the MMIO handler. */ … … 1816 1819 if (rc == VERR_NOT_SUPPORTED) 1817 1820 { 1818 LogRel 2(("HDA: Unsupported channel count (%RU8), falling back to stereo channels\n", pCfg->Props.cChannels));1821 LogRel(("HDA: Warning: Unsupported channel count (%RU8), falling back to stereo channels (2)\n", pCfg->Props.cChannels)); 1819 1822 1820 1823 /* Fall back to 2 channels (see below in fUseFront block). */ -
trunk/src/VBox/Devices/Audio/DevHDACommon.cpp
r70121 r70132 362 362 /* Sanity checks. */ 363 363 Assert(cbChunk <= pBDLE->Desc.u32BufSize - pBDLE->State.u32BufOff); 364 Assert(cbChunk % HDA_FRAME_SIZE== 0);364 Assert(cbChunk % pStream->State.cbFrameSize == 0); 365 365 Assert((cbChunk >> 1) >= 1); 366 366 -
trunk/src/VBox/Devices/Audio/HDAStream.cpp
r70125 r70132 180 180 pStream->u32CBL = HDA_STREAM_REG(pThis, CBL, pStream->u8SD); 181 181 pStream->u16FIFOS = HDA_STREAM_REG(pThis, FIFOS, pStream->u8SD) + 1; 182 183 /* Make sure to also update the stream's DMA counter (based on its current LPIB value). */184 hdaStreamSetPosition(pStream, HDA_STREAM_REG(pThis, LPIB, pStream->u8SD));185 182 186 183 PPDMAUDIOSTREAMCFG pCfg = &pStream->State.Cfg; … … 218 215 break; 219 216 } 217 218 /* Set the stream's frame size. */ 219 pStream->State.cbFrameSize = pCfg->Props.cChannels * (pCfg->Props.cBits / 8 /* To bytes */); 220 220 221 221 /* … … 231 231 232 232 LogFunc(("[SD%RU8] DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16, Hz=%RU32, rc=%Rrc\n", 233 pStream->u8SD, pStream->u64BDLBase, pStream->u32CBL, pStream->u16LVI, pStream->u16FIFOS, 233 pStream->u8SD, pStream->u64BDLBase, pStream->u32CBL, pStream->u16LVI, pStream->u16FIFOS, 234 234 pStream->State.Cfg.Props.uHz, rc)); 235 235 … … 251 251 pStream->State.cbTransferSize = pStream->u32CBL / cFragments; 252 252 Assert(pStream->State.cbTransferSize); 253 Assert(pStream->State.cbTransferSize % HDA_FRAME_SIZE== 0);253 Assert(pStream->State.cbTransferSize % pStream->State.cbFrameSize == 0); 254 254 255 255 /* Calculate the bytes we need to transfer to / from the stream's DMA per iteration. 256 256 * This is bound to the device's Hz rate and thus to the (virtual) timing the device expects. */ 257 pStream->State.cbTransferChunk = (pStream->State.Cfg.Props.uHz / pThis->u16TimerHz) * HDA_FRAME_SIZE;257 pStream->State.cbTransferChunk = (pStream->State.Cfg.Props.uHz / pThis->u16TimerHz) * pStream->State.cbFrameSize; 258 258 Assert(pStream->State.cbTransferChunk); 259 Assert(pStream->State.cbTransferChunk % HDA_FRAME_SIZE== 0);259 Assert(pStream->State.cbTransferChunk % pStream->State.cbFrameSize == 0); 260 260 261 261 /* Make sure that the transfer chunk does not exceed the overall transfer size. */ … … 303 303 #ifdef VBOX_WITH_INTEL_HDA 304 304 /* Intel ICH / PCH: 1 frame. */ 305 if (BDLE.Desc.u32BufSize == 1 * HDA_FRAME_SIZE)305 if (BDLE.Desc.u32BufSize == 1 * pStream->State.cbFrameSize) 306 306 { 307 307 cfPosAdjust = 1; 308 308 } 309 309 /* Intel Baytrail / Braswell: 32 frames. */ 310 else if (BDLE.Desc.u32BufSize == 32 * HDA_FRAME_SIZE)310 else if (BDLE.Desc.u32BufSize == 32 * pStream->State.cbFrameSize) 311 311 { 312 312 cfPosAdjust = 32; … … 328 328 329 329 LogFunc(("[SD%RU8] cfPosAdjust=%RU32\n", pStream->u8SD, cfPosAdjust)); 330 331 /* Make sure to also update the stream's DMA counter (based on its current LPIB value). */ 332 hdaStreamSetPosition(pStream, HDA_STREAM_REG(pThis, LPIB, pStream->u8SD)); 330 333 331 334 #ifdef LOG_ENABLED … … 492 495 AssertPtrReturnVoid(pStream); 493 496 494 Assert(u32LPIB % HDA_FRAME_SIZE== 0);497 Assert(u32LPIB % pStream->State.cbFrameSize == 0); 495 498 496 499 Log3Func(("[SD%RU8] LPIB=%RU32 (DMA Position Buffer Enabled: %RTbool)\n", … … 811 814 uint32_t cbProcessed = 0; 812 815 uint32_t cbLeft = cbToProcess; 813 Assert(cbLeft % HDA_FRAME_SIZE== 0);816 Assert(cbLeft % pStream->State.cbFrameSize == 0); 814 817 815 818 uint8_t abChunk[HDA_FIFO_MAX + 1]; … … 825 828 * make sure that we process them first as a whole. */ 826 829 if (pStream->State.cPosAdjustFramesLeft) 827 cbChunk = RT_MIN(cbChunk, uint32_t(pStream->State.cPosAdjustFramesLeft * HDA_FRAME_SIZE));830 cbChunk = RT_MIN(cbChunk, uint32_t(pStream->State.cPosAdjustFramesLeft * pStream->State.cbFrameSize)); 828 831 829 832 Log3Func(("[SD%RU8] cbChunk=%RU32, cPosAdjustFramesLeft=%RU16\n", … … 843 846 uint32_t cbDMAToWrite = cbChunk; 844 847 848 /** @todo Do we need interleaving streams support here as well? 849 * Never saw anything else besides mono/stereo mics (yet). */ 845 850 while (cbDMAToWrite) 846 851 { … … 893 898 } 894 899 900 #ifndef VBOX_WITH_HDA_AUDIO_INTERLEAVING_STREAMS_SUPPORT 901 /** 902 * The following code extracts the required audio stream (channel) data 903 * of non-interleaved *and* interleaved audio streams. 904 * 905 * We by default only support 2 channels with 16-bit samples (HDA_FRAME_SIZE), 906 * but an HDA audio stream can have interleaved audio data of multiple audio 907 * channels in such a single stream ("AA,AA,AA vs. AA,BB,AA,BB"). 908 * 909 * So take this into account by just handling the first channel in such a stream ("A") 910 * and just discard the other channel's data. 911 */ 895 912 while (cbDMALeft) 896 913 { 897 914 void *pvBuf; size_t cbBuf; 898 RTCircBufAcquireWriteBlock(pCircBuf, cbDMALeft, &pvBuf, &cbBuf);915 RTCircBufAcquireWriteBlock(pCircBuf, HDA_FRAME_SIZE, &pvBuf, &cbBuf); 899 916 900 917 if (cbBuf) … … 903 920 RTCircBufReleaseWriteBlock(pCircBuf, cbBuf); 904 921 905 cbDMALeft -= (uint32_t) cbBuf;906 cbDMAWritten += (uint32_t) cbBuf;922 cbDMALeft -= (uint32_t)pStream->State.cbFrameSize; 923 cbDMAWritten += (uint32_t)pStream->State.cbFrameSize; 907 924 } 925 #else 926 /** @todo This needs making use of HDAStreamMap + HDAStreamChannel. */ 927 # error "Implement reading interleaving streams support here." 928 #endif 908 929 } 909 930 else … … 918 939 if (cbDMA) 919 940 { 920 Assert(cbDMA % HDA_FRAME_SIZE== 0);941 Assert(cbDMA % pStream->State.cbFrameSize == 0); 921 942 922 943 /* We always increment the position of DMA buffer counter because we're always reading … … 985 1006 986 1007 /* Do the position adjustment accounting. */ 987 pStream->State.cPosAdjustFramesLeft -= RT_MIN(pStream->State.cPosAdjustFramesLeft, cbDMA / HDA_FRAME_SIZE);1008 pStream->State.cPosAdjustFramesLeft -= RT_MIN(pStream->State.cPosAdjustFramesLeft, cbDMA / pStream->State.cbFrameSize); 988 1009 989 1010 if (RT_FAILURE(rc)) … … 995 1016 996 1017 /* Sanity. */ 997 Assert(cbProcessed % HDA_FRAME_SIZE== 0);1018 Assert(cbProcessed % pStream->State.cbFrameSize == 0); 998 1019 Assert(cbProcessed == cbToProcess); 999 1020 Assert(cbLeft == 0); … … 1003 1024 if (pStream->State.cPosAdjustFramesLeft == 0) 1004 1025 { 1005 hdaStreamPeriodInc(pPeriod, RT_MIN(cbProcessed / HDA_FRAME_SIZE, hdaStreamPeriodGetRemainingFrames(pPeriod)));1026 hdaStreamPeriodInc(pPeriod, RT_MIN(cbProcessed / pStream->State.cbFrameSize, hdaStreamPeriodGetRemainingFrames(pPeriod))); 1006 1027 1007 1028 pStream->State.cbTransferProcessed += cbProcessed; … … 1032 1053 const bool fWalClkSet = hdaWalClkSet(pThis, 1033 1054 hdaWalClkGetCurrent(pThis) 1034 + hdaStreamPeriodFramesToWalClk(pPeriod, pStream->State.cbTransferProcessed / HDA_FRAME_SIZE),1055 + hdaStreamPeriodFramesToWalClk(pPeriod, pStream->State.cbTransferProcessed / pStream->State.cbFrameSize), 1035 1056 false /* fForce */); 1036 1057 RT_NOREF(fWalClkSet); … … 1078 1099 tsTransferNext = tsNow + (cbTransferNext * pStream->State.cTicksPerByte); 1079 1100 1080 /** 1101 /** 1081 1102 * If the current transfer is complete, reset our counter. 1082 * 1103 * 1083 1104 * This can happen for examlpe if the guest OS (like macOS) sets up 1084 1105 * big BDLEs without IOC bits set (but for the last one) and the 1085 * transfer is complete before we reach such a BDL entry. 1086 */ 1106 * transfer is complete before we reach such a BDL entry. 1107 */ 1087 1108 if (fTransferComplete) 1088 1109 pStream->State.cbTransferProcessed = 0; -
trunk/src/VBox/Devices/Audio/HDAStream.h
r70013 r70132 148 148 * BDLE interrupt-on-completion (IOC) bits set. */ 149 149 uint8_t cTransferPendingInterrupts; 150 uint8_t Padding1[4]; 150 /** The stream's current audio frame size (in bytes). */ 151 uint32_t cbFrameSize; 151 152 /** How many audio data frames are left to be processed 152 153 * for the position adjustment handling.
Note:
See TracChangeset
for help on using the changeset viewer.