Index: trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp	(revision 89480)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp	(revision 89481)
@@ -75,5 +75,5 @@
  * ALSA host audio specific stream data.
  */
-typedef struct ALSAAUDIOSTREAM
+typedef struct DRVHSTAUDALSASTREAM
 {
     /** Common part. */
@@ -87,7 +87,7 @@
     /** The stream's acquired configuration. */
     PDMAUDIOSTREAMCFG       Cfg;
-} ALSAAUDIOSTREAM;
+} DRVHSTAUDALSASTREAM;
 /** Pointer to the ALSA host audio specific stream data. */
-typedef ALSAAUDIOSTREAM *PALSAAUDIOSTREAM;
+typedef DRVHSTAUDALSASTREAM *PDRVHSTAUDALSASTREAM;
 
 
@@ -96,5 +96,5 @@
  * @implements PDMIAUDIOCONNECTOR
  */
-typedef struct DRVHOSTALSAAUDIO
+typedef struct DRVHSTAUDALSA
 {
     /** Pointer to the driver instance structure. */
@@ -109,7 +109,7 @@
     /** Default output device name. */
     char                szDefaultOut[256];
-} DRVHOSTALSAAUDIO;
+} DRVHSTAUDALSA;
 /** Pointer to the instance data of an ALSA host audio driver. */
-typedef DRVHOSTALSAAUDIO *PDRVHOSTALSAAUDIO;
+typedef DRVHSTAUDALSA *PDRVHSTAUDALSA;
 
 
@@ -122,5 +122,5 @@
  *                  NULL.
  */
-static int alsaStreamClose(snd_pcm_t **phPCM)
+static int drvHstAudAlsaStreamClose(snd_pcm_t **phPCM)
 {
     if (!phPCM || !*phPCM)
@@ -146,6 +146,6 @@
 
 #ifdef DEBUG
-static void alsaDbgErrorHandler(const char *file, int line, const char *function,
-                                int err, const char *fmt, ...)
+static void drvHstAudAlsaDbgErrorHandler(const char *file, int line, const char *function,
+                                         int err, const char *fmt, ...)
 {
     /** @todo Implement me! */
@@ -161,5 +161,5 @@
  * @param   hPCM               ALSA stream handle.
  */
-static int alsaStreamRecover(snd_pcm_t *hPCM)
+static int drvHstAudAlsaStreamRecover(snd_pcm_t *hPCM)
 {
     AssertPtrReturn(hPCM, VERR_INVALID_POINTER);
@@ -179,8 +179,10 @@
  * Resumes an ALSA stream.
  *
+ * Used by drvHstAudAlsaHA_StreamPlay() and drvHstAudAlsaHA_StreamCapture().
+ *
  * @returns VBox status code.
  * @param   hPCM               ALSA stream to resume.
  */
-static int alsaStreamResume(snd_pcm_t *hPCM)
+static int drvHstAudAlsaStreamResume(snd_pcm_t *hPCM)
 {
     AssertPtrReturn(hPCM, VERR_INVALID_POINTER);
@@ -200,5 +202,5 @@
  * @interface_method_impl{PDMIHOSTAUDIO,pfnGetConfig}
  */
-static DECLCALLBACK(int) drvHostAlsaAudioHA_GetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
+static DECLCALLBACK(int) drvHstAudAlsaHA_GetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
 {
     RT_NOREF(pInterface);
@@ -209,5 +211,5 @@
      */
     RTStrCopy(pBackendCfg->szName, sizeof(pBackendCfg->szName), "ALSA");
-    pBackendCfg->cbStream       = sizeof(ALSAAUDIOSTREAM);
+    pBackendCfg->cbStream       = sizeof(DRVHSTAUDALSASTREAM);
     pBackendCfg->fFlags         = 0;
     /* ALSA allows exactly one input and one output used at a time for the selected device(s). */
@@ -222,5 +224,5 @@
  * @interface_method_impl{PDMIHOSTAUDIO,pfnGetDevices}
  */
-static DECLCALLBACK(int) drvHostAlsaAudioHA_GetDevices(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHOSTENUM pDeviceEnum)
+static DECLCALLBACK(int) drvHstAudAlsaHA_GetDevices(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHOSTENUM pDeviceEnum)
 {
     RT_NOREF(pInterface);
@@ -321,5 +323,5 @@
  * @interface_method_impl{PDMIHOSTAUDIO,pfnGetStatus}
  */
-static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostAlsaAudioHA_GetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir)
+static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHstAudAlsaHA_GetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir)
 {
     RT_NOREF(enmDir);
@@ -617,5 +619,5 @@
  * @param   phPCM       Where to store the ALSA stream handle on success.
  */
-static int alsaStreamOpen(PDRVHOSTALSAAUDIO pThis, snd_pcm_format_t enmAlsaFmt, PCPDMAUDIOSTREAMCFG pCfgReq,
+static int alsaStreamOpen(PDRVHSTAUDALSA pThis, snd_pcm_format_t enmAlsaFmt, PCPDMAUDIOSTREAMCFG pCfgReq,
                           PPDMAUDIOSTREAMCFG pCfgAcq, snd_pcm_t **phPCM)
 {
@@ -665,5 +667,5 @@
         else
             LogRel(("ALSA: Error setting non-blocking mode for %s stream: %s\n", pszType, snd_strerror(err)));
-        alsaStreamClose(&hPCM);
+        drvHstAudAlsaStreamClose(&hPCM);
     }
     else
@@ -677,8 +679,8 @@
  * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
  */
-static DECLCALLBACK(int) drvHostAlsaAudioHA_StreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
-                                                         PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
-{
-    PDRVHOSTALSAAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTALSAAUDIO, IHostAudio);
+static DECLCALLBACK(int) drvHstAudAlsaHA_StreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
+                                                      PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
+{
+    PDRVHSTAUDALSA pThis = RT_FROM_MEMBER(pInterface, DRVHSTAUDALSA, IHostAudio);
     AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
@@ -686,5 +688,5 @@
     AssertPtrReturn(pCfgAcq,    VERR_INVALID_POINTER);
 
-    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
+    PDRVHSTAUDALSASTREAM pStreamALSA = (PDRVHSTAUDALSASTREAM)pStream;
     PDMAudioStrmCfgCopy(&pStreamALSA->Cfg, pCfgReq);
 
@@ -717,9 +719,8 @@
  * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
  */
-static DECLCALLBACK(int) drvHostAlsaAudioHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
-                                                          bool fImmediate)
+static DECLCALLBACK(int) drvHstAudAlsaHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, bool fImmediate)
 {
     RT_NOREF(pInterface);
-    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
+    PDRVHSTAUDALSASTREAM pStreamALSA = (PDRVHSTAUDALSASTREAM)pStream;
     AssertPtrReturn(pStreamALSA, VERR_INVALID_POINTER);
     RT_NOREF(fImmediate);
@@ -727,5 +728,5 @@
     /** @todo r=bird: It's not like we can do much with a bad status... Check
      *        what the caller does... */
-    return alsaStreamClose(&pStreamALSA->hPCM);
+    return drvHstAudAlsaStreamClose(&pStreamALSA->hPCM);
 }
 
@@ -734,8 +735,8 @@
  * @ interface_method_impl{PDMIHOSTAUDIO,pfnStreamEnable}
  */
-static DECLCALLBACK(int) drvHostAlsaAudioHA_StreamEnable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+static DECLCALLBACK(int) drvHstAudAlsaHA_StreamEnable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
 {
     RT_NOREF(pInterface);
-    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
+    PDRVHSTAUDALSASTREAM pStreamALSA = (PDRVHSTAUDALSASTREAM)pStream;
 
     /*
@@ -778,8 +779,8 @@
  * @ interface_method_impl{PDMIHOSTAUDIO,pfnStreamDisable}
  */
-static DECLCALLBACK(int) drvHostAlsaAudioHA_StreamDisable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+static DECLCALLBACK(int) drvHstAudAlsaHA_StreamDisable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
 {
     RT_NOREF(pInterface);
-    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
+    PDRVHSTAUDALSASTREAM pStreamALSA = (PDRVHSTAUDALSASTREAM)pStream;
 
     int rc = snd_pcm_drop(pStreamALSA->hPCM);
@@ -799,10 +800,10 @@
  * @ interface_method_impl{PDMIHOSTAUDIO,pfnStreamPause}
  */
-static DECLCALLBACK(int) drvHostAlsaAudioHA_StreamPause(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+static DECLCALLBACK(int) drvHstAudAlsaHA_StreamPause(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
 {
     /* Same as disable. */
     /** @todo r=bird: Try use pause and fallback on disable/enable if it isn't
      *        supported or doesn't work. */
-    return drvHostAlsaAudioHA_StreamDisable(pInterface, pStream);
+    return drvHstAudAlsaHA_StreamDisable(pInterface, pStream);
 }
 
@@ -811,8 +812,8 @@
  * @ interface_method_impl{PDMIHOSTAUDIO,pfnStreamResume}
  */
-static DECLCALLBACK(int) drvHostAlsaAudioHA_StreamResume(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+static DECLCALLBACK(int) drvHstAudAlsaHA_StreamResume(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
 {
     /* Same as enable. */
-    return drvHostAlsaAudioHA_StreamEnable(pInterface, pStream);
+    return drvHstAudAlsaHA_StreamEnable(pInterface, pStream);
 }
 
@@ -821,8 +822,8 @@
  * @ interface_method_impl{PDMIHOSTAUDIO,pfnStreamDrain}
  */
-static DECLCALLBACK(int) drvHostAlsaAudioHA_StreamDrain(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+static DECLCALLBACK(int) drvHstAudAlsaHA_StreamDrain(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
 {
     RT_NOREF(pInterface);
-    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
+    PDRVHSTAUDALSASTREAM pStreamALSA = (PDRVHSTAUDALSASTREAM)pStream;
 
     snd_pcm_state_t const enmState = snd_pcm_state(pStreamALSA->hPCM);
@@ -880,6 +881,6 @@
  * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
  */
-static DECLCALLBACK(int) drvHostAlsaAudioHA_StreamControl(PPDMIHOSTAUDIO pInterface,
-                                                          PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
+static DECLCALLBACK(int) drvHstAudAlsaHA_StreamControl(PPDMIHOSTAUDIO pInterface,
+                                                       PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
 {
     /** @todo r=bird: I'd like to get rid of this pfnStreamControl method,
@@ -890,13 +891,13 @@
     {
         case PDMAUDIOSTREAMCMD_ENABLE:
-            return drvHostAlsaAudioHA_StreamEnable(pInterface, pStream);
+            return drvHstAudAlsaHA_StreamEnable(pInterface, pStream);
         case PDMAUDIOSTREAMCMD_DISABLE:
-            return drvHostAlsaAudioHA_StreamDisable(pInterface, pStream);
+            return drvHstAudAlsaHA_StreamDisable(pInterface, pStream);
         case PDMAUDIOSTREAMCMD_PAUSE:
-            return drvHostAlsaAudioHA_StreamPause(pInterface, pStream);
+            return drvHstAudAlsaHA_StreamPause(pInterface, pStream);
         case PDMAUDIOSTREAMCMD_RESUME:
-            return drvHostAlsaAudioHA_StreamResume(pInterface, pStream);
+            return drvHstAudAlsaHA_StreamResume(pInterface, pStream);
         case PDMAUDIOSTREAMCMD_DRAIN:
-            return drvHostAlsaAudioHA_StreamDrain(pInterface, pStream);
+            return drvHstAudAlsaHA_StreamDrain(pInterface, pStream);
 
         case PDMAUDIOSTREAMCMD_END:
@@ -936,5 +937,5 @@
     if (cFramesAvail == -EPIPE)
     {
-        rc = alsaStreamRecover(hPCM);
+        rc = drvHstAudAlsaStreamRecover(hPCM);
         if (RT_SUCCESS(rc))
         {
@@ -964,8 +965,8 @@
  * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable}
  */
-static DECLCALLBACK(uint32_t) drvHostAlsaAudioHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+static DECLCALLBACK(uint32_t) drvHstAudAlsaHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
 {
     RT_NOREF(pInterface);
-    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
+    PDRVHSTAUDALSASTREAM pStreamALSA = (PDRVHSTAUDALSASTREAM)pStream;
 
     uint32_t          cbAvail      = 0;
@@ -982,8 +983,8 @@
  * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable}
  */
-static DECLCALLBACK(uint32_t) drvHostAlsaAudioHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+static DECLCALLBACK(uint32_t) drvHstAudAlsaHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
 {
     RT_NOREF(pInterface);
-    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
+    PDRVHSTAUDALSASTREAM pStreamALSA = (PDRVHSTAUDALSASTREAM)pStream;
 
     uint32_t          cbAvail      = 0;
@@ -1000,8 +1001,8 @@
  * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetPending}
  */
-static DECLCALLBACK(uint32_t) drvHostAlsaAudioHA_StreamGetPending(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
+static DECLCALLBACK(uint32_t) drvHstAudAlsaHA_StreamGetPending(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
 {
     RT_NOREF(pInterface);
-    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
+    PDRVHSTAUDALSASTREAM pStreamALSA = (PDRVHSTAUDALSASTREAM)pStream;
     AssertPtrReturn(pStreamALSA, 0);
 
@@ -1058,9 +1059,9 @@
  * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
  */
-static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHostAlsaAudioHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
-                                                                               PPDMAUDIOBACKENDSTREAM pStream)
+static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHstAudAlsaHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
+                                                                            PPDMAUDIOBACKENDSTREAM pStream)
 {
     RT_NOREF(pInterface);
-    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
+    PDRVHSTAUDALSASTREAM pStreamALSA = (PDRVHSTAUDALSASTREAM)pStream;
     AssertPtrReturn(pStreamALSA, PDMHOSTAUDIOSTREAMSTATE_INVALID);
 
@@ -1091,11 +1092,127 @@
 
 /**
+ * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
+ */
+static DECLCALLBACK(int) drvHstAudAlsaHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
+                                                    const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
+{
+    PDRVHSTAUDALSASTREAM pStreamALSA = (PDRVHSTAUDALSASTREAM)pStream;
+    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
+    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
+    AssertPtrReturn(pcbWritten, VERR_INVALID_POINTER);
+    Log4Func(("@%#RX64: pvBuf=%p cbBuf=%#x (%u) state=%s - %s\n", pStreamALSA->offInternal, pvBuf, cbBuf, cbBuf,
+              snd_pcm_state_name(snd_pcm_state(pStreamALSA->hPCM)), pStreamALSA->Cfg.szName));
+    if (cbBuf)
+        AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
+    else
+    {
+        /* Fend off draining calls. */
+        *pcbWritten = 0;
+        return VINF_SUCCESS;
+    }
+
+    /*
+     * Determine how much we can write (caller actually did this
+     * already, but we repeat it just to be sure or something).
+     */
+    snd_pcm_sframes_t cFramesAvail;
+    int rc = alsaStreamGetAvail(pStreamALSA->hPCM, &cFramesAvail);
+    if (RT_SUCCESS(rc))
+    {
+        Assert(cFramesAvail);
+        if (cFramesAvail)
+        {
+            PCPDMAUDIOPCMPROPS pProps    = &pStreamALSA->Cfg.Props;
+            uint32_t           cbToWrite = PDMAudioPropsFramesToBytes(pProps, (uint32_t)cFramesAvail);
+            if (cbToWrite)
+            {
+                if (cbToWrite > cbBuf)
+                    cbToWrite = cbBuf;
+
+                /*
+                 * Try write the data.
+                 */
+                uint32_t cFramesToWrite = PDMAudioPropsBytesToFrames(pProps, cbToWrite);
+                snd_pcm_sframes_t cFramesWritten = snd_pcm_writei(pStreamALSA->hPCM, pvBuf, cFramesToWrite);
+                if (cFramesWritten > 0)
+                {
+                    Log4Func(("snd_pcm_writei w/ cbToWrite=%u -> %ld (frames) [cFramesAvail=%ld]\n",
+                              cbToWrite, cFramesWritten, cFramesAvail));
+                    *pcbWritten = PDMAudioPropsFramesToBytes(pProps, cFramesWritten);
+                    pStreamALSA->offInternal += *pcbWritten;
+                    return VINF_SUCCESS;
+                }
+                LogFunc(("snd_pcm_writei w/ cbToWrite=%u -> %ld [cFramesAvail=%ld]\n", cbToWrite, cFramesWritten, cFramesAvail));
+
+
+                /*
+                 * There are a couple of error we can recover from, try to do so.
+                 * Only don't try too many times.
+                 */
+                for (unsigned iTry = 0;
+                     (cFramesWritten == -EPIPE || cFramesWritten == -ESTRPIPE) && iTry < ALSA_RECOVERY_TRIES_MAX;
+                     iTry++)
+                {
+                    if (cFramesWritten == -EPIPE)
+                    {
+                        /* Underrun occurred. */
+                        rc = drvHstAudAlsaStreamRecover(pStreamALSA->hPCM);
+                        if (RT_FAILURE(rc))
+                            break;
+                        LogFlowFunc(("Recovered from playback (iTry=%u)\n", iTry));
+                    }
+                    else
+                    {
+                        /* An suspended event occurred, needs resuming. */
+                        rc = drvHstAudAlsaStreamResume(pStreamALSA->hPCM);
+                        if (RT_FAILURE(rc))
+                        {
+                            LogRel(("ALSA: Failed to resume output stream (iTry=%u, rc=%Rrc)\n", iTry, rc));
+                            break;
+                        }
+                        LogFlowFunc(("Resumed suspended output stream (iTry=%u)\n", iTry));
+                    }
+
+                    cFramesWritten = snd_pcm_writei(pStreamALSA->hPCM, pvBuf, cFramesToWrite);
+                    if (cFramesWritten > 0)
+                    {
+                        Log4Func(("snd_pcm_writei w/ cbToWrite=%u -> %ld (frames) [cFramesAvail=%ld]\n",
+                                  cbToWrite, cFramesWritten, cFramesAvail));
+                        *pcbWritten = PDMAudioPropsFramesToBytes(pProps, cFramesWritten);
+                        pStreamALSA->offInternal += *pcbWritten;
+                        return VINF_SUCCESS;
+                    }
+                    LogFunc(("snd_pcm_writei w/ cbToWrite=%u -> %ld [cFramesAvail=%ld, iTry=%d]\n", cbToWrite, cFramesWritten, cFramesAvail, iTry));
+                }
+
+                /* Make sure we return with an error status. */
+                if (RT_SUCCESS_NP(rc))
+                {
+                    if (cFramesWritten == 0)
+                        rc = VERR_ACCESS_DENIED;
+                    else
+                    {
+                        rc = RTErrConvertFromErrno(-(int)cFramesWritten);
+                        LogFunc(("Failed to write %RU32 bytes: %ld (%Rrc)\n", cbToWrite, cFramesWritten, rc));
+                    }
+                }
+            }
+        }
+    }
+    else
+        LogFunc(("Error getting number of playback frames, rc=%Rrc\n", rc));
+    *pcbWritten = 0;
+    return rc;
+}
+
+
+/**
  * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
  */
-static DECLCALLBACK(int) drvHostAlsaAudioHA_StreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
-                                                          void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
+static DECLCALLBACK(int) drvHstAudAlsaHA_StreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
+                                                       void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
 {
     RT_NOREF_PV(pInterface);
-    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
+    PDRVHSTAUDALSASTREAM pStreamALSA = (PDRVHSTAUDALSASTREAM)pStream;
     AssertPtrReturn(pStreamALSA, VERR_INVALID_POINTER);
     AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
@@ -1124,5 +1241,5 @@
 
                 case SND_PCM_STATE_SUSPENDED:
-                    rc = alsaStreamResume(pStreamALSA->hPCM);
+                    rc = drvHstAudAlsaStreamResume(pStreamALSA->hPCM);
                     if (RT_SUCCESS(rc))
                     {
@@ -1190,5 +1307,5 @@
             if (cFramesRead == -EPIPE)
             {
-                rc = alsaStreamRecover(pStreamALSA->hPCM);
+                rc = drvHstAudAlsaStreamRecover(pStreamALSA->hPCM);
                 if (RT_SUCCESS(rc))
                 {
@@ -1224,127 +1341,12 @@
 }
 
-/**
- * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
- */
-static DECLCALLBACK(int) drvHostAlsaAudioHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
-                                                       const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
-{
-    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
-    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
-    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
-    AssertPtrReturn(pcbWritten, VERR_INVALID_POINTER);
-    Log4Func(("@%#RX64: pvBuf=%p cbBuf=%#x (%u) state=%s - %s\n", pStreamALSA->offInternal, pvBuf, cbBuf, cbBuf,
-              snd_pcm_state_name(snd_pcm_state(pStreamALSA->hPCM)), pStreamALSA->Cfg.szName));
-    if (cbBuf)
-        AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
-    else
-    {
-        /* Fend off draining calls. */
-        *pcbWritten = 0;
-        return VINF_SUCCESS;
-    }
-
-    /*
-     * Determine how much we can write (caller actually did this
-     * already, but we repeat it just to be sure or something).
-     */
-    snd_pcm_sframes_t cFramesAvail;
-    int rc = alsaStreamGetAvail(pStreamALSA->hPCM, &cFramesAvail);
-    if (RT_SUCCESS(rc))
-    {
-        Assert(cFramesAvail);
-        if (cFramesAvail)
-        {
-            PCPDMAUDIOPCMPROPS pProps    = &pStreamALSA->Cfg.Props;
-            uint32_t           cbToWrite = PDMAudioPropsFramesToBytes(pProps, (uint32_t)cFramesAvail);
-            if (cbToWrite)
-            {
-                if (cbToWrite > cbBuf)
-                    cbToWrite = cbBuf;
-
-                /*
-                 * Try write the data.
-                 */
-                uint32_t cFramesToWrite = PDMAudioPropsBytesToFrames(pProps, cbToWrite);
-                snd_pcm_sframes_t cFramesWritten = snd_pcm_writei(pStreamALSA->hPCM, pvBuf, cFramesToWrite);
-                if (cFramesWritten > 0)
-                {
-                    Log4Func(("snd_pcm_writei w/ cbToWrite=%u -> %ld (frames) [cFramesAvail=%ld]\n",
-                              cbToWrite, cFramesWritten, cFramesAvail));
-                    *pcbWritten = PDMAudioPropsFramesToBytes(pProps, cFramesWritten);
-                    pStreamALSA->offInternal += *pcbWritten;
-                    return VINF_SUCCESS;
-                }
-                LogFunc(("snd_pcm_writei w/ cbToWrite=%u -> %ld [cFramesAvail=%ld]\n", cbToWrite, cFramesWritten, cFramesAvail));
-
-
-                /*
-                 * There are a couple of error we can recover from, try to do so.
-                 * Only don't try too many times.
-                 */
-                for (unsigned iTry = 0;
-                     (cFramesWritten == -EPIPE || cFramesWritten == -ESTRPIPE) && iTry < ALSA_RECOVERY_TRIES_MAX;
-                     iTry++)
-                {
-                    if (cFramesWritten == -EPIPE)
-                    {
-                        /* Underrun occurred. */
-                        rc = alsaStreamRecover(pStreamALSA->hPCM);
-                        if (RT_FAILURE(rc))
-                            break;
-                        LogFlowFunc(("Recovered from playback (iTry=%u)\n", iTry));
-                    }
-                    else
-                    {
-                        /* An suspended event occurred, needs resuming. */
-                        rc = alsaStreamResume(pStreamALSA->hPCM);
-                        if (RT_FAILURE(rc))
-                        {
-                            LogRel(("ALSA: Failed to resume output stream (iTry=%u, rc=%Rrc)\n", iTry, rc));
-                            break;
-                        }
-                        LogFlowFunc(("Resumed suspended output stream (iTry=%u)\n", iTry));
-                    }
-
-                    cFramesWritten = snd_pcm_writei(pStreamALSA->hPCM, pvBuf, cFramesToWrite);
-                    if (cFramesWritten > 0)
-                    {
-                        Log4Func(("snd_pcm_writei w/ cbToWrite=%u -> %ld (frames) [cFramesAvail=%ld]\n",
-                                  cbToWrite, cFramesWritten, cFramesAvail));
-                        *pcbWritten = PDMAudioPropsFramesToBytes(pProps, cFramesWritten);
-                        pStreamALSA->offInternal += *pcbWritten;
-                        return VINF_SUCCESS;
-                    }
-                    LogFunc(("snd_pcm_writei w/ cbToWrite=%u -> %ld [cFramesAvail=%ld, iTry=%d]\n", cbToWrite, cFramesWritten, cFramesAvail, iTry));
-                }
-
-                /* Make sure we return with an error status. */
-                if (RT_SUCCESS_NP(rc))
-                {
-                    if (cFramesWritten == 0)
-                        rc = VERR_ACCESS_DENIED;
-                    else
-                    {
-                        rc = RTErrConvertFromErrno(-(int)cFramesWritten);
-                        LogFunc(("Failed to write %RU32 bytes: %ld (%Rrc)\n", cbToWrite, cFramesWritten, rc));
-                    }
-                }
-            }
-        }
-    }
-    else
-        LogFunc(("Error getting number of playback frames, rc=%Rrc\n", rc));
-    *pcbWritten = 0;
-    return rc;
-}
-
 
 /**
  * @interface_method_impl{PDMIBASE,pfnQueryInterface}
  */
-static DECLCALLBACK(void *) drvHostAlsaAudioQueryInterface(PPDMIBASE pInterface, const char *pszIID)
-{
-    PPDMDRVINS        pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
-    PDRVHOSTALSAAUDIO pThis   = PDMINS_2_DATA(pDrvIns, PDRVHOSTALSAAUDIO);
+static DECLCALLBACK(void *) drvHstAudAlsaQueryInterface(PPDMIBASE pInterface, const char *pszIID)
+{
+    PPDMDRVINS     pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
+    PDRVHSTAUDALSA pThis   = PDMINS_2_DATA(pDrvIns, PDRVHSTAUDALSA);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, &pThis->IHostAudio);
@@ -1359,9 +1361,9 @@
  * @copydoc FNPDMDRVCONSTRUCT
  */
-static DECLCALLBACK(int) drvHostAlsaAudioConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
+static DECLCALLBACK(int) drvHstAudAlsaConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
 {
     RT_NOREF(fFlags);
     PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
-    PDRVHOSTALSAAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTALSAAUDIO);
+    PDRVHSTAUDALSA pThis = PDMINS_2_DATA(pDrvIns, PDRVHSTAUDALSA);
     LogRel(("Audio: Initializing ALSA driver\n"));
 
@@ -1371,23 +1373,23 @@
     pThis->pDrvIns                   = pDrvIns;
     /* IBase */
-    pDrvIns->IBase.pfnQueryInterface = drvHostAlsaAudioQueryInterface;
+    pDrvIns->IBase.pfnQueryInterface = drvHstAudAlsaQueryInterface;
     /* IHostAudio */
-    pThis->IHostAudio.pfnGetConfig                  = drvHostAlsaAudioHA_GetConfig;
-    pThis->IHostAudio.pfnGetDevices                 = drvHostAlsaAudioHA_GetDevices;
+    pThis->IHostAudio.pfnGetConfig                  = drvHstAudAlsaHA_GetConfig;
+    pThis->IHostAudio.pfnGetDevices                 = drvHstAudAlsaHA_GetDevices;
     pThis->IHostAudio.pfnSetDevice                  = NULL;
-    pThis->IHostAudio.pfnGetStatus                  = drvHostAlsaAudioHA_GetStatus;
+    pThis->IHostAudio.pfnGetStatus                  = drvHstAudAlsaHA_GetStatus;
     pThis->IHostAudio.pfnDoOnWorkerThread           = NULL;
     pThis->IHostAudio.pfnStreamConfigHint           = NULL;
-    pThis->IHostAudio.pfnStreamCreate               = drvHostAlsaAudioHA_StreamCreate;
+    pThis->IHostAudio.pfnStreamCreate               = drvHstAudAlsaHA_StreamCreate;
     pThis->IHostAudio.pfnStreamInitAsync            = NULL;
-    pThis->IHostAudio.pfnStreamDestroy              = drvHostAlsaAudioHA_StreamDestroy;
+    pThis->IHostAudio.pfnStreamDestroy              = drvHstAudAlsaHA_StreamDestroy;
     pThis->IHostAudio.pfnStreamNotifyDeviceChanged  = NULL;
-    pThis->IHostAudio.pfnStreamControl              = drvHostAlsaAudioHA_StreamControl;
-    pThis->IHostAudio.pfnStreamGetReadable          = drvHostAlsaAudioHA_StreamGetReadable;
-    pThis->IHostAudio.pfnStreamGetWritable          = drvHostAlsaAudioHA_StreamGetWritable;
-    pThis->IHostAudio.pfnStreamGetPending           = drvHostAlsaAudioHA_StreamGetPending;
-    pThis->IHostAudio.pfnStreamGetState             = drvHostAlsaAudioHA_StreamGetState;
-    pThis->IHostAudio.pfnStreamPlay                 = drvHostAlsaAudioHA_StreamPlay;
-    pThis->IHostAudio.pfnStreamCapture              = drvHostAlsaAudioHA_StreamCapture;
+    pThis->IHostAudio.pfnStreamControl              = drvHstAudAlsaHA_StreamControl;
+    pThis->IHostAudio.pfnStreamGetReadable          = drvHstAudAlsaHA_StreamGetReadable;
+    pThis->IHostAudio.pfnStreamGetWritable          = drvHstAudAlsaHA_StreamGetWritable;
+    pThis->IHostAudio.pfnStreamGetPending           = drvHstAudAlsaHA_StreamGetPending;
+    pThis->IHostAudio.pfnStreamGetState             = drvHstAudAlsaHA_StreamGetState;
+    pThis->IHostAudio.pfnStreamPlay                 = drvHstAudAlsaHA_StreamPlay;
+    pThis->IHostAudio.pfnStreamCapture              = drvHstAudAlsaHA_StreamCapture;
 
     /*
@@ -1411,5 +1413,5 @@
     }
 #ifdef DEBUG
-    snd_lib_error_set_handler(alsaDbgErrorHandler);
+    snd_lib_error_set_handler(drvHstAudAlsaDbgErrorHandler);
 #endif
     return VINF_SUCCESS;
@@ -1439,7 +1441,7 @@
     ~0U,
     /* cbInstance */
-    sizeof(DRVHOSTALSAAUDIO),
+    sizeof(DRVHSTAUDALSA),
     /* pfnConstruct */
-    drvHostAlsaAudioConstruct,
+    drvHstAudAlsaConstruct,
     /* pfnDestruct */
     NULL,
