Changeset 89874 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Jun 24, 2021 9:51:51 AM (3 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHda.cpp
r89873 r89874 4753 4753 "|BufSizeOutMs" 4754 4754 "|InitialDelayMs" 4755 "|TimerHz"4756 4755 "|DebugEnabled" 4757 4756 "|DebugPathOut", … … 4777 4776 return PDMDEV_SET_ERROR(pDevIns, VERR_OUT_OF_RANGE, 4778 4777 N_("HDA configuration error: 'BufSizeOutMs' is out of bound, max 2000 ms")); 4779 4780 /** @todo uTimerHz isn't used for anything anymore. */4781 rc = pHlp->pfnCFGMQueryU16Def(pCfg, "TimerHz", &pThis->uTimerHz, HDA_TIMER_HZ_DEFAULT);4782 if (RT_FAILURE(rc))4783 return PDMDEV_SET_ERROR(pDevIns, rc,4784 N_("HDA configuration error: failed to read Hertz (Hz) rate as unsigned integer"));4785 if (pThis->uTimerHz != HDA_TIMER_HZ_DEFAULT)4786 LogRel(("HDA: Using custom device timer rate (%RU16Hz)\n", pThis->uTimerHz));4787 4778 4788 4779 /** @devcfgm{hda,InitialDelayMs,uint16_t,0,256,12,ms} -
trunk/src/VBox/Devices/Audio/DevHda.h
r89873 r89874 129 129 /** Current IRQ level. */ 130 130 uint8_t u8IRQL; 131 uint8_t abPadding[4]; 132 /** The device timer Hz rate. Defaults to HDA_TIMER_HZ_DEFAULT. */ 133 uint16_t uTimerHz; 131 uint8_t abPadding[4 + 2]; 134 132 /** Number of milliseconds to delay kicking off the AIO when a stream starts. 135 133 * @sa InitialDelayMs config value. */ -
trunk/src/VBox/Devices/Audio/DevHdaCommon.h
r89869 r89874 107 107 */ 108 108 109 /** Default timer frequency (in Hz).110 *111 * 20 Hz now seems enough for most setups, even with load on the guest.112 * Raising the rate will produce more I/O load on the guest and therefore113 * also will affect the performance.114 */115 #define HDA_TIMER_HZ_DEFAULT 100116 117 /** Default position adjustment (in audio samples).118 *119 * For snd_hda_intel (Linux guests), the first BDL entry always is being used as120 * so-called BDL adjustment, which can vary, and is being used for chipsets which121 * misbehave and/or are incorrectly implemented.122 *123 * The BDL adjustment entry *always* has the IOC (Interrupt on Completion) bit set.124 *125 * For Intel Baytrail / Braswell implementations the BDL default adjustment is 32 frames, whereas126 * for ICH / PCH it's only one (1) frame.127 *128 * See default_bdl_pos_adj() and snd_hdac_stream_setup_periods() for more information.129 *130 * By default we apply some simple heuristics in hdaStreamInit().131 */132 #define HDA_POS_ADJUST_DEFAULT 0133 134 /** HDA's (fixed) audio frame size in bytes.135 * We only support 16-bit stereo frames at the moment. */136 #define HDA_FRAME_SIZE_DEFAULT 4137 138 109 /** Offset of the SD0 register map. */ 139 110 #define HDA_REG_DESC_SD0_BASE 0x80 -
trunk/src/VBox/Devices/Audio/DevHdaStream.cpp
r89869 r89874 651 651 652 652 /* 653 * Calculate the transfer Hz for use in the circular buffer calculation. 653 * Calculate the transfer Hz for use in the circular buffer calculation 654 * and the average period for the scheduling hint. 654 655 */ 655 656 uint32_t cbMaxPeriod = 0; 656 657 uint32_t cbMinPeriod = UINT32_MAX; 658 uint64_t cTicks = 0; 657 659 uint32_t cPeriods = 0; 658 for (uint32_t i = 0; i < pStreamShared->State.cSchedule; i++)660 for (uint32_t i = pStreamShared->State.cSchedulePrologue; i < pStreamShared->State.cSchedule; i++) 659 661 { 660 662 uint32_t cbPeriod = pStreamShared->State.aSchedule[i].cbPeriod; … … 662 664 cbMinPeriod = RT_MIN(cbMinPeriod, cbPeriod); 663 665 cPeriods += pStreamShared->State.aSchedule[i].cLoops; 664 } 666 cTicks += pStreamShared->State.aSchedule[i].cPeriodTicks * pStreamShared->State.aSchedule[i].cLoops; 667 } 668 /* Only consider the prologue in relation to the max period. */ 669 for (uint32_t i = 0; i < pStreamShared->State.cSchedulePrologue; i++) 670 cbMaxPeriod = RT_MAX(cbMaxPeriod, pStreamShared->State.aSchedule[i].cbPeriod); 671 672 AssertLogRelReturn(cPeriods > 0, VERR_INTERNAL_ERROR_3); 665 673 uint64_t const cbTransferPerSec = RT_MAX(PDMAudioPropsFramesToBytes(&pCfg->Props, pCfg->Props.uHz), 666 674 4096 /* zero div prevention: min is 6kHz, picked 4k in case I'm mistaken */); … … 675 683 676 684 pStreamShared->State.cbAvgTransfer = (uint32_t)(cbTotal + cPeriods - 1) / cPeriods; 685 686 /* Calculate the average scheduling period length in nanoseconds. */ 687 uint64_t const cTimerResolution = PDMDevHlpTimerGetFreq(pDevIns, pStreamShared->hTimer); 688 Assert(cTimerResolution <= UINT32_MAX); 689 uint64_t const cNsPerPeriod = ASMMultU64ByU32DivByU32(cTicks / cPeriods, RT_NS_1SEC, cTimerResolution); 690 AssertLogRelReturn(cNsPerPeriod > 0, VERR_INTERNAL_ERROR_3); 677 691 678 692 /* For input streams we must determin a pre-buffering requirement. … … 687 701 * Set up data transfer stuff. 688 702 */ 689 690 /* Assign the global device rate to the stream I/O timer as default. */691 pStreamShared->State.uTimerIoHz = pThis->uTimerHz;692 ASSERT_GUEST_LOGREL_MSG_STMT(pStreamShared->State.uTimerIoHz,693 ("I/O timer Hz rate for stream #%RU8 is invalid\n", uSD),694 pStreamShared->State.uTimerIoHz = HDA_TIMER_HZ_DEFAULT);695 696 703 /* Set I/O scheduling hint for the backends. */ 697 /** @todo r=bird: derive this from the schedule instead of using the 698 * uTimerIoHz, as that's almost pure non-sense now. */ 699 pCfg->Device.cMsSchedulingHint = RT_MS_1SEC / pStreamShared->State.uTimerIoHz; 704 pCfg->Device.cMsSchedulingHint = cNsPerPeriod > RT_NS_1MS ? (cNsPerPeriod + RT_NS_1MS / 2) / RT_NS_1MS : 1; 700 705 LogRel2(("HDA: Stream #%RU8 set scheduling hint for the backends to %RU32ms\n", uSD, pCfg->Device.cMsSchedulingHint)); 701 702 706 703 707 /* Make sure to also update the stream's DMA counter (based on its current LPIB value). */ 704 708 /** @todo r=bird: We use LPIB as-is here, so if it's not zero we have to 705 * locate the right place in the schedule and whatnot... */ 709 * locate the right place in the schedule and whatnot... 710 * 711 * This is a similar scenario as when loading state saved, btw. 712 */ 706 713 if (HDA_STREAM_REG(pThis, LPIB, uSD) != 0) 707 714 LogRel2(("HDA: Warning! Stream #%RU8 is set up with LPIB=%#RX32 instead of zero!\n", uSD, HDA_STREAM_REG(pThis, LPIB, uSD))); … … 755 762 * channels we don't support / need to save space. 756 763 */ 757 uint32_t msCircBuf = RT_MS_1SEC * 6 / RT_MIN(uTransferHz, pStreamShared->State.uTimerIoHz); 758 msCircBuf = RT_MAX(msCircBuf, pThis->msInitialDelay + RT_MS_1SEC * 6 / uTransferHz); 759 760 uint32_t cbCircBuf = PDMAudioPropsMilliToBytes(&pCfg->Props, msCircBuf); 764 uint32_t cbCircBuf = PDMAudioPropsMilliToBytes(&pCfg->Props, pThis->msInitialDelay + RT_MS_1SEC * 6 / uTransferHz); 761 765 LogRel2(("HDA: Stream #%RU8 default ring buffer size is %RU32 bytes / %RU64 ms\n", 762 766 uSD, cbCircBuf, PDMAudioPropsBytesToMilli(&pCfg->Props, cbCircBuf))); -
trunk/src/VBox/Devices/Audio/DevHdaStream.h
r89869 r89874 96 96 /** Flag indicating if the stream is in running state or not. */ 97 97 volatile bool fRunning; 98 /** The stream's I/O timer Hz rate. */99 uint16_t uTimerIoHz;100 98 /** How many interrupts are pending due to 101 99 * BDLE interrupt-on-completion (IOC) bits set. */ 102 100 uint8_t cTransferPendingInterrupts; 103 /** Unused, padding. */104 uint8_t abPadding1[2];105 101 /** Input streams only: Set when we switch from feeding the guest silence and 106 102 * commits to proving actual audio input bytes. */ … … 108 104 /** Input streams only: The number of bytes we need to prebuffer. */ 109 105 uint32_t cbInputPreBuffer; 110 uint32_t u32Padding2;111 106 /** Timestamp (absolute, in timer ticks) of the last DMA data transfer. 112 107 * @note This is used for wall clock (WALCLK) calculations. */ … … 159 154 /** Current loop number within the current scheduling step. */ 160 155 uint32_t idxScheduleLoop; 156 157 /** Aligning the next members on 16 bytes. */ 158 uint64_t u64Padding; 161 159 162 160 /** Buffer descriptors and additional timer scheduling state.
Note:
See TracChangeset
for help on using the changeset viewer.