Changeset 70278 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Dec 21, 2017 1:54:17 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 119873
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r70251 r70278 1529 1529 1530 1530 uint64_t cTicksToNext = pStream->State.cTransferTicks; 1531 1532 Log3Func(("[SD%RU8] cTicksElapsed=%RU64, cTicksTransferred=%RU64, cTicksToNext=%RU64\n", 1533 pStream->u8SD, cTicksElapsed, cTicksTransferred, cTicksToNext)); 1534 1535 Log3Func(("[SD%RU8] cbTransferProcessed=%RU32, cbTransferChunk=%RU32, cbTransferSize=%RU32\n", 1536 pStream->u8SD, pStream->State.cbTransferProcessed, pStream->State.cbTransferChunk, pStream->State.cbTransferSize)); 1537 1538 if (cTicksElapsed <= cTicksToNext) 1539 { 1540 cTicksToNext = cTicksToNext - cTicksElapsed; 1541 } 1542 else /* Catch up. */ 1543 { 1544 Log3Func(("[SD%RU8] Warning: Lagging behind (%RU64 ticks elapsed, maximum allowed is %RU64)\n", 1545 pStream->u8SD, cTicksElapsed, cTicksToNext)); 1546 1547 LogRelMax2(64, ("HDA: Stream #%RU8 interrupt lagging behind (expected %uus, got %uus), trying to catch up ...\n", 1548 pStream->u8SD, 1549 (TMTimerGetFreq(pThis->pTimer) / pThis->u16TimerHz) / 1000, (tsNow - pStream->State.tsTransferLast) / 1000)); 1550 1551 cTicksToNext = 0; 1552 } 1553 1554 Log3Func(("[SD%RU8] -> cTicksToNext=%RU64\n", pStream->u8SD, cTicksToNext)); 1555 1556 /* Reset processed data counter. */ 1557 pStream->State.cbTransferProcessed = 0; 1558 1559 /* Re-arm the timer. */ 1560 hdaTimerSet(pThis, tsNow + cTicksToNext, false /* fForce */); 1531 if (cTicksToNext) /* Only do any calculations if the stream currently is set up for transfers. */ 1532 { 1533 Log3Func(("[SD%RU8] cTicksElapsed=%RU64, cTicksTransferred=%RU64, cTicksToNext=%RU64\n", 1534 pStream->u8SD, cTicksElapsed, cTicksTransferred, cTicksToNext)); 1535 1536 Log3Func(("[SD%RU8] cbTransferProcessed=%RU32, cbTransferChunk=%RU32, cbTransferSize=%RU32\n", 1537 pStream->u8SD, pStream->State.cbTransferProcessed, pStream->State.cbTransferChunk, pStream->State.cbTransferSize)); 1538 1539 if (cTicksElapsed <= cTicksToNext) 1540 { 1541 cTicksToNext = cTicksToNext - cTicksElapsed; 1542 } 1543 else /* Catch up. */ 1544 { 1545 Log3Func(("[SD%RU8] Warning: Lagging behind (%RU64 ticks elapsed, maximum allowed is %RU64)\n", 1546 pStream->u8SD, cTicksElapsed, cTicksToNext)); 1547 1548 LogRelMax2(64, ("HDA: Stream #%RU8 interrupt lagging behind (expected %uus, got %uus), trying to catch up ...\n", 1549 pStream->u8SD, 1550 (TMTimerGetFreq(pThis->pTimer) / pThis->u16TimerHz) / 1000, (tsNow - pStream->State.tsTransferLast) / 1000)); 1551 1552 cTicksToNext = 0; 1553 } 1554 1555 Log3Func(("[SD%RU8] -> cTicksToNext=%RU64\n", pStream->u8SD, cTicksToNext)); 1556 1557 /* Reset processed data counter. */ 1558 pStream->State.cbTransferProcessed = 0; 1559 1560 /* Re-arm the timer. */ 1561 hdaTimerSet(pThis, tsNow + cTicksToNext, false /* fForce */); 1562 } 1561 1563 1562 1564 DEVHDA_UNLOCK_BOTH(pThis); … … 2481 2483 2482 2484 AssertPtr(pSink->pMixSink); 2483 LogFlowFunc(("Sink=%s, enmMixerCtl=%d\n", pSink->pMixSink->pszName, enmMixerCtl));2485 LogFlowFunc(("Sink=%s, Mixer control=%s\n", pSink->pMixSink->pszName, DrvAudioHlpAudMixerCtlToStr(enmMixerCtl))); 2484 2486 } 2485 2487 else … … 2564 2566 rc = VERR_NOT_FOUND; 2565 2567 2566 LogF lowFunc(("enmMixerCtl=%d, rc=%Rrc\n", enmMixerCtl, rc));2568 LogFunc(("Mixer control=%s, rc=%Rrc\n", DrvAudioHlpAudMixerCtlToStr(enmMixerCtl), rc)); 2567 2569 return rc; 2568 2570 } 2569 2571 2570 2572 /** 2571 * Sets a SDn stream number and channel to a particular mixer control. 2573 * Controls an input / output converter widget, that is, which converter is connected 2574 * to which stream (and channel). 2572 2575 * 2573 2576 * @returns IPRT status code. … … 2581 2584 static DECLCALLBACK(int) hdaMixerControl(PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, uint8_t uSD, uint8_t uChannel) 2582 2585 { 2583 LogF lowFunc(("enmMixerCtl=%RU32, uSD=%RU8, uChannel=%RU8\n", enmMixerCtl, uSD, uChannel));2586 LogFunc(("enmMixerCtl=%s, uSD=%RU8, uChannel=%RU8\n", DrvAudioHlpAudMixerCtlToStr(enmMixerCtl), uSD, uChannel)); 2584 2587 2585 2588 if (uSD == 0) /* Stream number 0 is reserved. */ 2586 2589 { 2587 Log FlowFunc(("Invalid SDn (%RU8) number for mixer control %d, ignoring\n", uSD, enmMixerCtl));2590 Log2Func(("Invalid SDn (%RU8) number for mixer control '%s', ignoring\n", uSD, DrvAudioHlpAudMixerCtlToStr(enmMixerCtl))); 2588 2591 return VINF_SUCCESS; 2589 2592 } … … 2594 2597 uSD--; 2595 2598 2596 int rc; 2599 #ifndef VBOX_WITH_AUDIO_HDA_MIC_IN 2600 /* Only SDI0 (Line-In) is supported. */ 2601 if ( hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN 2602 && uSD >= 1) 2603 { 2604 LogRel2(("HDA: Dedicated Mic-In support not imlpemented / built-in (stream #%RU8), using Line-In (stream #0) instead\n", uSD)); 2605 uSD = 0; 2606 } 2607 #endif 2608 2609 int rc = VINF_SUCCESS; 2597 2610 2598 2611 PHDAMIXERSINK pSink = hdaMixerControlToSink(pThis, enmMixerCtl); 2599 2612 if (pSink) 2600 2613 { 2614 AssertPtr(pSink->pMixSink); 2615 2616 /* If this an output stream, determine the correct SD#. */ 2601 2617 if ( (uSD < HDA_MAX_SDI) 2602 2618 && AudioMixerSinkGetDir(pSink->pMixSink) == AUDMIXSINKDIR_OUTPUT) … … 2605 2621 } 2606 2622 2607 LogFlowFunc(("%s: Setting to stream ID=%RU8, channel=%RU8, enmMixerCtl=%RU32\n", 2608 pSink->pMixSink->pszName, uSD, uChannel, enmMixerCtl)); 2623 /* Detach the existing stream from the sink. */ 2624 if ( pSink->pStream 2625 && ( pSink->pStream->u8SD != uSD 2626 || pSink->pStream->u8Channel != uChannel) 2627 ) 2628 { 2629 LogFunc(("Sink '%s' was assigned to stream #%RU8 (channel %RU8) before\n", 2630 pSink->pMixSink->pszName, pSink->pStream->u8SD, pSink->pStream->u8Channel)); 2631 2632 hdaStreamLock(pSink->pStream); 2633 2634 /* Only disable the stream if the stream descriptor # has changed. */ 2635 if (pSink->pStream->u8SD != uSD) 2636 hdaStreamEnable(pSink->pStream, false); 2637 2638 pSink->pStream->pMixSink = NULL; 2639 2640 hdaStreamUnlock(pSink->pStream); 2641 2642 pSink->pStream = NULL; 2643 } 2609 2644 2610 2645 Assert(uSD < HDA_MAX_STREAMS); 2611 2646 2612 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD); 2613 if (pStream) 2614 { 2615 hdaStreamLock(pStream); 2616 2617 pSink->pStream = pStream; 2618 pStream->pMixSink = pSink; 2619 2620 hdaStreamUnlock(pStream); 2621 2622 rc = VINF_SUCCESS; 2623 } 2624 else 2625 { 2626 LogRel(("HDA: Guest wanted to assign invalid stream ID=%RU8 (channel %RU8) to mixer control %RU32, skipping\n", 2627 uSD, uChannel, enmMixerCtl)); 2628 rc = VERR_INVALID_PARAMETER; 2647 /* Attach the new stream to the sink. 2648 * Enabling the stream will be done by the gust via a separate SDnCTL call then. */ 2649 if (pSink->pStream == NULL) 2650 { 2651 LogRel2(("HDA: Setting sink '%s' to stream #%RU8 (channel %RU8), mixer control=%s\n", 2652 pSink->pMixSink->pszName, uSD, uChannel, DrvAudioHlpAudMixerCtlToStr(enmMixerCtl))); 2653 2654 PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD); 2655 if (pStream) 2656 { 2657 hdaStreamLock(pStream); 2658 2659 pSink->pStream = pStream; 2660 2661 pStream->u8Channel = uChannel; 2662 pStream->pMixSink = pSink; 2663 2664 hdaStreamUnlock(pStream); 2665 2666 rc = VINF_SUCCESS; 2667 } 2668 else 2669 rc = VERR_NOT_IMPLEMENTED; 2629 2670 } 2630 2671 } 2631 2672 else 2632 2673 rc = VERR_NOT_FOUND; 2674 2675 if (RT_FAILURE(rc)) 2676 LogRel(("HDA: Converter control for stream #%RU8 (channel %RU8) / mixer control '%s' failed with %Rrc, skipping\n", 2677 uSD, uChannel, DrvAudioHlpAudMixerCtlToStr(enmMixerCtl), rc)); 2633 2678 2634 2679 LogFlowFuncLeaveRC(rc); -
trunk/src/VBox/Devices/Audio/HDAStream.cpp
r70246 r70278 388 388 #endif 389 389 390 /* Assign the default mixer sink to the stream. */ 391 pStream->pMixSink = hdaGetDefaultSink(pThis, uSD); 392 390 393 pStream->State.tsTransferLast = 0; 391 394 pStream->State.tsTransferNext = 0; … … 442 445 int rc = VINF_SUCCESS; 443 446 444 if (pStream->pMixSink) /* Stream attached to a sink? */ 445 { 446 AUDMIXSINKCMD enmCmd = fEnable 447 ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE; 448 449 /* First, enable or disable the stream and the stream's sink, if any. */ 450 if (pStream->pMixSink->pMixSink) 451 rc = AudioMixerSinkCtl(pStream->pMixSink->pMixSink, enmCmd); 452 453 if ( RT_SUCCESS(rc) 454 && pStream->Dbg.Runtime.fEnabled) 455 { 456 if (fEnable) 457 { 447 if (!pStream->pMixSink) /* Stream attached to a sink? */ 448 { 449 AssertMsgFailed(("Stream #%RU8 not has no mixer sink attached\n", pStream->u8SD)); 450 return VERR_WRONG_ORDER; 451 } 452 453 AUDMIXSINKCMD enmCmd = fEnable 454 ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE; 455 456 /* First, enable or disable the stream and the stream's sink, if any. */ 457 if (pStream->pMixSink->pMixSink) 458 rc = AudioMixerSinkCtl(pStream->pMixSink->pMixSink, enmCmd); 459 460 if ( RT_SUCCESS(rc) 461 && pStream->Dbg.Runtime.fEnabled) 462 { 463 Assert(DrvAudioHlpPCMPropsAreValid(&pStream->State.Cfg.Props)); 464 465 if (fEnable) 466 { 458 467 int rc2 = DrvAudioHlpFileOpen(pStream->Dbg.Runtime.pFileStream, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS, 459 468 &pStream->State.Cfg.Props); … … 463 472 &pStream->State.Cfg.Props); 464 473 AssertRC(rc2); 465 466 467 474 } 475 else 476 { 468 477 int rc2 = DrvAudioHlpFileClose(pStream->Dbg.Runtime.pFileStream); 469 478 AssertRC(rc2); … … 471 480 rc2 = DrvAudioHlpFileClose(pStream->Dbg.Runtime.pFileDMA); 472 481 AssertRC(rc2); 473 }474 482 } 475 483 } … … 558 566 bool hdaStreamTransferIsScheduled(PHDASTREAM pStream) 559 567 { 560 AssertPtrReturn(pStream, false); 568 if (!pStream) 569 return false; 570 561 571 AssertPtrReturn(pStream->pHDAState, false); 562 572 … … 819 829 uint32_t cbProcessed = 0; 820 830 uint32_t cbLeft = cbToProcess; 821 Assert(cbLeft % pStream->State.cbFrameSize == 0);822 831 823 832 uint8_t abChunk[HDA_FIFO_MAX + 1]; … … 1156 1165 void hdaStreamUpdate(PHDASTREAM pStream, bool fInTimer) 1157 1166 { 1167 if (!pStream) 1168 return; 1169 1158 1170 PAUDMIXSINK pSink = NULL; 1159 1171 if ( pStream->pMixSink … … 1231 1243 uint32_t cbReadable = AudioMixerSinkGetReadable(pSink); 1232 1244 1233 Log3Func(("[SD%RU8] cbReadable=%RU32\n", pStream->u8SD, cbReadable)); 1245 /* How much (guest input) data is available for writing at the moment for the HDA stream? */ 1246 const uint32_t cbFree = hdaStreamGetFree(pStream); 1247 1248 Log3Func(("[SD%RU8] cbReadable=%RU32, cbFree=%RU32\n", pStream->u8SD, cbReadable, cbFree)); 1249 1250 /* Do not write more than the sink can hold at the moment. 1251 * The host sets the overall pace. */ 1252 if (cbReadable > cbFree) 1253 cbReadable = cbFree; 1234 1254 1235 1255 if (cbReadable) … … 1243 1263 AssertRCBreak(rc2); 1244 1264 1265 if (!cbRead) 1266 { 1267 AssertMsgFailed(("Nothing read from sink, even if %RU32 bytes were (still) announced\n", cbReadable)); 1268 break; 1269 } 1270 1245 1271 /* Write (guest input) data to the stream which was read from stream's sink before. */ 1246 rc2 = hdaStreamWrite(pStream, abFIFO, cbRead, NULL /* pcbWritten */); 1272 uint32_t cbWritten; 1273 rc2 = hdaStreamWrite(pStream, abFIFO, cbRead, &cbWritten); 1247 1274 AssertRCBreak(rc2); 1275 1276 if (!cbWritten) 1277 { 1278 AssertFailed(); /* Should never happen, as we know how much we can write. */ 1279 break; 1280 } 1248 1281 1249 1282 Assert(cbReadable >= cbRead);
Note:
See TracChangeset
for help on using the changeset viewer.