Changeset 70594 in vbox
- Timestamp:
- Jan 15, 2018 4:35:07 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 120302
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/HDAStream.cpp
r70540 r70594 217 217 } 218 218 219 if ( !pStream->u32CBL 220 || !pStream->u16LVI 221 || !pStream->u64BDLBase 222 || !pStream->u16FIFOS) 223 { 224 return VINF_SUCCESS; 225 } 226 219 227 /* Set the stream's frame size. */ 220 228 pStream->State.cbFrameSize = pCfg->Props.cChannels * (pCfg->Props.cBits / 8 /* To bytes */); 229 LogFunc(("[SD%RU8] cChannels=%RU8, cBits=%RU8 -> cbFrameSize=%RU32\n", 230 pStream->u8SD, pCfg->Props.cChannels, pCfg->Props.cBits, pStream->State.cbFrameSize)); 231 Assert(pStream->State.cbFrameSize); /* Frame size must not be 0. */ 221 232 222 233 /* … … 235 246 pStream->State.Cfg.Props.uHz, rc)); 236 247 237 if ( pStream->u32CBL 238 && pStream->u16LVI) 248 /* Make sure that mandatory parameters are set up correctly. */ 249 AssertStmt(pStream->u32CBL % pStream->State.cbFrameSize == 0, rc = VERR_INVALID_PARAMETER); 250 AssertStmt(pStream->u16LVI >= 1, rc = VERR_INVALID_PARAMETER); 251 252 if (RT_SUCCESS(rc)) 239 253 { 240 254 /* Make sure that the chosen Hz rate dividable by the stream's rate. */ … … 263 277 RT_ZERO(BDLE); 264 278 265 Assert(pStream->u64BDLBase);266 267 279 int rc2 = hdaBDLEFetch(pThis, &BDLE, pStream->u64BDLBase, 0 /* Entry */); 268 280 AssertRC(rc2); 269 281 270 Assert(BDLE.Desc.u32BufSize % pStream->State.cbFrameSize == 0); 282 /* Note: Do *not* check if this BDLE aligns to the stream's frame size. 283 * It can happen that this isn't the case on some guests, e.g. 284 * on Windows with a 5.1 speaker setup. 285 * 286 * The only thing which counts is that the stream's CBL value 287 * properly aligns to the stream's frame size. 288 */ 271 289 272 290 /* If no custom set position adjustment is set, apply some … … 340 358 pStream->State.cbTransferProcessed = 0; 341 359 pStream->State.cTransferPendingInterrupts = 0; 360 pStream->State.cbDMALeft = 0; 342 361 343 362 const uint64_t cTicksPerHz = TMTimerGetFreq(pThis->pTimer) / pThis->u16TimerHz; … … 366 385 #endif 367 386 } 387 388 if (RT_FAILURE(rc)) 389 LogRel(("HDA: Initializing stream #%RU8 failed with %Rrc\n", rc)); 368 390 369 391 return rc; … … 537 559 AssertPtrReturnVoid(pStream); 538 560 539 Assert(u32LPIB % pStream->State.cbFrameSize == 0);540 541 561 Log3Func(("[SD%RU8] LPIB=%RU32 (DMA Position Buffer Enabled: %RTbool)\n", 542 562 pStream->u8SD, u32LPIB, pStream->pHDAState->fDMAPosition)); … … 937 957 if (RT_SUCCESS(rc)) 938 958 { 939 uint32_t cbDMAWritten = 0; 940 uint32_t cbDMALeft = cbDMA; 941 942 if (cbDMALeft > RTCircBufFree(pCircBuf)) 943 { 944 LogRel2(("HDA: FIFO overflow for stream #%RU8 (%RU32 bytes outstanding)\n", 945 pStream->u8SD, cbDMALeft - RTCircBufFree(pCircBuf))); 946 947 /* Try to read as much as possible. */ 948 cbDMALeft = (uint32_t)RTCircBufFree(pCircBuf); 949 950 rc = VERR_BUFFER_OVERFLOW; 951 } 959 uint32_t cbDMARead = pStream->State.cbDMALeft ? pStream->State.cbFrameSize - pStream->State.cbDMALeft : 0; 960 uint32_t cbDMALeft = RT_MIN(cbDMA, RTCircBufFree(pCircBuf)); 952 961 953 962 #ifndef VBOX_WITH_HDA_AUDIO_INTERLEAVING_STREAMS_SUPPORT 954 963 /** 955 964 * The following code extracts the required audio stream (channel) data 956 * of non-interleaved 965 * of non-interleaved *and* interleaved audio streams. 957 966 * 958 967 * We by default only support 2 channels with 16-bit samples (HDA_FRAME_SIZE), … … 962 971 * So take this into account by just handling the first channel in such a stream ("A") 963 972 * and just discard the other channel's data. 973 * 974 * @todo Optimize this stuff -- copying only one frame a time is expensive. 964 975 */ 965 while (cbDMALeft )976 while (cbDMALeft >= pStream->State.cbFrameSize) 966 977 { 967 978 void *pvBuf; size_t cbBuf; 968 979 RTCircBufAcquireWriteBlock(pCircBuf, HDA_FRAME_SIZE, &pvBuf, &cbBuf); 969 980 981 AssertBreak(cbDMARead <= sizeof(abChunk)); 982 970 983 if (cbBuf) 971 memcpy(pvBuf, abChunk + cbDMA Written, cbBuf);984 memcpy(pvBuf, abChunk + cbDMARead, cbBuf); 972 985 973 986 RTCircBufReleaseWriteBlock(pCircBuf, cbBuf); 974 987 975 cbDMALeft -= (uint32_t)pStream->State.cbFrameSize; 976 cbDMAWritten += (uint32_t)pStream->State.cbFrameSize; 988 Assert(cbDMALeft >= pStream->State.cbFrameSize); 989 cbDMALeft -= pStream->State.cbFrameSize; 990 cbDMARead += pStream->State.cbFrameSize; 977 991 } 992 993 pStream->State.cbDMALeft = cbDMALeft; 994 Assert(pStream->State.cbDMALeft < pStream->State.cbFrameSize); 995 996 const size_t cbFree = RTCircBufFree(pCircBuf); 997 if (!cbFree) 998 LogRel2(("HDA: FIFO of stream #%RU8 full, discarding audio data\n", pStream->u8SD)); 978 999 #else 979 1000 /** @todo This needs making use of HDAStreamMap + HDAStreamChannel. */ … … 992 1013 if (cbDMA) 993 1014 { 994 Assert(cbDMA % pStream->State.cbFrameSize == 0);995 996 1015 /* We always increment the position of DMA buffer counter because we're always reading 997 1016 * into an intermediate buffer. */ … … 1069 1088 1070 1089 /* Sanity. */ 1071 Assert(cbProcessed % pStream->State.cbFrameSize == 0);1072 1090 Assert(cbProcessed == cbToProcess); 1073 1091 Assert(cbLeft == 0); -
trunk/src/VBox/Devices/Audio/HDAStream.h
r70248 r70594 171 171 RTLISTANCHORR3 lstDMAHandlers; 172 172 #endif 173 /** How much DMA data from a previous transfer is left to be processed (in bytes). 174 * This can happen if the stream's frame size is bigger (e.g. 16 bytes) than 175 * the current DMA FIFO can hold (e.g. 10 bytes). Mostly needed for more complex 176 * stuff like interleaved surround streams. */ 177 uint16_t cbDMALeft; 173 178 /** Unused, padding. */ 174 uint8_t Padding3 [3];179 uint8_t Padding3; 175 180 } HDASTREAMSTATE, *PHDASTREAMSTATE; 176 181
Note:
See TracChangeset
for help on using the changeset viewer.