Index: trunk/src/VBox/Devices/Audio/AudioMixer.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/AudioMixer.cpp	(revision 88884)
+++ trunk/src/VBox/Devices/Audio/AudioMixer.cpp	(revision 88887)
@@ -744,4 +744,9 @@
     }
 
+/** @todo r=bird: There almost serious issue here.  One stupid/buggy audio
+ *        driver chain will mess up the whole thing.  Either we or DrvAudio
+ *        need to take note of this and somehow gloss over it...  DevHDA with a
+ *        linux guest completely freezes up the audio in the guest if we fail
+ *        here. (Buggy VRDE code.) */
     PAUDMIXSTREAM pStream;
     if (   pSink->enmDir == AUDMIXSINKDIR_INPUT
@@ -2112,5 +2117,5 @@
             int rc = pConn->pfnStreamReInit(pConn, pStream);
             enmState = pConn->pfnStreamGetState(pConn, pStream);
-            LogFunc(("[%s] re-init returns %Rrc and %d.\n", pMixStream->pszName, rc, enmState));
+            LogFunc(("[%s] re-init returns %Rrc and %s.\n", pMixStream->pszName, rc, PDMAudioStreamStateGetName(enmState)));
 
             PAUDMIXSINK const pSink = pMixStream->pSink;
Index: trunk/src/VBox/Devices/Audio/DrvAudio.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 88884)
+++ trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 88887)
@@ -131,7 +131,7 @@
     uint32_t                cTriesReInit;
 
-    /** The backend status at the last play or capture call.
-     * This is used to detect state changes.  */
-    uint32_t                fLastBackendStatus;
+    /** The backend state at the last play or capture call.
+     * This is used to detect state changes (for what that is worth).  */
+    PDMHOSTAUDIOSTREAMSTATE enmLastBackendState;
 
     /** The pfnStreamInitAsync request handle. */
@@ -436,15 +436,17 @@
  * Wrapper around PDMIHOSTAUDIO::pfnStreamGetStatus and checks the result.
  *
- * @returns PDMAUDIOSTREAM_STS_XXX
+ * @returns A PDMHOSTAUDIOSTREAMSTATE value.
  * @param   pThis       Pointer to the DrvAudio instance data.
  * @param   pStreamEx   The stream to get the backend status for.
  */
-DECLINLINE(uint32_t) drvAudioStreamGetBackendStatus(PDRVAUDIO pThis, PDRVAUDIOSTREAM pStreamEx)
-{
-    uint32_t fBackendStatus = pThis->pHostDrvAudio
-                            ? pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pStreamEx->pBackend)
-                            : 0;
-    PDMAUDIOSTREAM_STS_ASSERT_VALID_BACKEND(fBackendStatus);
-    return fBackendStatus;
+DECLINLINE(PDMHOSTAUDIOSTREAMSTATE) drvAudioStreamGetBackendState(PDRVAUDIO pThis, PDRVAUDIOSTREAM pStreamEx)
+{
+    if (pThis->pHostDrvAudio)
+    {
+        PDMHOSTAUDIOSTREAMSTATE enmState = pThis->pHostDrvAudio->pfnStreamGetState(pThis->pHostDrvAudio, pStreamEx->pBackend);
+        Assert(enmState > PDMHOSTAUDIOSTREAMSTATE_INVALID && enmState < PDMHOSTAUDIOSTREAMSTATE_END);
+        return enmState;
+    }
+    return PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING;
 }
 
@@ -598,4 +600,8 @@
                         if (!(fStatus & PDMAUDIOSTREAM_STS_PENDING_DISABLE))
                         {
+                            /** @todo r=bird: We need to redo pre-buffering OR switch to
+                             *        DRVAUDIOPLAYSTATE_PREBUF_SWITCHING playback mode when disabling
+                             *        output streams.  The former is preferred if associated with
+                             *        reporting the stream as INACTIVE. */
                             rc2 = drvAudioStreamControlInternalBackend(pThis, pStreamEx, PDMAUDIOSTREAMCMD_ENABLE);
                             pszOperation = "enable";
@@ -1078,9 +1084,7 @@
 
         /*
-         * Tweak the last backend status to asserting in
-         * drvAudioStreamPlayProcessBackendStateChange().
+         * Update the last backend state.
          */
-        pStreamEx->fLastBackendStatus |=   drvAudioStreamGetBackendStatus(pThis, pStreamEx)
-                                         & PDMAUDIOSTREAM_STS_INITIALIZED;
+        pStreamEx->enmLastBackendState = drvAudioStreamGetBackendState(pThis, pStreamEx);
     }
     /*
@@ -1163,4 +1167,6 @@
     if (RT_SUCCESS(rc))
     {
+        pStreamEx->enmLastBackendState = drvAudioStreamGetBackendState(pThis, pStreamEx);
+
         AssertLogRelReturn(pStreamEx->pBackend->uMagic  == PDMAUDIOBACKENDSTREAM_MAGIC, VERR_INTERNAL_ERROR_3);
         AssertLogRelReturn(pStreamEx->pBackend->pStream == &pStreamEx->Core, VERR_INTERNAL_ERROR_3);
@@ -1170,7 +1176,4 @@
            several possible early return paths before it). */
         pStreamEx->fStatus |= PDMAUDIOSTREAM_STS_INITIALIZED;
-
-        pStreamEx->fLastBackendStatus = drvAudioStreamGetBackendStatus(pThis, pStreamEx);
-        PDMAUDIOSTREAM_STS_ASSERT_VALID(pStreamEx->fStatus);
     }
     else
@@ -1189,5 +1192,7 @@
     AssertStmt(rc != VINF_AUDIO_STREAM_ASYNC_INIT_NEEDED || pThis->pHostDrvAudio->pfnStreamInitAsync != NULL,
                pStreamEx->fNeedAsyncInit = false);
-    Assert(rc != VINF_AUDIO_STREAM_ASYNC_INIT_NEEDED || !(pStreamEx->fLastBackendStatus & PDMAUDIOSTREAM_STS_INITIALIZED));
+    AssertMsg(   rc != VINF_AUDIO_STREAM_ASYNC_INIT_NEEDED
+              || pStreamEx->enmLastBackendState == PDMHOSTAUDIOSTREAMSTATE_INITIALIZING,
+             ("rc=%Rrc %s\n", rc, PDMHostAudioStreamStateGetName(pStreamEx->enmLastBackendState)));
 
     /* Validate acquired configuration. */
@@ -1872,8 +1877,8 @@
         if (pStreamEx->cRefs > 0 && pStreamEx->cRefs < UINT32_MAX / 4)
         {
-            char szStatus[DRVAUDIO_STATUS_STR_MAX], szBackendStatus[DRVAUDIO_STATUS_STR_MAX];
+            char szStatus[DRVAUDIO_STATUS_STR_MAX];
             LogRel2(("Audio: Destroying stream '%s': cRefs=%u; status: %s; backend: %s; hReqInitAsync=%p\n",
                      pStreamEx->Core.szName, pStreamEx->cRefs, drvAudioStreamStatusToStr(szStatus, pStreamEx->fStatus),
-                     drvAudioStreamStatusToStr(szBackendStatus, drvAudioStreamGetBackendStatus(pThis, pStreamEx)),
+                     PDMHostAudioStreamStateGetName(drvAudioStreamGetBackendState(pThis, pStreamEx)),
                      pStreamEx->hReqInitAsync));
 
@@ -2198,18 +2203,20 @@
      *         finish initializing the stream, we'll update it about the stream state.
      */
-    int             rc             = VINF_SUCCESS;
-    uint32_t const  fBackendStatus = drvAudioStreamGetBackendStatus(pThis, pStreamEx); /* (checks pThis->pHostDrvAudio too) */
-    bool const      fDirEnabled    = pStreamEx->Core.enmDir == PDMAUDIODIR_IN ? pThis->In.fEnabled : pThis->Out.fEnabled;
-
-    char szStreamSts[DRVAUDIO_STATUS_STR_MAX], szBackendStreamSts[DRVAUDIO_STATUS_STR_MAX];
+    int                            rc              = VINF_SUCCESS;
+    bool const                     fDirEnabled     = pStreamEx->Core.enmDir == PDMAUDIODIR_IN
+                                                   ? pThis->In.fEnabled : pThis->Out.fEnabled;
+    PDMHOSTAUDIOSTREAMSTATE const  enmBackendState = drvAudioStreamGetBackendState(pThis, pStreamEx);
+                                                     /* ^^^ (checks pThis->pHostDrvAudio != NULL too) */
+
+    char szStreamSts[DRVAUDIO_STATUS_STR_MAX];
     LogRel2(("Audio: %s stream '%s' backend (%s is %s; status: %s; backend-status: %s)\n",
              PDMAudioStrmCmdGetName(enmStreamCmd), pStreamEx->Core.szName, PDMAudioDirGetName(pStreamEx->Core.enmDir),
              fDirEnabled ? "enabled" : "disabled",  drvAudioStreamStatusToStr(szStreamSts, pStreamEx->fStatus),
-             drvAudioStreamStatusToStr(szBackendStreamSts, fBackendStatus) ));
+             PDMHostAudioStreamStateGetName(enmBackendState) ));
 
     if (fDirEnabled)
     {
-        if (   (pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY)
-            && (fBackendStatus & PDMAUDIOSTREAM_STS_INITIALIZED))
+        if (   (pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY /* don't really need this check, do we? */)
+            && enmBackendState == PDMHOSTAUDIOSTREAMSTATE_OKAY)
         {
             /** @todo Backend will change to explicit methods here, so please don't simplify
@@ -2256,5 +2263,10 @@
             }
         }
-    }
+        else
+            LogFlowFunc(("enmBackendStat(=%s) != OKAY || !(fStatus(=%#x) & BACKEND_READY)\n",
+                         PDMHostAudioStreamStateGetName(enmBackendState), pStreamEx->fStatus));
+    }
+    else
+        LogFlowFunc(("fDirEnabled=false\n"));
     return rc;
 }
@@ -2370,20 +2382,35 @@
                 {
                     /* Reset the play state before we try to start. */
-                    pStreamEx->fLastBackendStatus = drvAudioStreamGetBackendStatus(pThis, pStreamEx);
+                    PDMHOSTAUDIOSTREAMSTATE const enmBackendState = drvAudioStreamGetBackendState(pThis, pStreamEx);
+                    pStreamEx->enmLastBackendState = enmBackendState;
                     if (pStreamEx->Core.enmDir == PDMAUDIODIR_OUT)
                     {
                         pStreamEx->Out.cbPreBuffered = 0;
                         pStreamEx->Out.offPreBuf     = 0;
-                        pStreamEx->Out.enmPlayState  = pStreamEx->Out.cbPreBufThreshold > 0
-                                                     ? DRVAUDIOPLAYSTATE_PREBUF
-                                                     :    (pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY)
-                                                       && (pStreamEx->fLastBackendStatus & PDMAUDIOSTREAM_STS_INITIALIZED)
-                                                     ? DRVAUDIOPLAYSTATE_PLAY
-                                                     : DRVAUDIOPLAYSTATE_NOPLAY;
-                        LogFunc(("ENABLE: fLastBackendStatus=%#x enmPlayState=%s\n",
-                                 pStreamEx->fLastBackendStatus, drvAudioPlayStateName(pStreamEx->Out.enmPlayState)));
+                        pStreamEx->Out.enmPlayState  = DRVAUDIOPLAYSTATE_NOPLAY;
+                        switch (enmBackendState)
+                        {
+                            case PDMHOSTAUDIOSTREAMSTATE_INITIALIZING:
+                                if (pStreamEx->Out.cbPreBufThreshold > 0)
+                                    pStreamEx->Out.enmPlayState = DRVAUDIOPLAYSTATE_PREBUF;
+                                break;
+                            case PDMHOSTAUDIOSTREAMSTATE_OKAY:
+                                pStreamEx->Out.enmPlayState = pStreamEx->Out.cbPreBufThreshold > 0
+                                                            ? DRVAUDIOPLAYSTATE_PREBUF : DRVAUDIOPLAYSTATE_PLAY;
+                                break;
+                            case PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING:
+                            case PDMHOSTAUDIOSTREAMSTATE_INACTIVE:
+                                break;
+                            /* no default */
+                            case PDMHOSTAUDIOSTREAMSTATE_INVALID:
+                            case PDMHOSTAUDIOSTREAMSTATE_END:
+                            case PDMHOSTAUDIOSTREAMSTATE_32BIT_HACK:
+                                break;
+                        }
+                        LogFunc(("ENABLE: enmBackendState=%s enmPlayState=%s\n", PDMHostAudioStreamStateGetName(enmBackendState),
+                                 drvAudioPlayStateName(pStreamEx->Out.enmPlayState)));
                     }
                     else
-                        LogFunc(("ENABLE: fLastBackendStatus=%#x\n", pStreamEx->fLastBackendStatus));
+                        LogFunc(("ENABLE: enmBackendState=%s\n", PDMHostAudioStreamStateGetName(enmBackendState)));
 
                     rc = drvAudioStreamControlInternalBackend(pThis, pStreamEx, PDMAUDIOSTREAMCMD_ENABLE);
@@ -2803,7 +2830,8 @@
                     /* Must check the backend state here first and only try commit the
                        pre-buffered samples if the backend is in working order. */
-                    uint32_t const fBackendStatus = drvAudioStreamGetBackendStatus(pThis, pStreamEx); /* (checks pThis->pHostDrvAudio too) */
+                    PDMHOSTAUDIOSTREAMSTATE const enmBackendState = drvAudioStreamGetBackendState(pThis, pStreamEx);
+                                                                     /* ^^^ (checks pThis->pHostDrvAudio != NULL too) */
                     if (   (pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY)
-                        && (fBackendStatus & PDMAUDIOSTREAM_STS_INITIALIZED))
+                        && enmBackendState == PDMHOSTAUDIOSTREAMSTATE_OKAY)
                     {
                         uint32_t cbIgnored = 0;
@@ -2812,6 +2840,6 @@
                     }
                     else
-                        Log3Func(("[%s] Skipping committing pre-buffered samples, backend not initialized (%#x)!\n",
-                                  pStreamEx->Core.szName, fBackendStatus));
+                        Log3Func(("[%s] Skipping committing pre-buffered samples (status: %#x backend: %s)!\n",
+                                  pStreamEx->Core.szName, pStreamEx->fStatus, PDMHostAudioStreamStateGetName(enmBackendState)));
                 }
                 break;
@@ -2929,10 +2957,9 @@
        )
     {
-        uint32_t const fBackendStatus = drvAudioStreamGetBackendStatus(pThis, pStreamEx);
-
+        PDMHOSTAUDIOSTREAMSTATE const enmBackendState = drvAudioStreamGetBackendState(pThis, pStreamEx);
         if (pStreamEx->fNoMixBufs)
             cbReadable =    pThis->pHostDrvAudio
                          && (pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY)
-                         && (fBackendStatus & PDMAUDIOSTREAM_STS_INITIALIZED)
+                         && enmBackendState == PDMHOSTAUDIOSTREAMSTATE_OKAY
                          && !fDisabled
                        ? pThis->pHostDrvAudio->pfnStreamGetReadable(pThis->pHostDrvAudio, pStreamEx->pBackend)
@@ -2953,5 +2980,5 @@
              * Reading the actual data from a stream then will return silence then.
              */
-            if (   !PDMAudioStrmStatusBackendCanRead(fBackendStatus)
+            if (   enmBackendState != PDMHOSTAUDIOSTREAMSTATE_OKAY /** @todo probably not correct.  OTOH, I'm not sure if we do what the above comment claims either. */
                 || fDisabled)
             {
@@ -2963,6 +2990,6 @@
                         LogRel(("Audio: Input for driver '%s' has been disabled, returning silence\n", pThis->szName));
                     else
-                        LogRel(("Audio: Warning: Input for stream '%s' of driver '%s' not ready (current input status is %#x), returning silence\n",
-                                pStreamEx->Core.szName, pThis->szName, fBackendStatus));
+                        LogRel(("Audio: Warning: Input for stream '%s' of driver '%s' not ready (current input status is %s), returning silence\n",
+                                pStreamEx->Core.szName, pThis->szName, PDMHostAudioStreamStateGetName(enmBackendState) ));
 
                     pStreamEx->Core.fWarningsShown |= PDMAUDIOSTREAM_WARN_FLAGS_DISABLED;
@@ -3016,5 +3043,5 @@
             case DRVAUDIOPLAYSTATE_PLAY_PREBUF:
                 Assert(pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY);
-                Assert(drvAudioStreamGetBackendStatus(pThis, pStreamEx) & PDMAUDIOSTREAM_STS_INITIALIZED);
+                Assert(drvAudioStreamGetBackendState(pThis, pStreamEx) == PDMHOSTAUDIOSTREAMSTATE_OKAY /* potential unplug race */);
                 cbWritable = pThis->pHostDrvAudio->pfnStreamGetWritable(pThis->pHostDrvAudio, pStreamEx->pBackend);
                 break;
@@ -3054,5 +3081,5 @@
                    to move the data. */
                 Assert(pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY);
-                Assert(drvAudioStreamGetBackendStatus(pThis, pStreamEx) & PDMAUDIOSTREAM_STS_INITIALIZED);
+                Assert(drvAudioStreamGetBackendState(pThis, pStreamEx) == PDMHOSTAUDIOSTREAMSTATE_OKAY /* potential unplug race */);
                 uint32_t const cbMin = PDMAudioPropsFramesToBytes(&pStreamEx->Core.Props, 8);
                 cbWritable = pThis->pHostDrvAudio->pfnStreamGetWritable(pThis->pHostDrvAudio, pStreamEx->pBackend);
@@ -3101,6 +3128,8 @@
     AssertRCReturn(rc, PDMAUDIOSTREAMSTATE_INVALID);
 
-    uint32_t const    fStrmStatus = pStreamEx->fStatus;
-    PDMAUDIODIR const enmDir      = pStreamEx->Guest.Cfg.enmDir;
+    PDMHOSTAUDIOSTREAMSTATE const enmBackendState = drvAudioStreamGetBackendState(pThis, pStreamEx);
+    uint32_t const                fStrmStatus     = pStreamEx->fStatus;
+    PDMAUDIODIR const             enmDir          = pStreamEx->Guest.Cfg.enmDir;
+    Assert(enmDir == PDMAUDIODIR_IN || enmDir == PDMAUDIODIR_OUT);
 
     RTCritSectLeave(&pThis->CritSect);
@@ -3114,5 +3143,8 @@
         if (fStrmStatus & PDMAUDIOSTREAM_STS_INITIALIZED)
         {
-            if (fStrmStatus & PDMAUDIOSTREAM_STS_ENABLED)
+            if (   (fStrmStatus & PDMAUDIOSTREAM_STS_ENABLED)
+                && (enmDir == PDMAUDIODIR_IN ? pThis->In.fEnabled : pThis->Out.fEnabled)
+                && (   enmBackendState == PDMHOSTAUDIOSTREAMSTATE_OKAY
+                    || enmBackendState == PDMHOSTAUDIOSTREAMSTATE_INITIALIZING ))
                 enmState = enmDir == PDMAUDIODIR_IN ? PDMAUDIOSTREAMSTATE_ENABLED_READABLE : PDMAUDIOSTREAMSTATE_ENABLED_WRITABLE;
             else
@@ -3128,5 +3160,6 @@
     char szStreamSts[DRVAUDIO_STATUS_STR_MAX];
 #endif
-    Log3Func(("[%s] returns %d (%s)\n", pStreamEx->Core.szName, enmState, drvAudioStreamStatusToStr(szStreamSts, fStrmStatus)));
+    Log3Func(("[%s] returns %s (status: %s)\n", pStreamEx->Core.szName, PDMAudioStreamStateGetName(enmState),
+              drvAudioStreamStatusToStr(szStreamSts, fStrmStatus)));
     return enmState;
 }
@@ -3156,80 +3189,68 @@
 
 /**
- * Processes backend status change.
- *
- * @todo bird: I'm more and more of the opinion that the backend should
- *       explicitly notify us about these changes, rather that we polling them
- *       via PDMIHOSTAUDIO::pfnStreamGetStatus...
- */
-static void drvAudioStreamPlayProcessBackendStateChange(PDRVAUDIOSTREAM pStreamEx, uint32_t fNewState, uint32_t fOldState)
-{
+ * Processes backend state change.
+ */
+static void drvAudioStreamPlayProcessBackendStateChange(PDRVAUDIOSTREAM pStreamEx, PDMHOSTAUDIOSTREAMSTATE enmNewState,
+                                                        PDMHOSTAUDIOSTREAMSTATE enmOldState)
+{
+#ifdef LOG_ENABLED
     DRVAUDIOPLAYSTATE const enmPlayState = pStreamEx->Out.enmPlayState;
-
-    /*
-     * Did PDMAUDIOSTREAM_STS_INITIALIZED change?
-     */
-    if ((fOldState ^ fNewState) & PDMAUDIOSTREAM_STS_INITIALIZED)
-    {
-        if (fOldState & PDMAUDIOSTREAM_STS_INITIALIZED)
-        {
-            /* Pulse audio clear INITIALIZED. */
-            switch (enmPlayState)
+#endif
+    Assert(enmNewState != enmOldState);
+    Assert(enmOldState > PDMHOSTAUDIOSTREAMSTATE_INVALID && enmOldState < PDMHOSTAUDIOSTREAMSTATE_END);
+    AssertReturnVoid(enmNewState > PDMHOSTAUDIOSTREAMSTATE_INVALID && enmNewState < PDMHOSTAUDIOSTREAMSTATE_END);
+
+    /*
+     * Figure out what happend and how that reflects on the playback state and stuff.
+     */
+    switch (enmNewState)
+    {
+        case PDMHOSTAUDIOSTREAMSTATE_INITIALIZING:
+            /* Guess we're switching device. Nothing to do because the backend will tell us, right? */
+            break;
+
+        case PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING:
+            /* The stream has stopped working.  Switch to noplay mode. */
+            pStreamEx->Out.enmPlayState = DRVAUDIOPLAYSTATE_NOPLAY;
+            break;
+
+        case PDMHOSTAUDIOSTREAMSTATE_OKAY:
+            switch (enmOldState)
             {
-                case DRVAUDIOPLAYSTATE_PLAY:
-                case DRVAUDIOPLAYSTATE_PREBUF_COMMITTING:
-                    pStreamEx->Out.enmPlayState = DRVAUDIOPLAYSTATE_NOPLAY;
-                    /** @todo We could enter PREBUF here and hope for the device to re-appear in
-                     *        initialized state... */
+                case PDMHOSTAUDIOSTREAMSTATE_INITIALIZING:
+                    /* Should be taken care of elsewhere, so do nothing. */
                     break;
-                case DRVAUDIOPLAYSTATE_PLAY_PREBUF:
-                    pStreamEx->Out.enmPlayState = DRVAUDIOPLAYSTATE_PREBUF_SWITCHING;
+
+                case PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING:
+                case PDMHOSTAUDIOSTREAMSTATE_INACTIVE:
+                    /* Go back to pre-buffering/playing depending on whether it is enabled
+                       or not, resetting the stream state. */
+                    drvAudioStreamResetInternal(pStreamEx);
                     break;
-                case DRVAUDIOPLAYSTATE_PREBUF:
-                    break;
-                case DRVAUDIOPLAYSTATE_PREBUF_OVERDUE:
-                case DRVAUDIOPLAYSTATE_PREBUF_SWITCHING:
-                    AssertFailedBreak();
-                /* no default */
-                case DRVAUDIOPLAYSTATE_NOPLAY:
-                case DRVAUDIOPLAYSTATE_END:
-                case DRVAUDIOPLAYSTATE_INVALID:
+
+                /* no default: */
+                case PDMHOSTAUDIOSTREAMSTATE_OKAY: /* impossible */
+                case PDMHOSTAUDIOSTREAMSTATE_INVALID:
+                case PDMHOSTAUDIOSTREAMSTATE_END:
+                case PDMHOSTAUDIOSTREAMSTATE_32BIT_HACK:
                     break;
             }
-            LogFunc(("PDMAUDIOSTREAM_STS_INITIALIZED was cleared: %s -> %s\n",
-                     drvAudioPlayStateName(enmPlayState), drvAudioPlayStateName(pStreamEx->Out.enmPlayState) ));
-        }
-        else
-        {
-            if (pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY)
-            {
-    /** @todo We need to resync the stream status somewhere...  */
-                switch (enmPlayState)
-                {
-                    case DRVAUDIOPLAYSTATE_PREBUF:
-                    case DRVAUDIOPLAYSTATE_PREBUF_SWITCHING:
-                        break;
-                    case DRVAUDIOPLAYSTATE_PREBUF_OVERDUE:
-                        pStreamEx->Out.enmPlayState = DRVAUDIOPLAYSTATE_PREBUF_COMMITTING;
-                        break;
-                    case DRVAUDIOPLAYSTATE_NOPLAY:
-                        pStreamEx->Out.enmPlayState = DRVAUDIOPLAYSTATE_PREBUF;
-                        break;
-                    case DRVAUDIOPLAYSTATE_PLAY:
-                    case DRVAUDIOPLAYSTATE_PLAY_PREBUF:
-                    case DRVAUDIOPLAYSTATE_PREBUF_COMMITTING:
-                        AssertFailedBreak();
-                    /* no default */
-                    case DRVAUDIOPLAYSTATE_END:
-                    case DRVAUDIOPLAYSTATE_INVALID:
-                        break;
-                }
-                LogFunc(("PDMAUDIOSTREAM_STS_INITIALIZED was set: %s -> %s\n",
-                         drvAudioPlayStateName(enmPlayState), drvAudioPlayStateName(pStreamEx->Out.enmPlayState) ));
-            }
-            else
-                LogFunc(("PDMAUDIOSTREAM_STS_INITIALIZED was set (enmPlayState=%s), but PDMAUDIOSTREAM_STS_BACKEND_READY is not.\n",
-                         drvAudioPlayStateName(enmPlayState) ));
-        }
-    }
+            break;
+
+        case PDMHOSTAUDIOSTREAMSTATE_INACTIVE:
+            /* Stream is now inactive. Switch to noplay mode. */
+            pStreamEx->Out.enmPlayState = DRVAUDIOPLAYSTATE_NOPLAY;
+            break;
+
+        /* no default: */
+        case PDMHOSTAUDIOSTREAMSTATE_INVALID:
+        case PDMHOSTAUDIOSTREAMSTATE_END:
+        case PDMHOSTAUDIOSTREAMSTATE_32BIT_HACK:
+            break;
+    }
+
+    LogFunc(("Stream '%s': %s/%s -> %s/%s\n", pStreamEx->Guest.Cfg.szName,
+             PDMHostAudioStreamStateGetName(enmOldState), drvAudioPlayStateName(enmPlayState),
+             PDMHostAudioStreamStateGetName(enmNewState), drvAudioPlayStateName(pStreamEx->Out.enmPlayState) ));
 }
 
@@ -3279,34 +3300,14 @@
             && pThis->pHostDrvAudio != NULL)
         {
-#ifdef LOG_ENABLED
-            char szState[DRVAUDIO_STATUS_STR_MAX];
-#endif
             /*
-             * Get the backend state and check if we've changed to "initialized" or
-             * to switch prep mode.
-             *
-             * We don't really need to watch ENABLE or PAUSE here as these should be
-             * in sync between our state and the backend (there is a tiny tiny chance
-             * that we are resumed before the backend driver, but AIO threads really
-             * shouldn't be getting here that fast I hope).
+             * Get the backend state and check if it changed.
              */
-            /** @todo
-             * The PENDING_DISABLE (== draining) is not reported by most backend and it's an
-             * open question whether we should still allow writes even when the backend
-             * is draining anyway.  We currently don't.  Maybe we just re-define it as
-             * a non-backend status flag.
-             */
-            uint32_t const fBackendStatus = drvAudioStreamGetBackendStatus(pThis, pStreamEx);
-            Assert(      (fBackendStatus     & (PDMAUDIOSTREAM_STS_ENABLED | PDMAUDIOSTREAM_STS_PAUSED))
-                      == (pStreamEx->fStatus & (PDMAUDIOSTREAM_STS_ENABLED | PDMAUDIOSTREAM_STS_PAUSED))
-                   || !(pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY)
-                   || !(fBackendStatus & PDMAUDIOSTREAM_STS_INITIALIZED));
-
-            if (!((pStreamEx->fLastBackendStatus ^ fBackendStatus) & PDMAUDIOSTREAM_STS_INITIALIZED))
+            PDMHOSTAUDIOSTREAMSTATE const enmBackendState = drvAudioStreamGetBackendState(pThis, pStreamEx);
+            if (enmBackendState == pStreamEx->enmLastBackendState)
             { /* no relevant change - likely */ }
             else
             {
-                drvAudioStreamPlayProcessBackendStateChange(pStreamEx, fBackendStatus, pStreamEx->fLastBackendStatus);
-                pStreamEx->fLastBackendStatus = fBackendStatus;
+                drvAudioStreamPlayProcessBackendStateChange(pStreamEx, enmBackendState, pStreamEx->enmLastBackendState);
+                pStreamEx->enmLastBackendState = enmBackendState;
             }
 
@@ -3318,5 +3319,5 @@
                 case DRVAUDIOPLAYSTATE_PLAY:
                     Assert(pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY);
-                    Assert(fBackendStatus & PDMAUDIOSTREAM_STS_INITIALIZED);
+                    Assert(enmBackendState == PDMHOSTAUDIOSTREAMSTATE_OKAY);
                     rc = drvAudioStreamPlayLocked(pThis, pStreamEx, (uint8_t const *)pvBuf, cbBuf, pcbWritten);
                     break;
@@ -3324,5 +3325,5 @@
                 case DRVAUDIOPLAYSTATE_PLAY_PREBUF:
                     Assert(pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY);
-                    Assert(fBackendStatus & PDMAUDIOSTREAM_STS_INITIALIZED);
+                    Assert(enmBackendState == PDMHOSTAUDIOSTREAMSTATE_OKAY);
                     rc = drvAudioStreamPlayLocked(pThis, pStreamEx, (uint8_t const *)pvBuf, cbBuf, pcbWritten);
                     drvAudioStreamPreBuffer(pStreamEx, (uint8_t const *)pvBuf, *pcbWritten, pStreamEx->Out.cbPreBufThreshold);
@@ -3332,5 +3333,5 @@
                     if (cbBuf + pStreamEx->Out.cbPreBuffered < pStreamEx->Out.cbPreBufThreshold)
                         rc = drvAudioStreamPlayToPreBuffer(pStreamEx, pvBuf, cbBuf, pStreamEx->Out.cbPreBufThreshold, pcbWritten);
-                    else if (   (fBackendStatus & PDMAUDIOSTREAM_STS_INITIALIZED)
+                    else if (   enmBackendState == PDMHOSTAUDIOSTREAMSTATE_OKAY
                              && (pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY))
                     {
@@ -3352,5 +3353,5 @@
                 case DRVAUDIOPLAYSTATE_PREBUF_OVERDUE:
                     Assert(   !(pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY)
-                           || !(fBackendStatus & PDMAUDIOSTREAM_STS_INITIALIZED));
+                           || enmBackendState != PDMHOSTAUDIOSTREAMSTATE_OKAY);
                     RT_FALL_THRU();
                 case DRVAUDIOPLAYSTATE_PREBUF_SWITCHING:
@@ -3360,5 +3361,5 @@
                 case DRVAUDIOPLAYSTATE_PREBUF_COMMITTING:
                     Assert(pStreamEx->fStatus & PDMAUDIOSTREAM_STS_BACKEND_READY);
-                    Assert(fBackendStatus & PDMAUDIOSTREAM_STS_INITIALIZED);
+                    Assert(enmBackendState == PDMHOSTAUDIOSTREAMSTATE_OKAY);
                     rc = drvAudioStreamPreBufComitting(pThis, pStreamEx, (uint8_t const *)pvBuf, cbBuf, pcbWritten);
                     break;
@@ -3368,5 +3369,5 @@
                     pStreamEx->offInternal += cbBuf;
                     Log3Func(("[%s] Discarding the data, backend state: %s\n", pStreamEx->Core.szName,
-                              drvAudioStreamStatusToStr(szState, fBackendStatus) ));
+                              PDMHostAudioStreamStateGetName(enmBackendState) ));
                     break;
 
@@ -3725,6 +3726,6 @@
         }
 
-        uint32_t const fBackendStatus = drvAudioStreamGetBackendStatus(pThis, pStreamEx);
-        if (fBackendStatus & PDMAUDIOSTREAM_STS_INITIALIZED)
+        PDMHOSTAUDIOSTREAMSTATE const enmBackendState = drvAudioStreamGetBackendState(pThis, pStreamEx);
+        if (enmBackendState == PDMHOSTAUDIOSTREAMSTATE_OKAY)
         {
             /*
@@ -3889,8 +3890,9 @@
             if (pThis->pHostDrvAudio->pfnStreamNotifyDeviceChanged)
             {
-                LogFlowFunc(("Calling pfnStreamNotifyDeviceChanged on %s, old backend status: %#x...\n", pStreamEx->Core.szName,
-                              drvAudioStreamGetBackendStatus(pThis, pStreamEx) ));
+                LogFlowFunc(("Calling pfnStreamNotifyDeviceChanged on %s, old backend state: %s...\n", pStreamEx->Core.szName,
+                             PDMHostAudioStreamStateGetName(drvAudioStreamGetBackendState(pThis, pStreamEx)) ));
                 pThis->pHostDrvAudio->pfnStreamNotifyDeviceChanged(pThis->pHostDrvAudio, pStreamEx->pBackend, pvUser);
-                LogFlowFunc(("New stream backend status: %#x.\n", drvAudioStreamGetBackendStatus(pThis, pStreamEx) ));
+                LogFlowFunc(("New stream backend state: %s\n",
+                             PDMHostAudioStreamStateGetName(drvAudioStreamGetBackendState(pThis, pStreamEx)) ));
             }
             else
@@ -4216,5 +4218,5 @@
     AssertPtrReturn(pIHostDrvAudio->pfnStreamGetWritable, VERR_INVALID_POINTER);
     AssertPtrNullReturn(pIHostDrvAudio->pfnStreamGetPending, VERR_INVALID_POINTER);
-    AssertPtrReturn(pIHostDrvAudio->pfnStreamGetStatus, VERR_INVALID_POINTER);
+    AssertPtrReturn(pIHostDrvAudio->pfnStreamGetState, VERR_INVALID_POINTER);
     AssertPtrReturn(pIHostDrvAudio->pfnStreamPlay, VERR_INVALID_POINTER);
     AssertPtrReturn(pIHostDrvAudio->pfnStreamCapture, VERR_INVALID_POINTER);
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp	(revision 88884)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp	(revision 88887)
@@ -1118,11 +1118,13 @@
 
 /**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
- */
-static DECLCALLBACK(uint32_t) drvHostAlsaAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
-{
-    RT_NOREF(pInterface, pStream);
-
-    return PDMAUDIOSTREAM_STS_INITIALIZED | PDMAUDIOSTREAM_STS_ENABLED;
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
+ */
+static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHostAlsaAudioHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
+                                                                               PPDMAUDIOBACKENDSTREAM pStream)
+{
+    RT_NOREF(pInterface);
+    AssertPtrReturn(pStream, PDMHOSTAUDIOSTREAMSTATE_INVALID);
+
+    return PDMHOSTAUDIOSTREAMSTATE_OKAY;
 }
 
@@ -1418,5 +1420,5 @@
     pThis->IHostAudio.pfnStreamGetWritable          = drvHostAlsaAudioHA_StreamGetWritable;
     pThis->IHostAudio.pfnStreamGetPending           = drvHostAlsaAudioHA_StreamGetPending;
-    pThis->IHostAudio.pfnStreamGetStatus            = drvHostAlsaAudioHA_StreamGetStatus;
+    pThis->IHostAudio.pfnStreamGetState             = drvHostAlsaAudioHA_StreamGetState;
     pThis->IHostAudio.pfnStreamPlay                 = drvHostAlsaAudioHA_StreamPlay;
     pThis->IHostAudio.pfnStreamCapture              = drvHostAlsaAudioHA_StreamCapture;
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioCoreAudio.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioCoreAudio.cpp	(revision 88884)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioCoreAudio.cpp	(revision 88887)
@@ -2424,22 +2424,20 @@
 
 /**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
- */
-static DECLCALLBACK(uint32_t) drvHostCoreAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
+ */
+static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHostCoreAudioHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
+                                                                               PPDMAUDIOBACKENDSTREAM pStream)
 {
     RT_NOREF(pInterface);
-    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
-
-    PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream;
-
-    uint32_t fStrmStatus = PDMAUDIOSTREAM_STS_NONE;
-
-    if (pCAStream->pCfg) /* Configured?  */
-    {
-        if (ASMAtomicReadU32(&pCAStream->enmStatus) == COREAUDIOSTATUS_INIT)
-            fStrmStatus |= PDMAUDIOSTREAM_STS_INITIALIZED | PDMAUDIOSTREAM_STS_ENABLED;
-    }
-
-    return fStrmStatus;
+    PCOREAUDIOSTREAM pStreamCa = (PCOREAUDIOSTREAM)pStream;
+    AssertPtrReturn(pStreamCa, PDMHOSTAUDIOSTREAMSTATE_INVALID);
+
+    if (pStreamCa->pCfg) /* Configured?  */
+    {
+        if (ASMAtomicReadU32(&pStreamCa->enmStatus) == COREAUDIOSTATUS_INIT)
+            return PDMHOSTAUDIOSTREAMSTATE_OKAY;
+    }
+
+    return PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING; /** @todo ?? */
 }
 
@@ -2557,5 +2555,5 @@
     pThis->IHostAudio.pfnStreamGetWritable          = drvHostCoreAudioHA_StreamGetWritable;
     pThis->IHostAudio.pfnStreamGetPending           = NULL;
-    pThis->IHostAudio.pfnStreamGetStatus            = drvHostCoreAudioHA_StreamGetStatus;
+    pThis->IHostAudio.pfnStreamGetState             = drvHostCoreAudioHA_StreamGetState;
     pThis->IHostAudio.pfnStreamPlay                 = drvHostCoreAudioHA_StreamPlay;
     pThis->IHostAudio.pfnStreamCapture              = drvHostCoreAudioHA_StreamCapture;
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp	(revision 88884)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp	(revision 88887)
@@ -2402,18 +2402,15 @@
 
 /**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
- */
-static DECLCALLBACK(uint32_t) drvHostDSoundHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
+ */
+static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHostDSoundHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
+                                                                            PPDMAUDIOBACKENDSTREAM pStream)
 {
     RT_NOREF(pInterface);
     PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream;
-    AssertPtrReturn(pStreamDS, PDMAUDIOSTREAM_STS_NONE);
-
-    uint32_t fStrmStatus = PDMAUDIOSTREAM_STS_INITIALIZED;
-    if (pStreamDS->fEnabled)
-        fStrmStatus |= PDMAUDIOSTREAM_STS_ENABLED;
-
-    LogFlowFunc(("returns %#x for '%s' {%s}\n", fStrmStatus, pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS)));
-    return fStrmStatus;
+    AssertPtrReturn(pStreamDS, PDMHOSTAUDIOSTREAMSTATE_INVALID);
+
+    LogFlowFunc(("returns OKAY for '%s' {%s}\n", pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS)));
+    return PDMHOSTAUDIOSTREAMSTATE_OKAY;
 }
 
@@ -2771,5 +2768,5 @@
     pThis->IHostAudio.pfnStreamGetWritable          = drvHostDSoundHA_StreamGetWritable;
     pThis->IHostAudio.pfnStreamGetPending           = NULL;
-    pThis->IHostAudio.pfnStreamGetStatus            = drvHostDSoundHA_StreamGetStatus;
+    pThis->IHostAudio.pfnStreamGetState             = drvHostDSoundHA_StreamGetState;
     pThis->IHostAudio.pfnStreamPlay                 = drvHostDSoundHA_StreamPlay;
     pThis->IHostAudio.pfnStreamCapture              = drvHostDSoundHA_StreamCapture;
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioDebug.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioDebug.cpp	(revision 88884)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioDebug.cpp	(revision 88887)
@@ -261,10 +261,12 @@
 
 /**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
- */
-static DECLCALLBACK(uint32_t) drvHostDebugAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
-{
-    RT_NOREF(pInterface, pStream);
-    return PDMAUDIOSTREAM_STS_INITIALIZED | PDMAUDIOSTREAM_STS_ENABLED;
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
+ */
+static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHostDebugAudioHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
+                                                                                PPDMAUDIOBACKENDSTREAM pStream)
+{
+    RT_NOREF(pInterface);
+    AssertPtrReturn(pStream, PDMHOSTAUDIOSTREAMSTATE_INVALID);
+    return PDMHOSTAUDIOSTREAMSTATE_OKAY;
 }
 
@@ -448,5 +450,5 @@
     pThis->IHostAudio.pfnStreamGetWritable          = drvHostDebugAudioHA_StreamGetWritable;
     pThis->IHostAudio.pfnStreamGetPending           = drvHostDebugAudioHA_StreamGetPending;
-    pThis->IHostAudio.pfnStreamGetStatus            = drvHostDebugAudioHA_StreamGetStatus;
+    pThis->IHostAudio.pfnStreamGetState             = drvHostDebugAudioHA_StreamGetState;
     pThis->IHostAudio.pfnStreamPlay                 = drvHostDebugAudioHA_StreamPlay;
     pThis->IHostAudio.pfnStreamCapture              = drvHostDebugAudioHA_StreamCapture;
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioNull.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioNull.cpp	(revision 88884)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioNull.cpp	(revision 88887)
@@ -181,10 +181,18 @@
 
 /**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
- */
-static DECLCALLBACK(uint32_t) drvHostNullAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
-{
-    RT_NOREF(pInterface, pStream);
-    return PDMAUDIOSTREAM_STS_INITIALIZED | PDMAUDIOSTREAM_STS_ENABLED;
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
+ */
+static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHostNullAudioHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
+                                                                               PPDMAUDIOBACKENDSTREAM pStream)
+{
+    RT_NOREF(pInterface);
+    AssertPtrReturn(pStream, PDMHOSTAUDIOSTREAMSTATE_INVALID);
+#if 0
+    /* Bit bucket appraoch where we ignore the output and silence the input buffers.  */
+    return PDMHOSTAUDIOSTREAMSTATE_OKAY;
+#else
+    /* Approach where the mixer in the devices skips us and saves a few CPU cycles. */
+    return PDMHOSTAUDIOSTREAMSTATE_INACTIVE;
+#endif
 }
 
@@ -242,5 +250,5 @@
     /* .pfnStreamGetWritable         =*/ drvHostNullAudioHA_StreamGetWritable,
     /* .pfnStreamGetPending          =*/ drvHostNullAudioHA_StreamGetPending,
-    /* .pfnStreamGetStatus           =*/ drvHostNullAudioHA_StreamGetStatus,
+    /* .pfnStreamGetState            =*/ drvHostNullAudioHA_StreamGetState,
     /* .pfnStreamPlay                =*/ drvHostNullAudioHA_StreamPlay,
     /* .pfnStreamCapture             =*/ drvHostNullAudioHA_StreamCapture,
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioOss.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioOss.cpp	(revision 88884)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioOss.cpp	(revision 88887)
@@ -699,10 +699,12 @@
 
 /**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
- */
-static DECLCALLBACK(uint32_t) drvHostOssAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
-{
-    RT_NOREF(pInterface, pStream);
-    return PDMAUDIOSTREAM_STS_INITIALIZED | PDMAUDIOSTREAM_STS_ENABLED;
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
+ */
+static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHostOssAudioHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
+                                                                              PPDMAUDIOBACKENDSTREAM pStream)
+{
+    RT_NOREF(pInterface);
+    AssertPtrReturn(pStream, PDMHOSTAUDIOSTREAMSTATE_INVALID);
+    return PDMHOSTAUDIOSTREAMSTATE_OKAY;
 }
 
@@ -871,5 +873,5 @@
     pThis->IHostAudio.pfnStreamGetWritable          = drvHostOssAudioHA_StreamGetWritable;
     pThis->IHostAudio.pfnStreamGetPending           = NULL;
-    pThis->IHostAudio.pfnStreamGetStatus            = drvHostOssAudioHA_StreamGetStatus;
+    pThis->IHostAudio.pfnStreamGetState             = drvHostOssAudioHA_StreamGetState;
     pThis->IHostAudio.pfnStreamPlay                 = drvHostOssAudioHA_StreamPlay;
     pThis->IHostAudio.pfnStreamCapture              = drvHostOssAudioHA_StreamCapture;
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp	(revision 88884)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp	(revision 88887)
@@ -1547,10 +1547,11 @@
 
 /**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
- */
-static DECLCALLBACK(uint32_t) drvHostAudioPaHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
+ */
+static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHostAudioPaHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
+                                                                             PPDMAUDIOBACKENDSTREAM pStream)
 {
     PDRVHOSTPULSEAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio);
-    RT_NOREF(pStream);
+    AssertPtrReturn(pStream, PDMHOSTAUDIOSTREAMSTATE_INVALID);
 
     /* Check PulseAudio's general status. */
@@ -1561,5 +1562,5 @@
         {
             /** @todo should we check the actual stream state? */
-            return PDMAUDIOSTREAM_STS_INITIALIZED | PDMAUDIOSTREAM_STS_ENABLED;
+            return PDMHOSTAUDIOSTREAMSTATE_OKAY;
         }
         LogFunc(("non-good context state: %d\n", enmState));
@@ -1567,5 +1568,5 @@
     else
         LogFunc(("No context!\n"));
-    return PDMAUDIOSTREAM_STS_NONE;
+    return PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING;
 }
 
@@ -1912,5 +1913,5 @@
     pThis->IHostAudio.pfnStreamGetWritable          = drvHostAudioPaHA_StreamGetWritable;
     pThis->IHostAudio.pfnStreamGetPending           = NULL;
-    pThis->IHostAudio.pfnStreamGetStatus            = drvHostAudioPaHA_StreamGetStatus;
+    pThis->IHostAudio.pfnStreamGetState             = drvHostAudioPaHA_StreamGetState;
     pThis->IHostAudio.pfnStreamPlay                 = drvHostAudioPaHA_StreamPlay;
     pThis->IHostAudio.pfnStreamCapture              = drvHostAudioPaHA_StreamCapture;
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioValidationKit.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioValidationKit.cpp	(revision 88884)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioValidationKit.cpp	(revision 88887)
@@ -332,10 +332,12 @@
 
 /**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
- */
-static DECLCALLBACK(uint32_t) drvHostValKitAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
-{
-    RT_NOREF(pInterface, pStream);
-    return PDMAUDIOSTREAM_STS_INITIALIZED | PDMAUDIOSTREAM_STS_ENABLED;
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
+ */
+static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHostValKitAudioHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
+                                                                                 PPDMAUDIOBACKENDSTREAM pStream)
+{
+    RT_NOREF(pInterface);
+    AssertPtrReturn(pStream, PDMHOSTAUDIOSTREAMSTATE_INVALID);
+    return PDMHOSTAUDIOSTREAMSTATE_OKAY;
 }
 
@@ -445,5 +447,5 @@
     pThis->IHostAudio.pfnStreamGetWritable          = drvHostValKitAudioHA_StreamGetWritable;
     pThis->IHostAudio.pfnStreamGetPending           = NULL;
-    pThis->IHostAudio.pfnStreamGetStatus            = drvHostValKitAudioHA_StreamGetStatus;
+    pThis->IHostAudio.pfnStreamGetState             = drvHostValKitAudioHA_StreamGetState;
     pThis->IHostAudio.pfnStreamPlay                 = drvHostValKitAudioHA_StreamPlay;
     pThis->IHostAudio.pfnStreamCapture              = drvHostValKitAudioHA_StreamCapture;
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioWasApi.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioWasApi.cpp	(revision 88884)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioWasApi.cpp	(revision 88887)
@@ -2519,36 +2519,32 @@
 
 /**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
- */
-static DECLCALLBACK(uint32_t) drvHostAudioWasHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
+ */
+static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHostAudioWasHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
+                                                                              PPDMAUDIOBACKENDSTREAM pStream)
 {
     RT_NOREF(pInterface);
     PDRVHOSTAUDIOWASSTREAM pStreamWas = (PDRVHOSTAUDIOWASSTREAM)pStream;
-    AssertPtrReturn(pStreamWas, PDMAUDIOSTREAM_STS_NONE);
-
-    uint32_t fStrmStatus = 0;
+    AssertPtrReturn(pStreamWas, PDMHOSTAUDIOSTREAMSTATE_INVALID);
+
+    PDMHOSTAUDIOSTREAMSTATE enmState;
     AssertPtr(pStreamWas->pDevCfg);
     if (pStreamWas->pDevCfg /*paranoia*/)
     {
         if (RT_SUCCESS(pStreamWas->pDevCfg->rcSetup))
-            fStrmStatus |= PDMAUDIOSTREAM_STS_INITIALIZED;
-        else if (pStreamWas->pDevCfg->rcSetup != VERR_AUDIO_STREAM_INIT_IN_PROGRESS)
-        {
-            /** @todo trigger device reset? Probably won't help, so what to do?  */
-        }
-    }
-    if (pStreamWas->fEnabled)
-    {
-        fStrmStatus |= PDMAUDIOSTREAM_STS_ENABLED;
-        if (pStreamWas->fDraining)
-            fStrmStatus |= PDMAUDIOSTREAM_STS_PENDING_DISABLE;
-        if (pStreamWas->fRestartOnResume)
-            fStrmStatus |= PDMAUDIOSTREAM_STS_PAUSED;
-    }
-    if (pStreamWas->fSwitchingDevice)
-        fStrmStatus |= PDMAUDIOSTREAM_STS_PREPARING_SWITCH;
-
-    LogFlowFunc(("returns %#x for '%s' {%s}\n", fStrmStatus, pStreamWas->Cfg.szName, drvHostWasStreamStatusString(pStreamWas)));
-    return fStrmStatus;
+            enmState = PDMHOSTAUDIOSTREAMSTATE_OKAY;
+        else if (   pStreamWas->pDevCfg->rcSetup == VERR_AUDIO_STREAM_INIT_IN_PROGRESS
+                 || pStreamWas->fSwitchingDevice )
+            enmState = PDMHOSTAUDIOSTREAMSTATE_INITIALIZING;
+        else
+            enmState = PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING;
+    }
+    else if (pStreamWas->fSwitchingDevice)
+        enmState = PDMHOSTAUDIOSTREAMSTATE_INITIALIZING;
+    else
+        enmState = PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING;
+
+    LogFlowFunc(("returns %d for '%s' {%s}\n", enmState, pStreamWas->Cfg.szName, drvHostWasStreamStatusString(pStreamWas)));
+    return enmState;
 }
 
@@ -3020,5 +3016,5 @@
     pThis->IHostAudio.pfnStreamGetWritable          = drvHostAudioWasHA_StreamGetWritable;
     pThis->IHostAudio.pfnStreamGetPending           = drvHostAudioWasHA_StreamGetPending;
-    pThis->IHostAudio.pfnStreamGetStatus            = drvHostAudioWasHA_StreamGetStatus;
+    pThis->IHostAudio.pfnStreamGetState             = drvHostAudioWasHA_StreamGetState;
     pThis->IHostAudio.pfnStreamPlay                 = drvHostAudioWasHA_StreamPlay;
     pThis->IHostAudio.pfnStreamCapture              = drvHostAudioWasHA_StreamCapture;
