Index: trunk/src/VBox/Devices/Audio/DevHDA.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevHDA.cpp	(revision 88168)
+++ trunk/src/VBox/Devices/Audio/DevHDA.cpp	(revision 88170)
@@ -59,5 +59,4 @@
 #include "HDAStream.h"
 #include "HDAStreamMap.h"
-#include "HDAStreamPeriod.h"
 
 #include "DrvAudio.h"
@@ -534,14 +533,4 @@
 };
 
-/** HDASTREAMPERIOD field descriptors for the v7 saved state. */
-static SSMFIELD const g_aSSMStreamPeriodFields7[] =
-{
-    SSMFIELD_ENTRY(HDASTREAMPERIOD, u64StartWalClk),
-    SSMFIELD_ENTRY(HDASTREAMPERIOD, u64ElapsedWalClk),
-    SSMFIELD_ENTRY(HDASTREAMPERIOD, cFramesTransferred),
-    SSMFIELD_ENTRY_OLD(cIntPending, sizeof(uint8_t)),   /** @todo Not sure what we should for non-zero values on restore... ignoring it for now.  */
-    SSMFIELD_ENTRY_TERM()
-};
-
 /** HDABDLE field descriptors for the v1 thru v4 saved states. */
 static SSMFIELD const g_aSSMStreamBdleFields1234[] =
@@ -1154,11 +1143,69 @@
 }
 
+/**
+ * Gets the wall clock.
+ *
+ * Used by hdaRegReadWALCLK() and 'info hda'.
+ *
+ * @returns The full wall clock value
+ * @param   pDevIns     The device instance.
+ * @param   pThis       The shared HDA device state.
+ */
+static uint64_t hdaGetWallClock(PPDMDEVINS pDevIns, PHDASTATE pThis)
+{
+    /*
+     * The wall clock is calculated from the virtual sync clock.  Since
+     * the clock is supposed to reset to zero on controller reset, a
+     * start offset is subtracted.
+     *
+     * In addition, we hold the clock back when there are active DMA engines
+     * so that the guest won't conclude we've gotten further in the buffer
+     * processing than what we really have. (We generally read a whole buffer
+     * at once when the IOC is due, so we're a lot later than what real
+     * hardware would be in reading/writing the buffers.)
+     *
+     * Here are some old notes from the DMA engine that might be useful even
+     * if a little dated:
+     *
+     * Note 1) Only certain guests (like Linux' snd_hda_intel) rely on the WALCLK register
+     *         in order to determine the correct timing of the sound device. Other guests
+     *         like Windows 7 + 10 (or even more exotic ones like Haiku) will completely
+     *         ignore this.
+     *
+     * Note 2) When updating the WALCLK register too often / early (or even in a non-monotonic
+     *         fashion) this *will* upset guest device drivers and will completely fuck up the
+     *         sound output. Running VLC on the guest will tell!
+     */
+    uint64_t const uFreq    = PDMDevHlpTimerGetFreq(pDevIns, pThis->aStreams[0].hTimer);
+    Assert(uFreq <= UINT32_MAX);
+    uint64_t const tsStart  = 0; /** @todo pThis->tsWallClkStart (as it is reset on controller reset) */
+    uint64_t const tsNow    = PDMDevHlpTimerGet(pDevIns, pThis->aStreams[0].hTimer);
+
+    /* Find the oldest DMA transfer timestamp from the active streams. */
+    int            iDmaNow  = -1;
+    uint64_t       tsDmaNow = tsNow;
+    for (size_t i = 0; i < RT_ELEMENTS(pThis->aStreams); i++)
+        if (   pThis->aStreams[i].State.fRunning
+            && pThis->aStreams[i].State.tsTransferLast < tsDmaNow
+            && pThis->aStreams[i].State.tsTransferLast > tsStart)
+        {
+            tsDmaNow = pThis->aStreams[i].State.tsTransferLast;
+            iDmaNow  = (int)i;
+        }
+
+    /* Convert it to wall clock ticks. */
+    uint64_t const uWallClkNow = ASMMultU64ByU32DivByU32(tsDmaNow - tsStart,
+                                                         24000000 /*Wall clock frequency */,
+                                                         uFreq);
+    Log3Func(("Returning %#RX64 - tsNow=%#RX64 tsDmaNow=%#RX64 (%d) -> %#RX64\n",
+              uWallClkNow, tsNow, tsDmaNow, iDmaNow, tsNow - tsDmaNow));
+    RT_NOREF(iDmaNow);
+    return uWallClkNow;
+}
+
 static VBOXSTRICTRC hdaRegReadWALCLK(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value)
 {
     RT_NOREF(pDevIns, iReg);
-
-    const uint64_t u64WalClkCur = ASMAtomicReadU64(&pThis->u64WalClk);
-    *pu32Value = RT_LO_U32(u64WalClkCur);
-
+    *pu32Value = (uint32_t)hdaGetWallClock(pDevIns, pThis);
     return VINF_SUCCESS;
 }
@@ -1431,13 +1478,4 @@
                     pThisCC->cStreamsActive++;
 
-                    /* (Re-)init the stream's period. */
-                    hdaR3StreamPeriodInit(&pStreamShared->State.Period, uSD, pStreamShared->u16LVI,
-                                          pStreamShared->u32CBL, &pStreamShared->State.Cfg);
-
-                    /* Begin a new period for this stream. */
-                    rc2 = hdaR3StreamPeriodBegin(&pStreamShared->State.Period,
-                                                 hdaWalClkGetCurrent(pThis) /* Use current wall clock time */);
-                    AssertRC(rc2);
-
                     /** @todo move this into a HDAStream.cpp function. */
                     uint64_t tsNow;
@@ -1452,4 +1490,6 @@
                         /* Input streams: Arm the timer and kick the AIO thread. */
                         tsNow = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer);
+                        pStreamShared->State.tsTransferLast = tsNow; /* for WALCLK */
+
                         uint64_t tsTransferNext = tsNow + pStreamShared->State.aSchedule[0].cPeriodTicks;
                         pStreamShared->State.tsTransferNext = tsTransferNext; /* legacy */
@@ -1457,4 +1497,5 @@
                         Log3Func(("[SD%RU8] tsTransferNext=%RU64 (in %RU64)\n",
                                   pStreamShared->u8SD, tsTransferNext, tsTransferNext - tsNow));
+
                         int rc = PDMDevHlpTimerSet(pDevIns, pStreamShared->hTimer, tsTransferNext);
                         AssertRC(rc);
@@ -1471,7 +1512,4 @@
                     if (pThisCC->cStreamsActive)
                         pThisCC->cStreamsActive--;
-
-                    /* Reset the period. */
-                    hdaR3StreamPeriodReset(&pStreamShared->State.Period);
 
                     hdaR3StreamMarkStopped(pStreamShared);
@@ -2918,4 +2956,7 @@
     HDA_REG(pThis, STATESTS) = 0x1;
 
+    /* Reset the wall clock. */
+    pThis->tsWalClkStart = PDMDevHlpTimerGet(pDevIns, pThis->aStreams[0].hTimer);
+
     LogFlowFuncLeave();
     LogRel(("HDA: Reset\n"));
@@ -3402,8 +3443,4 @@
     AssertRCReturn(rc, rc);
 
-    rc = pHlp->pfnSSMPutStructEx(pSSM, &pStreamShared->State.Period, sizeof(pStreamShared->State.Period),
-                                 0 /* fFlags */, g_aSSMStreamPeriodFields7, NULL);
-    AssertRCReturn(rc, rc);
-
     uint32_t cbCircBufSize = 0;
     uint32_t cbCircBufUsed = 0;
@@ -3475,5 +3512,5 @@
 
     /* Save controller-specifc internals. */
-    pHlp->pfnSSMPutU64(pSSM, pThis->u64WalClk);
+    pHlp->pfnSSMPutU64(pSSM, pThis->tsWalClkStart);
     pHlp->pfnSSMPutU8(pSSM, pThis->u8IRQL);
 
@@ -3526,7 +3563,4 @@
             hdaR3StreamAsyncIOEnable(pStreamR3, true /* fEnable */);
 #endif
-            /* Resume the stream's period. */
-            hdaR3StreamPeriodResume(&pStreamShared->State.Period);
-
             /* (Re-)enable the stream. */
             rc2 = hdaR3StreamEnable(pStreamShared, pStreamR3, true /* fEnable */);
@@ -3910,7 +3944,18 @@
         || pHlp->pfnSSMHandleVersion(pSSM)  >= VBOX_FULL_VERSION_MAKE(5, 2, 0))
     {
-        pHlp->pfnSSMGetU64(pSSM, &pThis->u64WalClk);
+        pHlp->pfnSSMGetU64(pSSM, &pThis->tsWalClkStart); /* Was current wall clock */
         rc = pHlp->pfnSSMGetU8(pSSM, &pThis->u8IRQL);
         AssertRCReturn(rc, rc);
+
+        /* Convert the saved wall clock timestamp to a start timestamp. */
+        if (uVersion < HDA_SAVED_STATE_WITHOUT_PERIOD && pThis->tsWalClkStart != 0)
+        {
+            uint64_t const cTimerTicksPerSec = PDMDevHlpTimerGetFreq(pDevIns, pThis->aStreams[0].hTimer);
+            AssertLogRel(cTimerTicksPerSec <= UINT32_MAX);
+            pThis->tsWalClkStart = ASMMultU64ByU32DivByU32(pThis->tsWalClkStart,
+                                                           cTimerTicksPerSec,
+                                                           24000000 /* wall clock freq */);
+            pThis->tsWalClkStart = PDMDevHlpTimerGet(pDevIns, pThis->aStreams[0].hTimer) - pThis->tsWalClkStart;
+        }
     }
 
@@ -3975,10 +4020,18 @@
          * Load period state.
          */
-        hdaR3StreamPeriodInit(&pStreamShared->State.Period, pStreamShared->u8SD, pStreamShared->u16LVI,
-                              pStreamShared->u32CBL, &pStreamShared->State.Cfg);
-
-        rc = pHlp->pfnSSMGetStructEx(pSSM, &pStreamShared->State.Period, sizeof(pStreamShared->State.Period),
-                                     0 /* fFlags */, g_aSSMStreamPeriodFields7, NULL);
-        AssertRCReturn(rc, rc);
+        if (uVersion <= HDA_SAVED_STATE_WITHOUT_PERIOD)
+        {
+            static SSMFIELD const s_aSSMStreamPeriodFields7[] = /* For the removed HDASTREAMPERIOD structure. */
+            {
+                SSMFIELD_ENTRY_OLD(u64StartWalClk,     sizeof(uint64_t)),
+                SSMFIELD_ENTRY_OLD(u64ElapsedWalClk,   sizeof(uint64_t)),
+                SSMFIELD_ENTRY_OLD(cFramesTransferred, sizeof(uint32_t)),
+                SSMFIELD_ENTRY_OLD(cIntPending, sizeof(uint8_t)),   /** @todo Not sure what we should for non-zero values on restore... ignoring it for now.  */
+                SSMFIELD_ENTRY_TERM()
+            };
+            uint8_t bWhatever = 0;
+            rc = pHlp->pfnSSMGetStructEx(pSSM, &bWhatever, sizeof(bWhatever), 0 /* fFlags */, s_aSSMStreamPeriodFields7, NULL);
+            AssertRCReturn(rc, rc);
+        }
 
         /*
@@ -4137,5 +4190,5 @@
 
 /** Worker for hdaR3DbgInfo.  */
-static void hdaR3DbgPrintRegister(PHDASTATE pThis, PCDBGFINFOHLP pHlp, int iHdaIndex)
+static void hdaR3DbgPrintRegister(PPDMDEVINS pDevIns, PHDASTATE pThis, PCDBGFINFOHLP pHlp, int iHdaIndex)
 {
     /** @todo HDA_REG_IDX_NOMEM & GCAP both uses mem_idx zero, no flag or anything to tell them appart. */
@@ -4143,5 +4196,5 @@
         pHlp->pfnPrintf(pHlp, "%s: 0x%x\n", g_aHdaRegMap[iHdaIndex].abbrev, pThis->au32Regs[g_aHdaRegMap[iHdaIndex].mem_idx]);
     else
-        pHlp->pfnPrintf(pHlp, "%s: 0x%RX64\n", g_aHdaRegMap[iHdaIndex].abbrev, pThis->u64WalClk);
+        pHlp->pfnPrintf(pHlp, "%s: 0x%RX64\n", g_aHdaRegMap[iHdaIndex].abbrev, hdaGetWallClock(pDevIns, pThis));
 }
 
@@ -4154,8 +4207,8 @@
     int idxReg = hdaR3DbgLookupRegByName(pszArgs);
     if (idxReg != -1)
-        hdaR3DbgPrintRegister(pThis, pHlp, idxReg);
+        hdaR3DbgPrintRegister(pDevIns, pThis, pHlp, idxReg);
     else
         for (idxReg = 0; idxReg < HDA_NUM_REGS; ++idxReg)
-            hdaR3DbgPrintRegister(pThis, pHlp, idxReg);
+            hdaR3DbgPrintRegister(pDevIns, pThis, pHlp, idxReg);
 }
 
@@ -5031,6 +5084,7 @@
     for (size_t i = 0; i < HDA_MAX_STREAMS; i++)
     {
+        /* We need the first timer in ring-0 to calculate the wall clock (WALCLK) time. */
         rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hdaR3Timer, (void *)(uintptr_t)i,
-                                  TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
+                                  TMTIMER_FLAGS_NO_CRIT_SECT | (i == 0 ? TMTIMER_FLAGS_RING0 : TMTIMER_FLAGS_NO_RING0),
                                   s_apszNames[i], &pThis->aStreams[i].hTimer);
         AssertRCReturn(rc, rc);
Index: trunk/src/VBox/Devices/Audio/DevHDA.h
===================================================================
--- trunk/src/VBox/Devices/Audio/DevHDA.h	(revision 88168)
+++ trunk/src/VBox/Devices/Audio/DevHDA.h	(revision 88170)
@@ -31,5 +31,4 @@
 #include "HDAStream.h"
 #include "HDAStreamMap.h"
-#include "HDAStreamPeriod.h"
 
 #ifdef DEBUG_andy
@@ -119,13 +118,4 @@
     /** Current IRQ level. */
     uint8_t                 u8IRQL;
-#ifdef VBOX_STRICT
-    /** Wall clock (WALCLK) stale count.
-     *  This indicates the number of set wall clock values which did not actually
-     *  move the counter forward (stale). */
-    uint8_t                 u8WalClkStaleCnt;
-#else
-    uint8_t                 bPadding1;
-#endif
-    uint8_t                 bPadding2;
     /** The device timer Hz rate. Defaults to HDA_TIMER_HZ_DEFAULT. */
     uint16_t                uTimerHz;
@@ -139,7 +129,6 @@
      *  The actual buffer size in bytes will depend on the actual stream configuration. */
     uint16_t                cbCircBufOutMs;
-    uint16_t                au16Padding3[3];
-    /** Last updated wall clock (WALCLK) counter. */
-    uint64_t                u64WalClk;
+    /** The start time of the wall clock (WALCLK), measured on the virtual sync clock. */
+    uint64_t                tsWalClkStart;
     /** The CORB buffer. */
     uint32_t                au32CorbBuf[HDA_CORB_SIZE];
Index: trunk/src/VBox/Devices/Audio/DevHDACommon.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevHDACommon.cpp	(revision 88168)
+++ trunk/src/VBox/Devices/Audio/DevHDACommon.cpp	(revision 88170)
@@ -104,158 +104,5 @@
 }
 
-/**
- * Retrieves the currently set value for the wall clock.
- *
- * @return  IPRT status code.
- * @return  Currently set wall clock value.
- * @param   pThis               The shared HDA device state.
- *
- * @remark  Operation is atomic.
- */
-uint64_t hdaWalClkGetCurrent(PHDASTATE pThis)
-{
-    return ASMAtomicReadU64(&pThis->u64WalClk);
-}
-
 #ifdef IN_RING3
-
-/**
- * Helper for hdaR3WalClkSet.
- */
-DECLINLINE(PHDASTREAMPERIOD) hdaR3SinkToStreamPeriod(PHDAMIXERSINK pSink)
-{
-    PHDASTREAM pStream = hdaR3GetSharedStreamFromSink(pSink);
-    if (pStream)
-        return &pStream->State.Period;
-    return NULL;
-}
-
-/**
- * Returns the current maximum value the wall clock counter can be set to.
- *
- * This maximum value depends on all currently handled HDA streams and their own current timing.
- *
- * @return  Current maximum value the wall clock counter can be set to.
- * @param   pThis               The shared HDA device state.
- * @param   pThisCC             The ring-3 HDA device state.
- *
- * @remark  Does not actually set the wall clock counter.
- *
- */
-uint64_t hdaR3WalClkGetMax(PHDASTATE pThis, PHDASTATER3 pThisCC)
-{
-    const uint64_t u64WalClkCur       = ASMAtomicReadU64(&pThis->u64WalClk);
-    const uint64_t u64FrontAbsWalClk  = pThisCC->SinkFront.pStreamShared
-                                      ? hdaR3StreamPeriodGetAbsElapsedWalClk(&pThisCC->SinkFront.pStreamShared->State.Period)  : 0;
-# ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
-#  error "Implement me!"
-# endif
-    const uint64_t u64LineInAbsWalClk = pThisCC->SinkLineIn.pStreamShared
-                                      ? hdaR3StreamPeriodGetAbsElapsedWalClk(&pThisCC->SinkLineIn.pStreamShared->State.Period) : 0;
-# ifdef VBOX_WITH_HDA_MIC_IN
-    const uint64_t u64MicInAbsWalClk  = pThisCC->SinkMicIn.pStreamShared
-                                      ? hdaR3StreamPeriodGetAbsElapsedWalClk(&pThisCC->SinkMicIn.pStreamShared->State.Period)  : 0;
-# endif
-
-    uint64_t u64WalClkNew = RT_MAX(u64WalClkCur, u64FrontAbsWalClk);
-# ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
-#  error "Implement me!"
-# endif
-    u64WalClkNew          = RT_MAX(u64WalClkNew, u64LineInAbsWalClk);
-# ifdef VBOX_WITH_HDA_MIC_IN
-    u64WalClkNew          = RT_MAX(u64WalClkNew, u64MicInAbsWalClk);
-# endif
-
-    Log3Func(("%RU64 -> Front=%RU64, LineIn=%RU64 -> %RU64\n",
-              u64WalClkCur, u64FrontAbsWalClk, u64LineInAbsWalClk, u64WalClkNew));
-
-    return u64WalClkNew;
-}
-
-/**
- * Sets the actual WALCLK register to the specified wall clock value.
- * The specified wall clock value only will be set (unless fForce is set to true) if all
- * handled HDA streams have passed (in time) that value. This guarantees that the WALCLK
- * register stays in sync with all handled HDA streams.
- *
- * @return  true if the WALCLK register has been updated, false if not.
- * @param   pThis               The shared HDA device state.
- * @param   pThisCC             The ring-3 HDA device state.
- * @param   u64WalClk           Wall clock value to set WALCLK register to.
- * @param   fForce              Whether to force setting the wall clock value or not.
- */
-bool hdaR3WalClkSet(PHDASTATE pThis, PHDASTATER3 pThisCC, uint64_t u64WalClk, bool fForce)
-{
-    const bool     fFrontPassed       = hdaR3StreamPeriodHasPassedAbsWalClk( hdaR3SinkToStreamPeriod(&pThisCC->SinkFront), u64WalClk);
-    const uint64_t u64FrontAbsWalClk  = hdaR3StreamPeriodGetAbsElapsedWalClk(hdaR3SinkToStreamPeriod(&pThisCC->SinkFront));
-# ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
-#  error "Implement me!"
-# endif
-
-    const bool     fLineInPassed      = hdaR3StreamPeriodHasPassedAbsWalClk (hdaR3SinkToStreamPeriod(&pThisCC->SinkLineIn), u64WalClk);
-    const uint64_t u64LineInAbsWalClk = hdaR3StreamPeriodGetAbsElapsedWalClk(hdaR3SinkToStreamPeriod(&pThisCC->SinkLineIn));
-# ifdef VBOX_WITH_HDA_MIC_IN
-    const bool     fMicInPassed       = hdaR3StreamPeriodHasPassedAbsWalClk (hdaR3SinkToStreamPeriod(&pThisCC->SinkMicIn),  u64WalClk);
-    const uint64_t u64MicInAbsWalClk  = hdaR3StreamPeriodGetAbsElapsedWalClk(hdaR3SinkToStreamPeriod(&pThisCC->SinkMicIn));
-# endif
-
-# ifdef VBOX_STRICT
-    const uint64_t u64WalClkCur       = ASMAtomicReadU64(&pThis->u64WalClk);
-# endif
-
-    /* Only drive the WALCLK register forward if all (active) stream periods have passed
-     * the specified point in time given by u64WalClk. */
-    if (  (   fFrontPassed
-# ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
-#  error "Implement me!"
-# endif
-           && fLineInPassed
-# ifdef VBOX_WITH_HDA_MIC_IN
-           && fMicInPassed
-# endif
-          )
-       || fForce)
-    {
-        if (!fForce)
-        {
-            /* Get the maximum value of all periods we need to handle.
-             * Not the most elegant solution, but works for now ... */
-            u64WalClk = RT_MAX(u64WalClk, u64FrontAbsWalClk);
-# ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
-#  error "Implement me!"
-# endif
-            u64WalClk = RT_MAX(u64WalClk, u64LineInAbsWalClk);
-# ifdef VBOX_WITH_HDA_MIC_IN
-            u64WalClk = RT_MAX(u64WalClk, u64MicInAbsWalClk);
-# endif
-
-# ifdef VBOX_STRICT
-            AssertMsg(u64WalClk >= u64WalClkCur,
-                      ("Setting WALCLK to a value going backwards does not make any sense (old %RU64 vs. new %RU64)\n",
-                       u64WalClkCur, u64WalClk));
-            if (u64WalClk == u64WalClkCur)     /* Setting a stale value? */
-            {
-                if (pThis->u8WalClkStaleCnt++ > 3)
-                    AssertMsgFailed(("Setting WALCLK to a stale value (%RU64) too often isn't a good idea really. "
-                                     "Good luck with stuck audio stuff.\n", u64WalClk));
-            }
-            else
-                pThis->u8WalClkStaleCnt = 0;
-# endif
-        }
-
-        /* Set the new WALCLK value. */
-        ASMAtomicWriteU64(&pThis->u64WalClk, u64WalClk);
-    }
-
-    const uint64_t u64WalClkNew = hdaWalClkGetCurrent(pThis);
-
-    Log3Func(("Cur: %RU64, New: %RU64 (force %RTbool) -> %RU64 %s\n",
-              u64WalClkCur, u64WalClk, fForce,
-              u64WalClkNew, u64WalClkNew == u64WalClk ? "[OK]" : "[DELAYED]"));
-
-    return (u64WalClkNew == u64WalClk);
-}
-
 /**
  * Returns the default (mixer) sink from a given SD#.
@@ -299,5 +146,4 @@
     return NULL;
 }
-
 #endif /* IN_RING3 */
 
Index: trunk/src/VBox/Devices/Audio/DevHDACommon.h
===================================================================
--- trunk/src/VBox/Devices/Audio/DevHDACommon.h	(revision 88168)
+++ trunk/src/VBox/Devices/Audio/DevHDACommon.h	(revision 88170)
@@ -595,14 +595,4 @@
 /** @} */
 
-/** @name Wall clock (WALCLK) functions.
- * @{
- */
-uint64_t      hdaWalClkGetCurrent(PHDASTATE pThis);
-#ifdef IN_RING3
-uint64_t      hdaR3WalClkGetMax(PHDASTATE pThis, PHDASTATER3 pThisCC);
-bool          hdaR3WalClkSet(PHDASTATE pThis, PHDASTATER3 pThisCC, uint64_t u64WalClk, bool fForce);
-#endif
-/** @} */
-
 /** @name Register functions.
  * @{
Index: trunk/src/VBox/Devices/Audio/HDACodec.h
===================================================================
--- trunk/src/VBox/Devices/Audio/HDACodec.h	(revision 88168)
+++ trunk/src/VBox/Devices/Audio/HDACodec.h	(revision 88170)
@@ -985,4 +985,9 @@
 /** @name DevHDA saved state versions
  * @{ */
+/** The current staved state version. */
+#define HDA_SAVED_STATE_VERSION  HDA_SAVED_STATE_WITHOUT_PERIOD
+
+/** Removed period and redefined wall clock. */
+#define HDA_SAVED_STATE_WITHOUT_PERIOD 8
 /** Added (Controller):              Current wall clock value (this independent from WALCLK register value).
   * Added (Controller):              Current IRQ level.
@@ -992,5 +997,5 @@
   * Added (Current BDLE per stream): Struct g_aSSMBDLEDescFields7.
   * Added (Current BDLE per stream): Struct g_aSSMBDLEStateFields7. */
-#define HDA_SAVED_STATE_VERSION   7
+#define HDA_SAVED_STATE_VERSION_7 7
 /** Saves the current BDLE state.
  * @since 5.0.14 (r104839) */
Index: trunk/src/VBox/Devices/Audio/HDAStream.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/HDAStream.cpp	(revision 88168)
+++ trunk/src/VBox/Devices/Audio/HDAStream.cpp	(revision 88170)
@@ -87,7 +87,4 @@
 #endif
 
-    rc = hdaR3StreamPeriodCreate(&pStreamShared->State.Period);
-    AssertRCReturn(rc, rc);
-
 #ifdef DEBUG
     rc = RTCritSectInit(&pStreamR3->Dbg.CritSect);
@@ -195,6 +192,4 @@
         pStreamR3->State.pCircBuf = NULL;
     }
-
-    hdaR3StreamPeriodDestroy(&pStreamShared->State.Period);
 
 #ifdef DEBUG
@@ -852,7 +847,4 @@
     pStreamR3->State.offRead  = 0;
 
-    /* Reset the stream's period. */
-    hdaR3StreamPeriodReset(&pStreamShared->State.Period);
-
 #ifdef DEBUG
     pStreamR3->Dbg.cReadsTotal      = 0;
@@ -936,4 +928,6 @@
     if (RT_SUCCESS(rc))
     {
+        if (fEnable)
+            pStreamShared->State.tsTransferLast = 0; /* Make sure it's not stale and messes up WALCLK calculations. */
         pStreamShared->State.fRunning = fEnable;
     }
@@ -1054,4 +1048,17 @@
         return (uint32_t)RTCircBufFree(pStreamR3->State.pCircBuf);
     return 0;
+}
+
+/**
+ * Converts frame count to wall clock ticks (WALCLK).
+ *
+ * @returns Wall clock ticks.
+ * @param   pStream     The stream to do the conversion for.
+ * @param   cFrames     Number of audio frames.
+ */
+DECLINLINE(uint64_t) hdaR3StreamFramesToWalClk(PHDASTREAM pStreamShared, uint32_t cFrames)
+{
+    const uint32_t uHz = RT_MAX(pStreamShared->State.Cfg.Props.uHz, 1 /* prevent div/0 */);
+    return ASMMultU32ByU32DivByU32(cFrames, 24000000 /* 24 MHz wall clock (WALCLK). */ , uHz);
 }
 
@@ -1151,5 +1158,5 @@
  * @param   pszFunction     The function name (for logging).
  */
-DECLINLINE(bool) hdaR3StreamDoDmaPrologue(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared, uint8_t uSD,
+DECLINLINE(bool) hdaR3StreamDoDmaPrologue(PHDASTATE pThis, PHDASTREAM pStreamShared, uint8_t uSD,
                                           uint64_t tsNowNs, const char *pszFunction)
 {
@@ -1199,5 +1206,4 @@
     Log3(("%s: [SD%RU8] tsDeltaNs=%'RU64 ns\n", pszFunction, uSD, tsNowNs - pStreamShared->State.tsLastTransferNs));
     pStreamShared->State.tsLastTransferNs = tsNowNs;
-    pStreamShared->State.tsTransferLast   = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer);
 
     /*
@@ -1217,52 +1223,34 @@
  * Common do-DMA epilogue.
  *
- * @param   pThis           The shared HDA device state.
- * @param   pThisCC         The ring-3 HDA device state.
- * @param   pStreamShared   HDA stream to update (shared).
- * @param   cbProcessed     The number of bytes processed.
- */
-DECLINLINE(void) hdaR3StreamDoDmaEpilogue(PHDASTATE pThis, PHDASTATER3 pThisCC, PHDASTREAM pStreamShared, uint32_t cbProcessed)
-{
-    /*
-     * Clear the (pointless) FIFORDY bit again.
-     */
-    HDA_STREAM_REG(pThis, STS, pStreamShared->u8SD) &= ~HDA_SDSTS_FIFORDY;
-
-    /*
-     * Try updating the wall clock.
-     *
-     * Note 1) Only certain guests (like Linux' snd_hda_intel) rely on the WALCLK register
-     *         in order to determine the correct timing of the sound device. Other guests
-     *         like Windows 7 + 10 (or even more exotic ones like Haiku) will completely
-     *         ignore this.
-     *
-     * Note 2) When updating the WALCLK register too often / early (or even in a non-monotonic
-     *         fashion) this *will* upset guest device drivers and will completely fuck up the
-     *         sound output. Running VLC on the guest will tell!
-     */
-    uint32_t const cFramesProcessed = PDMAudioPropsBytesToFrames(&pStreamShared->State.Cfg.Props, cbProcessed);
-    /** @todo this needs to go, but we need it for hdaR3WalClkGetMax below. */
-    hdaR3StreamPeriodInc(&pStreamShared->State.Period,
-                         RT_MIN(cFramesProcessed, hdaR3StreamPeriodGetRemainingFrames(&pStreamShared->State.Period)));
-
-    uint64_t const cWallTicks = hdaR3StreamPeriodFramesToWalClk(&pStreamShared->State.Period, cFramesProcessed);
-    uint64_t const uWallNew   = hdaWalClkGetCurrent(pThis) + cWallTicks;
-    uint64_t const uWallMax   = hdaR3WalClkGetMax(pThis, pThisCC);
-    bool const     fWalClkSet = hdaR3WalClkSet(pThis, pThisCC, RT_MIN(uWallNew, uWallMax), false /* fForce */);
-    RT_NOREF(fWalClkSet);
-}
-
-/**
- * Completes a BDLE at the end of a DMA loop iteration, if possible.
- *
  * @param   pDevIns         The device instance.
  * @param   pThis           The shared HDA device state.
- * @param   pThisCC         The ring-3 HDA device state.
  * @param   pStreamShared   HDA stream to update (shared).
- * @param   pStreamR3       HDA stream to update (ring-3).
+ */
+DECLINLINE(void) hdaR3StreamDoDmaEpilogue(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared)
+{
+    /*
+     * Clear the (pointless) FIFORDY bit again.
+     */
+    HDA_STREAM_REG(pThis, STS, pStreamShared->u8SD) &= ~HDA_SDSTS_FIFORDY;
+
+    /*
+     * We must update this in the epilogue rather than in the prologue
+     * as it is used for WALCLK calculation and we must make sure the
+     * guest doesn't think we've processed the current period till we
+     * actually have.
+     */
+    pStreamShared->State.tsTransferLast = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer);
+}
+
+/**
+ * Completes a BDLE at the end of a DMA loop iteration, if possible.
+ *
+ * @param   pDevIns         The device instance.
+ * @param   pThis           The shared HDA device state.
+ * @param   pStreamShared   HDA stream to update (shared).
  * @param   pszFunction     The function name (for logging).
  */
-DECLINLINE(void) hdaR3StreamDoDmaMaybeCompleteBuffer(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC,
-                                                     PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, const char *pszFunction)
+DECLINLINE(void) hdaR3StreamDoDmaMaybeCompleteBuffer(PPDMDEVINS pDevIns, PHDASTATE pThis,
+                                                     PHDASTREAM pStreamShared, const char *pszFunction)
 {
     RT_NOREF(pszFunction);
@@ -1277,14 +1265,4 @@
               pStreamShared->State.aBdl[pStreamShared->State.idxCurBdle].cb,
               pStreamShared->State.aBdl[pStreamShared->State.idxCurBdle].fFlags));
-
-        /* Make sure to also update the wall clock when a BDLE is complete.
-         * Needed for Windows 10 guests. */
-        /** @todo there is a rounding error here.   */
-        hdaR3WalClkSet(pThis, pThisCC,
-                         hdaWalClkGetCurrent(pThis)
-                       + hdaR3StreamPeriodFramesToWalClk(&pStreamShared->State.Period,
-                                                           hdaR3StreamDmaBufGetSize(pStreamShared)
-                                                         / pStreamR3->State.Mapping.cbGuestFrame),
-                       false /* fForce */);
 
         /*
@@ -1338,5 +1316,4 @@
  * @param   pDevIns             The device instance.
  * @param   pThis               The shared HDA device state.
- * @param   pThisCC             The ring-3 HDA device state.
  * @param   pStreamShared       HDA stream to update (shared).
  * @param   pStreamR3           HDA stream to update (ring-3).
@@ -1354,5 +1331,5 @@
  * @remarks Caller owns the stream lock.
  */
-static void hdaR3StreamDoDmaInput(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, PHDASTREAM pStreamShared,
+static void hdaR3StreamDoDmaInput(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared,
                                   PHDASTREAMR3 pStreamR3, uint32_t cbToConsume, bool fWriteSilence, uint64_t tsNowNs)
 {
@@ -1363,5 +1340,5 @@
      * Common prologue.
      */
-    if (hdaR3StreamDoDmaPrologue(pDevIns, pThis, pStreamShared, uSD, tsNowNs, "hdaR3StreamDoDmaInput"))
+    if (hdaR3StreamDoDmaPrologue(pThis, pStreamShared, uSD, tsNowNs, "hdaR3StreamDoDmaInput"))
     { /* likely */ }
     else
@@ -1536,5 +1513,5 @@
          * Complete the buffer if necessary (common with the output DMA code).
          */
-        hdaR3StreamDoDmaMaybeCompleteBuffer(pDevIns, pThis, pThisCC, pStreamShared, pStreamR3, "hdaR3StreamDoDmaInput");
+        hdaR3StreamDoDmaMaybeCompleteBuffer(pDevIns, pThis, pStreamShared, "hdaR3StreamDoDmaInput");
     }
 
@@ -1545,5 +1522,5 @@
      * Common epilogue.
      */
-    hdaR3StreamDoDmaEpilogue(pThis, pThisCC, pStreamShared, cbToConsume);
+    hdaR3StreamDoDmaEpilogue(pDevIns, pThis, pStreamShared);
 
     /*
@@ -1638,5 +1615,4 @@
  * @param   pDevIns             The device instance.
  * @param   pThis               The shared HDA device state.
- * @param   pThisCC             The ring-3 HDA device state.
  * @param   pStreamShared       HDA stream to update (shared).
  * @param   pStreamR3           HDA stream to update (ring-3).
@@ -1649,5 +1625,5 @@
  * @remarks Caller owns the stream lock.
  */
-static void hdaR3StreamDoDmaOutput(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, PHDASTREAM pStreamShared,
+static void hdaR3StreamDoDmaOutput(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared,
                                    PHDASTREAMR3 pStreamR3, uint32_t cbToProduce, uint64_t tsNowNs)
 {
@@ -1658,5 +1634,5 @@
      * Common prologue.
      */
-    if (hdaR3StreamDoDmaPrologue(pDevIns, pThis, pStreamShared, uSD, tsNowNs, "hdaR3StreamDoDmaOutput"))
+    if (hdaR3StreamDoDmaPrologue(pThis, pStreamShared, uSD, tsNowNs, "hdaR3StreamDoDmaOutput"))
     { /* likely */ }
     else
@@ -1821,5 +1797,5 @@
          * Complete the buffer if necessary (common with the output DMA code).
          */
-        hdaR3StreamDoDmaMaybeCompleteBuffer(pDevIns, pThis, pThisCC, pStreamShared, pStreamR3, "hdaR3StreamDoDmaOutput");
+        hdaR3StreamDoDmaMaybeCompleteBuffer(pDevIns, pThis, pStreamShared, "hdaR3StreamDoDmaOutput");
     }
 
@@ -1830,5 +1806,5 @@
      * Common epilogue.
      */
-    hdaR3StreamDoDmaEpilogue(pThis, pThisCC, pStreamShared, cbToProduce);
+    hdaR3StreamDoDmaEpilogue(pDevIns, pThis, pStreamShared);
 
     /*
@@ -1991,4 +1967,5 @@
                        PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, bool fInTimer)
 {
+    RT_NOREF(pThisCC);
     int rc2;
 
@@ -2081,5 +2058,5 @@
 
             uint64_t const offWriteBefore = pStreamR3->State.offWrite;
-            hdaR3StreamDoDmaOutput(pDevIns, pThis, pThisCC, pStreamShared, pStreamR3, RT_MIN(cbStreamFree, cbPeriod), tsNowNs);
+            hdaR3StreamDoDmaOutput(pDevIns, pThis, pStreamShared, pStreamR3, RT_MIN(cbStreamFree, cbPeriod), tsNowNs);
 
 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
@@ -2279,5 +2256,5 @@
 # endif
 
-                hdaR3StreamDoDmaInput(pDevIns, pThis, pThisCC, pStreamShared, pStreamR3,
+                hdaR3StreamDoDmaInput(pDevIns, pThis, pStreamShared, pStreamR3,
                                       RT_MIN(cbStreamUsed, cbPeriod), fWriteSilence, tsNowNs);
 
Index: trunk/src/VBox/Devices/Audio/HDAStream.h
===================================================================
--- trunk/src/VBox/Devices/Audio/HDAStream.h	(revision 88168)
+++ trunk/src/VBox/Devices/Audio/HDAStream.h	(revision 88170)
@@ -24,5 +24,4 @@
 #include "DevHDACommon.h"
 #include "HDAStreamMap.h"
-#include "HDAStreamPeriod.h"
 
 
@@ -134,6 +133,7 @@
     uint32_t                cbInputPreBuffer;
     uint32_t                u32Padding2;
-    /** Timestamp (absolute, in timer ticks) of the last DMA data transfer. */
-    uint64_t                tsTransferLast;
+    /** Timestamp (absolute, in timer ticks) of the last DMA data transfer.
+     * @note This is used for wall clock (WALCLK) calculations.  */
+    uint64_t volatile       tsTransferLast;
     /** Timestamp (absolute, in timer ticks) of the next DMA data transfer.
      *  Next for determining the next scheduling window.
@@ -145,6 +145,4 @@
     /** The size of an average transfer. */
     uint32_t                cbAvgTransfer;
-    /** The stream's period. Need for timing. */
-    HDASTREAMPERIOD         Period;
     /** The stream's current host side configuration.
      * This should match the SDnFMT in all respects but maybe the channel count as
@@ -164,6 +162,4 @@
     /** The start time for the playback (on the timer clock). */
     uint64_t                tsStart;
-
-    uint64_t                au64Padding[3];
 
     /** @name DMA engine
@@ -217,4 +213,5 @@
 } HDASTREAMSTATE;
 AssertCompileSizeAlignment(HDASTREAMSTATE, 8);
+AssertCompileMemberAlignment(HDASTREAMSTATE, aBdl, 8);
 AssertCompileMemberAlignment(HDASTREAMSTATE, aBdl, 16);
 AssertCompileMemberAlignment(HDASTREAMSTATE, aSchedule, 16);
@@ -273,5 +270,5 @@
 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
     /** Pad the structure size to a 64 byte alignment. */
-    uint64_t                    au64Padding1[2];
+    uint64_t                    au64Padding1[4];
     /** Critical section for serialize access to the stream state between the async
      * I/O thread and (basically) the guest. */
Index: trunk/src/VBox/Devices/Audio/HDAStreamPeriod.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/HDAStreamPeriod.cpp	(revision 88168)
+++ 	(revision )
@@ -1,284 +1,0 @@
-/* $Id$ */
-/** @file
- * HDAStreamPeriod.cpp - Stream period functions for HD Audio.
- *
- * Utility functions for handling HDA audio stream periods.  Stream period
- * handling is needed in order to keep track of a stream's timing
- * and processed audio data.
- *
- * As the HDA device only has one bit clock (WALCLK) but audio streams can be
- * processed at certain points in time, these functions can be used to estimate
- * and schedule the wall clock (WALCLK) for all streams accordingly.
- */
-
-/*
- * Copyright (C) 2017-2020 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-
-/*********************************************************************************************************************************
-*   Header Files                                                                                                                 *
-*********************************************************************************************************************************/
-#define LOG_GROUP LOG_GROUP_DEV_HDA
-#include <VBox/log.h>
-
-#include <iprt/asm-math.h> /* For ASMMultU64ByU32DivByU32(). */
-
-#include <VBox/vmm/pdmdev.h>
-#include <VBox/vmm/pdmaudioifs.h>
-#include <VBox/vmm/pdmaudioinline.h>
-
-#include "DrvAudio.h"
-#include "HDAStreamPeriod.h"
-
-
-#ifdef IN_RING3 /* entire file currently */
-
-/**
- * Creates a stream period.
- *
- * @return  IPRT status code.
- * @param   pPeriod             Stream period to initialize.
- */
-int hdaR3StreamPeriodCreate(PHDASTREAMPERIOD pPeriod)
-{
-    Assert(!(pPeriod->fStatus & HDASTREAMPERIOD_F_VALID));
-
-    pPeriod->fStatus = HDASTREAMPERIOD_F_VALID;
-
-    return VINF_SUCCESS;
-}
-
-/**
- * Destroys a formerly created stream period.
- *
- * @param   pPeriod             Stream period to destroy.
- */
-void hdaR3StreamPeriodDestroy(PHDASTREAMPERIOD pPeriod)
-{
-    if (pPeriod->fStatus & HDASTREAMPERIOD_F_VALID)
-        pPeriod->fStatus = HDASTREAMPERIOD_F_NONE;
-}
-
-/**
- * Initializes a given stream period with needed parameters.
- *
- * @return  VBox status code.
- * @param   pPeriod             Stream period to (re-)initialize. Must be created with hdaR3StreamPeriodCreate() first.
- * @param   u8SD                Stream descriptor (serial data #) number to assign this stream period to.
- * @param   u16LVI              The HDA stream's LVI value to use for the period calculation.
- * @param   u32CBL              The HDA stream's CBL value to use for the period calculation.
- * @param   pStreamCfg          Audio stream configuration to use for this period.
- */
-int hdaR3StreamPeriodInit(PHDASTREAMPERIOD pPeriod,
-                          uint8_t u8SD, uint16_t u16LVI, uint32_t u32CBL, PPDMAUDIOSTREAMCFG pStreamCfg)
-{
-    if (   !u16LVI
-        || !u32CBL
-        || !DrvAudioHlpPcmPropsAreValid(&pStreamCfg->Props))
-    {
-        return VERR_INVALID_PARAMETER;
-    }
-
-    /*
-     * Linux guests (at least Ubuntu):
-     * 17632 bytes (CBL) / 4 (frame size) = 4408 frames / 4 (LVI) = 1102 frames per period
-     *
-     * Windows guests (Win10 AU):
-     * 3584  bytes (CBL) / 4 (frame size) = 896 frames / 2 (LVI)  = 448 frames per period
-     */
-    unsigned cTotalPeriods = u16LVI + 1;
-
-    if (cTotalPeriods <= 1)
-        cTotalPeriods = 2; /* At least two periods *must* be present (LVI >= 1). */
-
-    uint32_t cFramesToTransfer =
-        (u32CBL / (pStreamCfg->Props.cbSample * pStreamCfg->Props.cChannels /* Frame size */)) / cTotalPeriods;
-
-    pPeriod->u8SD               = u8SD;
-    pPeriod->u64StartWalClk     = 0;
-    pPeriod->u32Hz              = pStreamCfg->Props.uHz;
-    pPeriod->u64DurationWalClk  = hdaR3StreamPeriodFramesToWalClk(pPeriod, cFramesToTransfer);
-    pPeriod->u64ElapsedWalClk   = 0;
-    pPeriod->i64DelayWalClk     = 0;
-    pPeriod->cFramesToTransfer  = cFramesToTransfer;
-    pPeriod->cFramesTransferred = 0;
-
-    Log3Func(("[SD%RU8] %RU64 long, Hz=%RU32, CBL=%RU32, LVI=%RU16 -> %u periods, %RU32 frames each\n",
-              pPeriod->u8SD, pPeriod->u64DurationWalClk, pPeriod->u32Hz, u32CBL, u16LVI,
-              cTotalPeriods, pPeriod->cFramesToTransfer));
-
-    return VINF_SUCCESS;
-}
-
-/**
- * Resets a stream period to its initial state.
- *
- * @param   pPeriod             Stream period to reset.
- */
-void hdaR3StreamPeriodReset(PHDASTREAMPERIOD pPeriod)
-{
-    Log3Func(("[SD%RU8]\n", pPeriod->u8SD));
-
-    pPeriod->fStatus          &= ~HDASTREAMPERIOD_F_ACTIVE;
-    pPeriod->u64StartWalClk    = 0;
-    pPeriod->u64ElapsedWalClk  = 0;
-    pPeriod->cFramesTransferred = 0;
-# ifdef LOG_ENABLED
-    pPeriod->Dbg.tsStartNs     = 0;
-# endif
-}
-
-/**
- * Begins a new period life span of a given period.
- *
- * @return  IPRT status code.
- * @param   pPeriod             Stream period to begin new life span for.
- * @param   u64WalClk           Wall clock (WALCLK) value to set for the period's starting point.
- */
-int hdaR3StreamPeriodBegin(PHDASTREAMPERIOD pPeriod, uint64_t u64WalClk)
-{
-    Assert(!(pPeriod->fStatus & HDASTREAMPERIOD_F_ACTIVE)); /* No nested calls. */
-
-    pPeriod->fStatus          |= HDASTREAMPERIOD_F_ACTIVE;
-    pPeriod->u64StartWalClk    = u64WalClk;
-    pPeriod->u64ElapsedWalClk  = 0;
-    pPeriod->cFramesTransferred = 0;
-# ifdef LOG_ENABLED
-    pPeriod->Dbg.tsStartNs     = RTTimeNanoTS();
-# endif
-
-    Log3Func(("[SD%RU8] Starting @ %RU64 (%RU64 long)\n", pPeriod->u8SD, pPeriod->u64StartWalClk, pPeriod->u64DurationWalClk));
-    return VINF_SUCCESS;
-}
-
-/**
- * Resumes a formerly paused period.
- *
- * @param   pPeriod             Stream period to resume.
- */
-void hdaR3StreamPeriodResume(PHDASTREAMPERIOD pPeriod)
-{
-    AssertMsg(!(pPeriod->fStatus & HDASTREAMPERIOD_F_ACTIVE), ("Period %p already in active state\n", pPeriod));
-
-    pPeriod->fStatus |= HDASTREAMPERIOD_F_ACTIVE;
-
-    Log3Func(("[SD%RU8]\n", pPeriod->u8SD));
-}
-
-/**
- * Returns the wall clock (WALCLK) value for a given amount of stream period audio frames.
- *
- * @return  Calculated wall clock value.
- * @param   pPeriod     Stream period to calculate wall clock value for.
- * @param   cFrames     Number of audio frames to calculate wall clock value for.
- *
- * @remark  Calculation depends on the given stream period and assumes a 24 MHz wall clock counter (WALCLK).
- */
-uint64_t hdaR3StreamPeriodFramesToWalClk(PHDASTREAMPERIOD pPeriod, uint32_t cFrames)
-{
-    /* Prevent division by zero. */
-    const uint32_t uHz = pPeriod->u32Hz ? pPeriod->u32Hz : 1;
-
-    /* 24 MHz wall clock (WALCLK): 42ns resolution. */
-    return ASMMultU32ByU32DivByU32(cFrames, 24000000, uHz);
-}
-
-/**
- * Returns the absolute wall clock (WALCLK) value for the already elapsed time of
- * a given stream period.
- *
- * @return  Absolute elapsed time as wall clock (WALCLK) value.
- * @param   pPeriod             Stream period to use.
- */
-uint64_t hdaR3StreamPeriodGetAbsElapsedWalClk(PHDASTREAMPERIOD pPeriod)
-{
-    return pPeriod->u64StartWalClk
-         + pPeriod->u64ElapsedWalClk
-         + pPeriod->i64DelayWalClk;
-}
-
-/**
- * Returns the absolute wall clock (WALCLK) value for the calculated end time of
- * a given stream period.
- *
- * @return  Absolute end time as wall clock (WALCLK) value.
- * @param   pPeriod             Stream period to use.
- */
-uint64_t hdaR3StreamPeriodGetAbsEndWalClk(PHDASTREAMPERIOD pPeriod)
-{
-    return pPeriod->u64StartWalClk + pPeriod->u64DurationWalClk;
-}
-
-/**
- * Returns the remaining audio frames to process for a given stream period.
- *
- * @return  Number of remaining audio frames to process. 0 if all were processed.
- * @param   pPeriod             Stream period to return value for.
- */
-uint32_t hdaR3StreamPeriodGetRemainingFrames(PHDASTREAMPERIOD pPeriod)
-{
-    Assert(pPeriod->cFramesToTransfer >= pPeriod->cFramesTransferred);
-    return pPeriod->cFramesToTransfer - pPeriod->cFramesTransferred;
-}
-
-/**
- * Tells whether a given stream period has elapsed (time-wise) or not.
- *
- * @return  true if the stream period has elapsed, false if not.
- * @param   pPeriod             Stream period to get status for.
- */
-bool hdaR3StreamPeriodHasElapsed(PHDASTREAMPERIOD pPeriod)
-{
-    return (pPeriod->u64ElapsedWalClk >= pPeriod->u64DurationWalClk);
-}
-
-/**
- * Tells whether a given stream period has passed the given absolute wall clock (WALCLK)
- * time or not
- *
- * @return  true if the stream period has passed the given time, false if not.
- * @param   pPeriod             Stream period to get status for.
- * @param   u64WalClk           Absolute wall clock (WALCLK) time to check for.
- */
-bool hdaR3StreamPeriodHasPassedAbsWalClk(PHDASTREAMPERIOD pPeriod, uint64_t u64WalClk)
-{
-    /* Period not in use? */
-    if (!(pPeriod->fStatus & HDASTREAMPERIOD_F_ACTIVE))
-        return true; /* ... implies that it has passed. */
-
-    if (hdaR3StreamPeriodHasElapsed(pPeriod))
-        return true; /* Period already has elapsed. */
-
-    return (pPeriod->u64StartWalClk + pPeriod->u64ElapsedWalClk) >= u64WalClk;
-}
-
-/**
- * Adds an amount of (processed) audio frames to a given stream period.
- *
- * @return  IPRT status code.
- * @param   pPeriod             Stream period to add audio frames to.
- * @param   framesInc           Audio frames to add.
- */
-void hdaR3StreamPeriodInc(PHDASTREAMPERIOD pPeriod, uint32_t framesInc)
-{
-    pPeriod->cFramesTransferred += framesInc;
-    Assert(pPeriod->cFramesTransferred <= pPeriod->cFramesToTransfer);
-
-    pPeriod->u64ElapsedWalClk   = hdaR3StreamPeriodFramesToWalClk(pPeriod, pPeriod->cFramesTransferred);
-    Assert(pPeriod->u64ElapsedWalClk <= pPeriod->u64DurationWalClk);
-
-    Log3Func(("[SD%RU8] cbTransferred=%RU32, u64ElapsedWalClk=%RU64\n",
-              pPeriod->u8SD, pPeriod->cFramesTransferred, pPeriod->u64ElapsedWalClk));
-}
-
-#endif /* IN_RING3 */
-
Index: trunk/src/VBox/Devices/Audio/HDAStreamPeriod.h
===================================================================
--- trunk/src/VBox/Devices/Audio/HDAStreamPeriod.h	(revision 88168)
+++ 	(revision )
@@ -1,103 +1,0 @@
-/* $Id$ */
-/** @file
- * HDAStreamPeriod.h - Stream period functions for HD Audio.
- */
-
-/*
- * Copyright (C) 2017-2020 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#ifndef VBOX_INCLUDED_SRC_Audio_HDAStreamPeriod_h
-#define VBOX_INCLUDED_SRC_Audio_HDAStreamPeriod_h
-#ifndef RT_WITHOUT_PRAGMA_ONCE
-# pragma once
-#endif
-
-#include <iprt/critsect.h>
-#ifdef DEBUG
-# include <iprt/time.h>
-#endif
-#include <VBox/log.h> /* LOG_ENABLED */
-
-
-#ifdef LOG_ENABLED
-/**
- * Debug stuff for a HDA stream's period.
- */
-typedef struct HDASTREAMPERIODDEBUG
-{
-    /** Host start time (in ns) of the period. */
-    uint64_t                tsStartNs;
-} HDASTREAMPERIODDEBUG;
-#endif
-
-/** No flags set. */
-#define HDASTREAMPERIOD_F_NONE      0
-/** The stream period has been initialized and is in a valid state. */
-#define HDASTREAMPERIOD_F_VALID     RT_BIT(0)
-/** The stream period is active. */
-#define HDASTREAMPERIOD_F_ACTIVE    RT_BIT(1)
-
-/**
- * HDA stream's time period.
- *
- * This is needed in order to keep track of stream timing and interrupt delivery.
- */
-typedef struct HDASTREAMPERIOD
-{
-    /** Associated HDA stream descriptor (SD) number. */
-    uint8_t                 u8SD;
-    /** The period's status flags. */
-    uint8_t                 fStatus;
-    uint8_t                 abPadding[2];
-    /** Hertz (Hz) rate this period runs with. */
-    uint32_t                u32Hz;
-    /** Period start time (in wall clock counts). */
-    uint64_t                u64StartWalClk;
-    /** Period duration (in wall clock counts). */
-    uint64_t                u64DurationWalClk;
-    /** The period's (relative) elapsed time (in wall clock counts). */
-    uint64_t                u64ElapsedWalClk;
-    /** Delay (in wall clock counts) for tweaking the period timing. Optional. */
-    int64_t                 i64DelayWalClk;
-    /** Number of audio frames to transfer for this period. */
-    uint32_t                cFramesToTransfer;
-    /** Number of audio frames already transfered. */
-    uint32_t                cFramesTransferred;
-#ifdef LOG_ENABLED
-    /** Debugging state. */
-    HDASTREAMPERIODDEBUG    Dbg;
-#else
-    uint64_t                uPlaceholder;
-#endif
-} HDASTREAMPERIOD;
-AssertCompileSizeAlignment(HDASTREAMPERIOD, 8);
-/** Pointer to a HDA stream's time period keeper. */
-typedef HDASTREAMPERIOD *PHDASTREAMPERIOD;
-
-#ifdef IN_RING3
-int      hdaR3StreamPeriodCreate(PHDASTREAMPERIOD pPeriod);
-void     hdaR3StreamPeriodDestroy(PHDASTREAMPERIOD pPeriod);
-int      hdaR3StreamPeriodInit(PHDASTREAMPERIOD pPeriod, uint8_t u8SD, uint16_t u16LVI, uint32_t u32CBL, PPDMAUDIOSTREAMCFG pStreamCfg);
-void     hdaR3StreamPeriodReset(PHDASTREAMPERIOD pPeriod);
-int      hdaR3StreamPeriodBegin(PHDASTREAMPERIOD pPeriod, uint64_t u64WalClk);
-void     hdaR3StreamPeriodResume(PHDASTREAMPERIOD pPeriod);
-uint64_t hdaR3StreamPeriodFramesToWalClk(PHDASTREAMPERIOD pPeriod, uint32_t uFrames);
-uint64_t hdaR3StreamPeriodGetAbsEndWalClk(PHDASTREAMPERIOD pPeriod);
-uint64_t hdaR3StreamPeriodGetAbsElapsedWalClk(PHDASTREAMPERIOD pPeriod);
-uint32_t hdaR3StreamPeriodGetRemainingFrames(PHDASTREAMPERIOD pPeriod);
-bool     hdaR3StreamPeriodHasElapsed(PHDASTREAMPERIOD pPeriod);
-bool     hdaR3StreamPeriodHasPassedAbsWalClk(PHDASTREAMPERIOD pPeriod, uint64_t u64WalClk);
-void     hdaR3StreamPeriodInc(PHDASTREAMPERIOD pPeriod, uint32_t framesInc);
-#endif /* IN_RING3 */
-
-#endif /* !VBOX_INCLUDED_SRC_Audio_HDAStreamPeriod_h */
-
Index: trunk/src/VBox/Devices/Makefile.kmk
===================================================================
--- trunk/src/VBox/Devices/Makefile.kmk	(revision 88168)
+++ trunk/src/VBox/Devices/Makefile.kmk	(revision 88170)
@@ -638,5 +638,4 @@
 	Audio/HDAStreamChannel.cpp \
 	Audio/HDAStreamMap.cpp \
-	Audio/HDAStreamPeriod.cpp \
 	Audio/AudioMixBuffer.cpp \
 	Audio/AudioMixer.cpp \
