Changeset 75980 in vbox
- Timestamp:
- Dec 5, 2018 3:56:13 PM (6 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 2 edited
-
DevHDA.cpp (modified) (4 diffs)
-
HDAStream.cpp (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r75965 r75980 1301 1301 const bool fInReset = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_SDCTL_SRST); 1302 1302 1303 # ifdef LOG_ENABLED 1304 if (fRun) 1305 { 1306 PDMAUDIOPCMPROPS Props; 1307 int rc2 = hdaR3SDFMTToPCMProps(HDA_STREAM_REG(pThis, FMT, uSD), &Props); 1308 AssertRC(rc2); 1309 LogFunc(("[SD%RU8] %RU32Hz, %RU8bit, %RU8 channel(s)\n", 1310 uSD, Props.uHz, Props.cBytes * 8 /* Bit */, Props.cChannels)); 1311 } 1312 # endif 1313 1314 LogFunc(("[SD%RU8] fRun=%RTbool, fInRun=%RTbool, fReset=%RTbool, fInReset=%RTbool, %R[sdctl]\n", 1315 uSD, fRun, fInRun, fReset, fInReset, u32Value)); 1316 1317 if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT) 1318 { 1319 const uint8_t uStripeCtl = ((u32Value >> HDA_SDCTL_STRIPE_SHIFT) & HDA_SDCTL_STRIPE_MASK) + 1; 1320 LogFunc(("[SD%RU8] Using %RU8 SDOs (stripe control)\n", uSD, uStripeCtl)); 1321 if (uStripeCtl > 1) 1322 LogRel2(("HDA: Warning: Striping output over more than one SDO for stream #%RU8 currently is not implemented " \ 1323 "(%RU8 SDOs requested)\n", uSD, uStripeCtl)); 1324 } 1303 /*LogFunc(("[SD%RU8] fRun=%RTbool, fInRun=%RTbool, fReset=%RTbool, fInReset=%RTbool, %R[sdctl]\n", 1304 uSD, fRun, fInRun, fReset, fInReset, u32Value));*/ 1325 1305 1326 1306 /* … … 1341 1321 } 1342 1322 1343 PHDATAG pTag = &pThis->aTags[uTag]; 1344 AssertPtr(pTag); 1345 1346 LogFunc(("[SD%RU8] Using stream tag=%RU8\n", uSD, uTag)); 1347 1348 /* Assign new values. */ 1349 pTag->uTag = uTag; 1350 pTag->pStream = hdaGetStreamFromSD(pThis, uSD); 1351 1352 PHDASTREAM pStream = pTag->pStream; 1323 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD); 1353 1324 AssertPtr(pStream); 1354 1325 … … 1410 1381 if (fRun) 1411 1382 { 1383 if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT) 1384 { 1385 const uint8_t uStripeCtl = ((u32Value >> HDA_SDCTL_STRIPE_SHIFT) & HDA_SDCTL_STRIPE_MASK) + 1; 1386 LogFunc(("[SD%RU8] Using %RU8 SDOs (stripe control)\n", uSD, uStripeCtl)); 1387 if (uStripeCtl > 1) 1388 LogRel2(("HDA: Warning: Striping output over more than one SDO for stream #%RU8 currently is not implemented " \ 1389 "(%RU8 SDOs requested)\n", uSD, uStripeCtl)); 1390 } 1391 1392 PHDATAG pTag = &pThis->aTags[uTag]; 1393 AssertPtr(pTag); 1394 1395 LogFunc(("[SD%RU8] Using stream tag=%RU8\n", uSD, uTag)); 1396 1397 /* Assign new values. */ 1398 pTag->uTag = uTag; 1399 pTag->pStream = hdaGetStreamFromSD(pThis, uSD); 1400 1401 # ifdef LOG_ENABLED 1402 PDMAUDIOPCMPROPS Props; 1403 rc2 = hdaR3SDFMTToPCMProps(HDA_STREAM_REG(pThis, FMT, pStream->u8SD), &Props); 1404 AssertRC(rc2); 1405 LogFunc(("[SD%RU8] %RU32Hz, %RU8bit, %RU8 channel(s)\n", 1406 pStream->u8SD, Props.uHz, Props.cBytes * 8 /* Bit */, Props.cChannels)); 1407 # endif 1412 1408 /* (Re-)initialize the stream with current values. */ 1413 1409 rc2 = hdaR3StreamInit(pStream, pStream->u8SD); 1414 AssertRC(rc2); 1415 1416 /* Remove the old stream from the device setup. */ 1417 rc2 = hdaR3RemoveStream(pThis, &pStream->State.Cfg); 1418 AssertRC(rc2); 1419 1420 /* Add the stream to the device setup. */ 1421 rc2 = hdaR3AddStream(pThis, &pStream->State.Cfg); 1422 AssertRC(rc2); 1410 if ( RT_SUCCESS(rc2) 1411 /* Any vital stream change occurred so that we need to (re-)add the stream to our setup? 1412 * Otherwise just skip this, as this costs a lot of performance. */ 1413 && rc2 != VINF_NO_CHANGE) 1414 { 1415 /* Remove the old stream from the device setup. */ 1416 rc2 = hdaR3RemoveStream(pThis, &pStream->State.Cfg); 1417 AssertRC(rc2); 1418 1419 /* Add the stream to the device setup. */ 1420 rc2 = hdaR3AddStream(pThis, &pStream->State.Cfg); 1421 AssertRC(rc2); 1422 } 1423 1423 } 1424 1424 … … 4210 4210 ("HDA: Saved state contains invalid DMA buffer usage (%RU32/%RU32) for stream #%RU8", 4211 4211 cbCircBufUsed, cbCircBufSize, uStreamID)); 4212 AssertPtr(pStream->State.pCircBuf);4213 4212 4214 4213 /* Do we need to cre-create the circular buffer do fit the data size? */ 4215 if (cbCircBufSize != (uint32_t)RTCircBufSize(pStream->State.pCircBuf)) 4214 if ( pStream->State.pCircBuf 4215 && cbCircBufSize != (uint32_t)RTCircBufSize(pStream->State.pCircBuf)) 4216 4216 { 4217 4217 RTCircBufDestroy(pStream->State.pCircBuf); 4218 4218 pStream->State.pCircBuf = NULL; 4219 4220 rc = RTCircBufCreate(&pStream->State.pCircBuf, cbCircBufSize);4221 AssertRC(rc);4222 4219 } 4220 4221 rc = RTCircBufCreate(&pStream->State.pCircBuf, cbCircBufSize); 4222 AssertRC(rc); 4223 4223 4224 4224 if ( RT_SUCCESS(rc) -
trunk/src/VBox/Devices/Audio/HDAStream.cpp
r75962 r75980 135 135 AssertPtrReturnVoid(pStream); 136 136 137 LogFlowFunc(("[SD%RU8] :Destroying ...\n", pStream->u8SD));137 LogFlowFunc(("[SD%RU8] Destroying ...\n", pStream->u8SD)); 138 138 139 139 hdaR3StreamMapDestroy(&pStream->State.Mapping); … … 186 186 * Initializes an HDA stream. 187 187 * 188 * @returns IPRT status code. 188 * @returns IPRT status code. VINF_NO_CHANGE if the stream does not need (re-)initialization because the stream's (hardware) 189 * parameters did not change. 189 190 * @param pStream HDA stream to initialize. 190 191 * @param uSD SD (stream descriptor) number to assign the HDA stream to. … … 197 198 AssertPtr(pThis); 198 199 199 pStream->u8SD = uSD; 200 pStream->u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStream->u8SD), 201 HDA_STREAM_REG(pThis, BDPU, pStream->u8SD)); 202 pStream->u16LVI = HDA_STREAM_REG(pThis, LVI, pStream->u8SD); 203 pStream->u32CBL = HDA_STREAM_REG(pThis, CBL, pStream->u8SD); 204 pStream->u16FIFOS = HDA_STREAM_REG(pThis, FIFOS, pStream->u8SD) + 1; 205 206 PPDMAUDIOSTREAMCFG pCfg = &pStream->State.Cfg; 207 208 int rc = hdaR3SDFMTToPCMProps(HDA_STREAM_REG(pThis, FMT, uSD), &pCfg->Props); 200 const uint64_t u64BDLBase = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, uSD), 201 HDA_STREAM_REG(pThis, BDPU, uSD)); 202 const uint16_t u16LVI = HDA_STREAM_REG(pThis, LVI, uSD); 203 const uint32_t u32CBL = HDA_STREAM_REG(pThis, CBL, uSD); 204 const uint16_t u16FIFOS = HDA_STREAM_REG(pThis, FIFOS, uSD) + 1; 205 const uint32_t u32FMT = HDA_STREAM_REG(pThis, FMT, uSD); 206 207 /* Is the bare minimum set of registers configured for the stream? 208 * If not, bail out early, as there's nothing to do here for us (yet). */ 209 if ( !u64BDLBase 210 || !u16LVI 211 || !u32CBL 212 || !u16FIFOS 213 || !u32FMT) 214 { 215 LogFunc(("[SD%RU8] Registers not set up yet, skipping (re-)initialization\n", uSD)); 216 return VINF_SUCCESS; 217 } 218 219 PDMAUDIOPCMPROPS Props; 220 int rc = hdaR3SDFMTToPCMProps(u32FMT, &Props); 209 221 if (RT_FAILURE(rc)) 210 222 { … … 213 225 } 214 226 215 /* Set scheduling hint (if available). */ 216 if (pThis->uTimerHz) 217 pCfg->Device.uSchedulingHintMs = 1000 /* ms */ / pThis->uTimerHz; 227 /* Reset (any former) stream map. */ 228 hdaR3StreamMapReset(&pStream->State.Mapping); 229 230 /* 231 * Initialize the stream mapping in any case, regardless if 232 * we support surround audio or not. This is needed to handle 233 * the supported channels within a single audio stream, e.g. mono/stereo. 234 * 235 * In other words, the stream mapping *always* knows the real 236 * number of channels in a single audio stream. 237 */ 238 rc = hdaR3StreamMapInit(&pStream->State.Mapping, &Props); 239 AssertRCReturn(rc, rc); 240 241 #ifndef VBOX_WITH_AUDIO_HDA_51_SURROUND 242 if (Props.cChannels > 2) 243 { 244 /* 245 * When not running with surround support enabled, override the audio channel count 246 * with stereo (2) channels so that we at least can properly work with those. 247 * 248 * Note: This also involves dealing with surround setups the guest might has set up for us. 249 */ 250 LogRel2(("HDA: More than stereo (2) channels are not supported (%RU8 requested), " 251 "falling back to stereo channels for stream #%RU8\n", Props.cChannels, uSD)); 252 Props.cChannels = 2; 253 } 254 #endif 255 256 /* Did some of the vital / critical parameters change? 257 * If not, we can skip a lot of the (re-)initialization and just (re-)use the existing stuff. 258 * Also, tell the caller so that further actions can be taken. */ 259 if ( uSD == pStream->u8SD 260 && u64BDLBase == pStream->u64BDLBase 261 && u16LVI == pStream->u16LVI 262 && u32CBL == pStream->u32CBL 263 && u16FIFOS == pStream->u16FIFOS 264 && DrvAudioHlpPCMPropsAreEqual(&Props, &pStream->State.Cfg.Props)) 265 { 266 LogFunc(("[SD%RU8] No format change, skipping (re-)initialization\n", uSD)); 267 return VINF_NO_CHANGE; 268 } 269 270 pStream->u8SD = uSD; 271 pStream->u64BDLBase = u64BDLBase; 272 pStream->u16LVI = u16LVI; 273 pStream->u32CBL = u32CBL; 274 pStream->u16FIFOS = u16FIFOS; 275 276 PPDMAUDIOSTREAMCFG pCfg = &pStream->State.Cfg; 277 pCfg->Props = Props; 218 278 219 279 /* (Re-)Allocate the stream's internal DMA buffer, based on the PCM properties we just got above. */ … … 225 285 226 286 /* By default we allocate an internal buffer of 100ms. */ 227 rc = RTCircBufCreate(&pStream->State.pCircBuf, DrvAudioHlpMilliToBytes(100 /* ms */, &pCfg->Props)); /** @todo Make this configurable. */ 287 rc = RTCircBufCreate(&pStream->State.pCircBuf, 288 DrvAudioHlpMilliToBytes(100 /* ms */, &pCfg->Props)); /** @todo Make this configurable. */ 228 289 AssertRCReturn(rc, rc); 229 290 … … 254 315 } 255 316 256 if ( !pStream->u32CBL 257 || !pStream->u16LVI 258 || !pStream->u64BDLBase 259 || !pStream->u16FIFOS) 260 { 261 return VINF_SUCCESS; 262 } 263 264 /* 265 * Initialize the stream mapping in any case, regardless if 266 * we support surround audio or not. This is needed to handle 267 * the supported channels within a single audio stream, e.g. mono/stereo. 268 * 269 * In other words, the stream mapping *always* knows the real 270 * number of channels in a single audio stream. 271 */ 272 rc = hdaR3StreamMapInit(&pStream->State.Mapping, &pCfg->Props); 273 AssertRCReturn(rc, rc); 274 275 #ifndef VBOX_WITH_AUDIO_HDA_51_SURROUND 276 /* 277 * When not running with surround support enabled, override the channel count 278 * with stereo (2) channels so that we at least can properly work with those. 279 * 280 * Note: This also involves dealing with surround setups the guest might has set up for us. 281 */ 282 pCfg->Props.cChannels = 2; 283 #endif 284 285 LogFunc(("[SD%RU8] DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16, Hz=%RU32, rc=%Rrc\n", 286 pStream->u8SD, pStream->u64BDLBase, pStream->u32CBL, pStream->u16LVI, pStream->u16FIFOS, 287 pStream->State.Cfg.Props.uHz, rc)); 317 LogFunc(("[SD%RU8] DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16\n", 318 pStream->u8SD, pStream->u64BDLBase, pStream->u32CBL, pStream->u16LVI, pStream->u16FIFOS)); 288 319 289 320 /* Make sure that mandatory parameters are set up correctly. */ … … 397 428 pStream->State.cbTransferChunk = pStream->State.cbTransferSize; 398 429 399 pStream->State.cbTransferProcessed = 0;400 pStream->State.cTransferPendingInterrupts = 0;401 pStream->State.tsLastUpdateNs = 0;402 403 430 const uint64_t cTicksPerHz = TMTimerGetFreq(pStream->pTimer) / pThis->uTimerHz; 404 431 … … 410 437 pStream->State.cTransferTicks = pStream->State.cbTransferChunk * pStream->State.cTicksPerByte; 411 438 Assert(pStream->State.cTransferTicks); 412 413 /* Initialize the transfer timestamps. */414 pStream->State.tsTransferLast = 0;415 pStream->State.tsTransferNext = 0;416 439 417 440 LogFunc(("[SD%RU8] Timer %uHz (%RU64 ticks per Hz), cTicksPerByte=%RU64, cbTransferChunk=%RU32, cTransferTicks=%RU64, " \ … … 451 474 # endif 452 475 453 LogFunc(("[SD%RU8] :Reset\n", uSD));476 LogFunc(("[SD%RU8] Reset\n", uSD)); 454 477 455 478 /* … … 482 505 483 506 /* Assign the default mixer sink to the stream. */ 484 pStream->pMixSink = hdaR3GetDefaultSink(pThis, uSD); 485 507 pStream->pMixSink = hdaR3GetDefaultSink(pThis, uSD); 508 509 /* Reset transfer stuff. */ 510 pStream->State.cbTransferProcessed = 0; 511 pStream->State.cTransferPendingInterrupts = 0; 486 512 pStream->State.tsTransferLast = 0; 487 513 pStream->State.tsTransferNext = 0; 488 514 515 /* Initialize other timestamps. */ 516 pStream->State.tsLastUpdateNs = 0; 517 489 518 RT_ZERO(pStream->State.BDLE); 490 519 pStream->State.uCurBDLE = 0; … … 492 521 if (pStream->State.pCircBuf) 493 522 RTCircBufReset(pStream->State.pCircBuf); 494 495 /* Reset stream map. */496 hdaR3StreamMapReset(&pStream->State.Mapping);497 498 /* (Re-)initialize the stream with current values. */499 int rc2 = hdaR3StreamInit(pStream, uSD);500 AssertRC(rc2);501 523 502 524 /* Reset the stream's period. */ … … 534 556 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 535 557 536 LogFunc(("[SD%RU8] :fEnable=%RTbool, pMixSink=%p\n", pStream->u8SD, fEnable, pStream->pMixSink));558 LogFunc(("[SD%RU8] fEnable=%RTbool, pMixSink=%p\n", pStream->u8SD, fEnable, pStream->pMixSink)); 537 559 538 560 int rc = VINF_SUCCESS; … … 781 803 if (!pSink) 782 804 { 783 AssertMsgFailed(("[SD%RU8] :Can't read from a stream with no sink attached\n", pStream->u8SD));805 AssertMsgFailed(("[SD%RU8] Can't read from a stream with no sink attached\n", pStream->u8SD)); 784 806 785 807 if (pcbRead) … … 814 836 815 837 Assert(cbSrc >= cbWritten); 816 Log2Func(("[SD%RU8] :%RU32/%zu bytes read\n", pStream->u8SD, cbWritten, cbSrc));838 Log2Func(("[SD%RU8] %RU32/%zu bytes read\n", pStream->u8SD, cbWritten, cbSrc)); 817 839 } 818 840 … … 1565 1587 u32LPIB = RT_MIN(u32LPIB, pStream->u32CBL); 1566 1588 1567 LogFlowFunc(("[SD%RU8] :LPIB=%RU32 (DMA Position Buffer Enabled: %RTbool)\n",1589 LogFlowFunc(("[SD%RU8] LPIB=%RU32 (DMA Position Buffer Enabled: %RTbool)\n", 1568 1590 pStream->u8SD, u32LPIB, pThis->fDMAPosition)); 1569 1591 … … 1777 1799 RTThreadUserSignal(hThreadSelf); 1778 1800 1779 LogFunc(("[SD%RU8] :Started\n", pStream->u8SD));1801 LogFunc(("[SD%RU8] Started\n", pStream->u8SD)); 1780 1802 1781 1803 for (;;) … … 1806 1828 } 1807 1829 1808 LogFunc(("[SD%RU8] :Ended\n", pStream->u8SD));1830 LogFunc(("[SD%RU8] Ended\n", pStream->u8SD)); 1809 1831 1810 1832 ASMAtomicXchgBool(&pAIO->fStarted, false); … … 1851 1873 rc = VINF_SUCCESS; 1852 1874 1853 LogFunc(("[SD%RU8] :Returning %Rrc\n", pStream->u8SD, rc));1875 LogFunc(("[SD%RU8] Returning %Rrc\n", pStream->u8SD, rc)); 1854 1876 return rc; 1855 1877 } … … 1890 1912 } 1891 1913 1892 LogFunc(("[SD%RU8] :Returning %Rrc\n", pStream->u8SD, rc));1914 LogFunc(("[SD%RU8] Returning %Rrc\n", pStream->u8SD, rc)); 1893 1915 return rc; 1894 1916 }
Note:
See TracChangeset
for help on using the changeset viewer.

