Index: /trunk/Config.kmk
===================================================================
--- /trunk/Config.kmk	(revision 50685)
+++ /trunk/Config.kmk	(revision 50686)
@@ -409,4 +409,6 @@
 # Enable PCI passthrough support.
 VBOX_WITH_PCI_PASSTHROUGH = 1
+# Enable PDM based audio driver
+VBOX_WITH_PDM_AUDIO_DRIVER  =
 # Enable statically linked dbus support.
 if1of ($(KBUILD_TARGET), linux solaris)
Index: /trunk/include/VBox/vmm/pdmifs.h
===================================================================
--- /trunk/include/VBox/vmm/pdmifs.h	(revision 50685)
+++ /trunk/include/VBox/vmm/pdmifs.h	(revision 50686)
@@ -2533,4 +2533,5 @@
 
 
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
 /** Pointer to a network connector interface */
 typedef struct PDMIAUDIOCONNECTOR *PPDMIAUDIOCONNECTOR;
@@ -2550,4 +2551,5 @@
 
 
+#endif
 /** @todo r=bird: the two following interfaces are hacks to work around the missing audio driver
  * interface. This should be addressed rather than making more temporary hacks. */
Index: /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 50685)
+++ /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 50686)
@@ -21,4 +21,7 @@
 #define LOG_GROUP LOG_GROUP_DEV_AUDIO
 #include <VBox/vmm/pdmdev.h>
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+#include <VBox/vmm/pdmaudioifs.h>
+#endif
 #include <iprt/assert.h>
 #include <iprt/uuid.h>
@@ -26,8 +29,9 @@
 
 #include "VBoxDD.h"
-
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
 extern "C" {
 #include "audio.h"
 }
+#endif
 
 
@@ -194,6 +198,7 @@
 
     /** Audio stuff.  */
-    QEMUSoundCard           card;
-
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
+    QEMUSoundCard card;
+#endif
     /** Global Control (Bus Master Control Register) */
     uint32_t                glob_cnt;
@@ -206,4 +211,12 @@
     AC97BusMasterRegs       bm_regs[3];
     uint8_t                 mixer_data[256];
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    /** PCM in */
+    PPDMGSTVOICEIN          voice_pi[2];
+    /** PCM out */
+    PPDMGSTVOICEOUT         voice_po[2];
+    /** Mic in */
+    PPDMGSTVOICEIN          voice_mc[2];
+#else
     /** PCM in */
     SWVoiceIn              *voice_pi;
@@ -212,4 +225,5 @@
     /** Mic in */
     SWVoiceIn              *voice_mc;
+#endif
     uint8_t                 silence[128];
     int                     bup_flag;
@@ -217,5 +231,9 @@
     PPDMDEVINSR3            pDevIns;
     /** Pointer to the connector of the attached audio driver. */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    PPDMIAUDIOCONNECTOR     pDrv[2];
+#else
     PPDMIAUDIOCONNECTOR     pDrv;
+#endif
     /** Pointer to the attached audio driver. */
     PPDMIBASE               pDrvBase;
@@ -355,7 +373,23 @@
     switch (bm_index)
     {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        uint32_t lun;
+        case PI_INDEX:
+            for (lun = 0; lun < 2; lun++)
+                pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->voice_pi[lun], on);
+            break;
+        case PO_INDEX:
+            for (lun = 0; lun < 2; lun++)
+                pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->voice_po[lun], on);
+        break;
+        case MC_INDEX:
+            for (lun = 0; lun < 2; lun++)
+                pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->voice_mc[lun], on);
+            break;
+#else
         case PI_INDEX: AUD_set_active_in( pThis->voice_pi, on); break;
         case PO_INDEX: AUD_set_active_out(pThis->voice_po, on); break;
         case MC_INDEX: AUD_set_active_in( pThis->voice_mc, on); break;
+#endif
         default:       AssertFailed (); break;
     }
@@ -374,5 +408,4 @@
     pReg->cr       = pReg->cr & CR_DONT_CLEAR_MASK;
     pReg->bd_valid = 0;
-
     voice_set_active(pThis, pReg - pThis->bm_regs, 0);
     memset(pThis->silence, 0, sizeof(pThis->silence));
@@ -408,17 +441,28 @@
 static void open_voice(PAC97STATE pThis, int index, int freq)
 {
-    audsettings_t as;
-
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    int rc;
+#endif
+    LogFlow(("DevIchAC97: open_voice freq = %d\n", freq));
     if (freq)
     {
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
+        audsettings_t as;
         as.freq       = freq;
         as.nchannels  = 2;
         as.fmt        = AUD_FMT_S16;
         as.endianness = 0;
-
+        uint32_t lun;
+#endif
         switch (index)
         {
             case PI_INDEX: /* PCM in */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                for (uint32_t lun = 0; lun < 2; lun++)
+                    rc = pThis->pDrv[lun]->pfnOpenIn(pThis->pDrv[lun], &pThis->voice_pi[lun], "ac97.pi",
+                                                     pThis, pi_callback, freq, 2, AUD_FMT_S16, 0);
+#else
                 pThis->voice_pi = AUD_open_in(&pThis->card, pThis->voice_pi, "ac97.pi", pThis, pi_callback, &as);
+#endif
 #ifdef LOG_VOICES
                 LogRel(("AC97: open PI freq=%d (%s)\n", freq, pThis->voice_pi ? "ok" : "FAIL"));
@@ -427,5 +471,14 @@
 
             case PO_INDEX: /* PCM out */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                for (int lun = 0; lun < 2; lun++)
+                {
+                    LogFlow(("LUN###%d\n", lun));
+                    rc = pThis->pDrv[lun]->pfnOpenOut(pThis->pDrv[lun], &pThis->voice_po[lun], "ac97.po",
+                                                      pThis, po_callback, freq, 2, AUD_FMT_S16, 0);
+                }
+#else
                 pThis->voice_po = AUD_open_out(&pThis->card, pThis->voice_po, "ac97.po", pThis, po_callback, &as);
+#endif
 #ifdef LOG_VOICES
                 LogRel(("AC97: open PO freq=%d (%s)\n", freq, pThis->voice_po ? "ok" : "FAIL"));
@@ -434,5 +487,11 @@
 
             case MC_INDEX: /* Mic in */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                for (uint32_t lun = 0; lun < 2; lun++)
+                    rc = pThis->pDrv[lun]->pfnOpenIn(pThis->pDrv[lun], &pThis->voice_mc[lun], "ac97.mc",
+                                                     pThis, mc_callback, freq, 2, AUD_FMT_S16, 0);
+#else
                 pThis->voice_mc = AUD_open_in(&pThis->card, pThis->voice_mc, "ac97.mc", pThis, mc_callback, &as);
+#endif
 #ifdef LOG_VOICES
                 LogRel(("AC97: open MC freq=%d (%s)\n", freq, pThis->voice_mc ? "ok" : "FAIL"));
@@ -446,25 +505,49 @@
         {
             case PI_INDEX:
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                for (uint32_t lun = 0; lun < 2; lun++)
+                {
+                    pThis->pDrv[lun]->pfnCloseIn(pThis->pDrv[lun], pThis->voice_pi[lun]);
+                    pThis->voice_pi[lun] = NULL;
+                }
+#else
                 AUD_close_in(&pThis->card, pThis->voice_pi);
+                pThis->voice_pi = NULL;
+#endif
 #ifdef LOG_VOICES
                 LogRel(("AC97: Closing PCM IN\n"));
 #endif
-                pThis->voice_pi = NULL;
                 break;
 
             case PO_INDEX:
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                for (uint32_t lun = 0; lun < 2; lun++)
+                {
+                    pThis->pDrv[lun]->pfnCloseOut(pThis->pDrv[lun], pThis->voice_po[lun]);
+                    pThis->voice_po[lun] = NULL;
+                }
+#else
                 AUD_close_out(&pThis->card, pThis->voice_po);
+                pThis->voice_po = NULL;
+#endif
 #ifdef LOG_VOICES
                 LogRel(("AC97: Closing PCM OUT\n"));
 #endif
-                pThis->voice_po = NULL;
                 break;
 
             case MC_INDEX:
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                for (uint32_t lun = 0; lun < 2; lun++)
+                {
+                    pThis->pDrv[lun]->pfnCloseIn(pThis->pDrv[lun], pThis->voice_mc[lun]);
+                    pThis->voice_mc[lun] = NULL;
+                }
+#else
                 AUD_close_in(&pThis->card, pThis->voice_mc);
+                pThis->voice_mc = NULL;
+#endif
 #ifdef LOG_VOICES
                 LogRel(("AC97: Closing MIC IN\n"));
 #endif
-                pThis->voice_mc = NULL;
                 break;
         }
@@ -478,13 +561,28 @@
     freq = mixer_load(pThis, AC97_PCM_LR_ADC_Rate);
     open_voice(pThis, PI_INDEX, freq);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    for (uint32_t lun = 0; lun < 2; lun++)
+        pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->voice_pi[lun], active[PI_INDEX]);
+#else
     AUD_set_active_in(pThis->voice_pi, active[PI_INDEX]);
-
+#endif
     freq = mixer_load(pThis, AC97_PCM_Front_DAC_Rate);
+    LogFlow(("DevIchAC97: reset_voices calling open_voice freq = %d\n", freq));
     open_voice(pThis, PO_INDEX, freq);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    for (uint32_t lun = 0; lun < 2; lun++)
+        pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->voice_po[lun], active[PO_INDEX]);
+#else
     AUD_set_active_out(pThis->voice_po, active[PO_INDEX]);
+#endif
 
     freq = mixer_load(pThis, AC97_MIC_ADC_Rate);
     open_voice(pThis, MC_INDEX, freq);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    for (uint32_t lun = 0; lun < 2; lun++)
+        pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->voice_mc[lun], active[MC_INDEX]);
+#else
     AUD_set_active_in(pThis->voice_mc, active[MC_INDEX]);
+#endif
 }
 
@@ -501,9 +599,29 @@
 # ifdef SOFT_VOLUME
     if (index == AC97_Master_Volume_Mute)
+    {
+#  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    for (uint32_t lun = 0; lun < 1; lun++)
+        pThis->pDrv[lun]->pfnIsSetOutVolume(pThis->pDrv[lun], pThis->voice_po[lun], mute, lvol, rvol);
+#  else
         AUD_set_volume_out(pThis->voice_po, mute, lvol, rvol);
+#  endif
+    }
     else
+    {
+#  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        for (uint32_t lun = 0; lun < 1; lun++)
+            /* @tod0 in SetVolume no passing audmixerctl_in as its not used in DrvAudio.c */
+            pThis->pDrv[lun]->pfnSetVolume(pThis->pDrv[lun], &mute, &lvol, &rvol);
+#  else
         AUD_set_volume(mt, &mute, &lvol, &rvol);
+#  endif
+    }
 # else
+#  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    for (uint32_t lun = 0; lun < 1; lun++)
+        pThis->pDrv[lun]->pfnSetVolume(pThis->pDrv[lun], &mute, &lvol, &rvol);
+#  else
     AUD_set_volume(mt, &mute, &lvol, &rvol);
+#  endif
 # endif
 
@@ -565,5 +683,5 @@
     audrecsource_t ars = ac97_to_aud_record_source(rs);
     audrecsource_t als = ac97_to_aud_record_source(ls);
-    AUD_set_record_source(&als, &ars);
+    //AUD_set_record_source(&als, &ars);
     rs = aud_to_ac97_record_source(ars);
     ls = aud_to_ac97_record_source(als);
@@ -607,4 +725,6 @@
     mixer_store(pThis, AC97_MIC_ADC_Rate            , 0xbb80);
 
+
+
 #ifdef USE_MIXER
     record_select(pThis, 0);
@@ -630,4 +750,13 @@
     uint32_t    written = 0;
     int         to_copy = 0;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    /* count of bytes left in buf to read = samples left in buffer (each of 16 bit) to read denoted by picb * 2) */
+    uint32_t    cbToRead = pReg->picb << 1;
+    uint32_t    cbMinToRead;
+    uint8_t     tmpbufCopy[4096];
+    int    lun = 0;
+    uint32_t    slowestLun;
+    uint32_t    cSamplesLeft;
+#endif
 
     temp = audio_MIN(temp, (uint32_t)max);
@@ -643,6 +772,18 @@
         to_copy = audio_MIN(temp, sizeof(tmpbuf));
         PDMDevHlpPhysRead(pDevIns, addr, tmpbuf, to_copy);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        /* save a copy of the audio samples read */
+        memcpy(tmpbufCopy, tmpbuf, to_copy);
+        uint32_t slowlun = 0;
+        for (lun = 0; lun < 2; lun++)
+        {
+            LogFlow(("DevIchAC97: write_audio to_copy = %d LUN##%d\n", to_copy, lun));
+            copied = pThis->pDrv[lun]->pfnWrite(pThis->pDrv[lun], pThis->voice_po[lun], tmpbuf, to_copy);
+            /* call pfnwrite with the same data that has been read from the guest physical memory */
+            LogFlow(("DevIchAC97: write_audio copied = %d\n", copied));
+        }
+#else
         copied = AUD_write(pThis->voice_po, tmpbuf, to_copy);
-        Log(("ac97: write_audio max=%x to_copy=%x copied=%x\n", max, to_copy, copied));
+#endif
         if (!copied)
         {
@@ -673,5 +814,4 @@
 {
     int written = 0;
-
     Log(("ac97: write_bup\n"));
     if (!(pThis->bup_flag & BUP_SET))
@@ -693,7 +833,17 @@
     {
         unsigned int temp = audio_MIN((unsigned int)elapsed, sizeof(pThis->silence));
+        int copied;
         while (temp)
         {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            for (int lun = 0; lun < 2; lun++)
+            {
+                LogFlow(("DevIchAC97: write_silence LUN##%d , to_copy=%d\n", lun, temp));
+                copied = pThis->pDrv[lun]->pfnWrite(pThis->pDrv[lun], pThis->voice_po[lun], pThis->silence, temp);
+                LogFlow(("DevIchAC97: write_silence LUN##%d , copied=%d\n", lun, copied));
+            }
+#else
             int copied = AUD_write(pThis->voice_po, pThis->silence, temp);
+#endif
             if (!copied)
                 return;
@@ -708,10 +858,34 @@
 {
     PPDMDEVINS  pDevIns = ICHAC97STATE_2_DEVINS(pThis);
-    uint8_t     tmpbuf[4096];
+
     uint32_t    addr = pReg->bd.addr;
     uint32_t    temp = pReg->picb << 1;
     uint32_t    nread = 0;
     int         to_copy = 0;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    uint8_t     u8DupBuf[4096];
+    PDMHOSTSTEREOSAMPLE     tmpbuf[4096];
+    PDMHOSTSTEREOSAMPLE MixBuf[2000];
+    PDMHOSTSTEREOSAMPLE InputBuf[2000];
+    PPDMHOSTSTEREOSAMPLE SrcBuf;
+    uint32_t    cSamplesMixed = 0;
+    uint32_t    cTotalSamplesMixed = 0;
+    uint32_t    cSamplesRead = 0;
+    uint32_t    offRead = 0;
+    uint32_t    offWrite = 0;
+    uint32_t    cTotalSamplesRead = 0;
+    uint32_t isamp = 0, osamp = 0;
+    uint32_t lun =0;
+    PPDMGSTVOICEIN voice[2];
+    memset(MixBuf, 0, sizeof(MixBuf));
+    memset(InputBuf, 0, sizeof(InputBuf));
+    memset(u8DupBuf, 0, sizeof(u8DupBuf));
+    void * rate[2];
+
+    for (lun = 0; lun < 2; lun++)
+        voice[lun] = (pReg - pThis->bm_regs) == MC_INDEX ? pThis->voice_mc[lun] : pThis->voice_pi[lun];
+#else
     SWVoiceIn  *voice = (pReg - pThis->bm_regs) == MC_INDEX ? pThis->voice_mc : pThis->voice_pi;
+#endif
 
     temp = audio_MIN(temp, (uint32_t)max);
@@ -722,4 +896,68 @@
     }
 
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    rate[0] = pThis->pDrv[0]->pfnPrepareAudioConversion(pThis->pDrv[0], 48000, 48000);
+    //rate[1] = pThis->pDrv[1]->pfnPrepareAudioConversion(pThis->pDrv[1], 22100, 22100);
+    rate[1] = pThis->pDrv[1]->pfnPrepareAudioConversion(pThis->pDrv[1], 48000, 48000);
+    for (lun = 0; lun < 2; lun++)
+    {
+        temp = pReg->picb << 1;
+        temp = audio_MIN(temp, (uint32_t)max);
+        LogFlow(("DevIchAC97: temp = %d and max = %d\n", temp, max));
+        if (!temp)
+        {
+            *stop = 1;
+            return 0;
+        }
+        memset(tmpbuf, 0, sizeof(tmpbuf));
+        offRead = 0;
+        offWrite = 0;
+        cSamplesMixed = 0;
+        nread = 0;
+        while (temp)
+        {
+            int acquired;
+            to_copy = audio_MIN(temp, sizeof(tmpbuf));
+            acquired = pThis->pDrv[lun]->pfnRead(pThis->pDrv[lun], voice[lun], tmpbuf, to_copy);
+            cSamplesRead = acquired >> voice[lun]->Props.cShift;
+            while (cSamplesRead)
+            {
+                SrcBuf = tmpbuf + offRead;
+                isamp = cSamplesRead;
+                if (!isamp)
+                {
+                    LogFlow(("DevichAC97: No Input samples \n"));
+                    break;
+                }
+                osamp = cSamplesRead - cSamplesMixed; /*sizeof(MixBuf)*/;
+                pThis->pDrv[lun]->pfnDoRateConvAndMix(pThis->pDrv[lun], rate[lun], SrcBuf,
+                                                    MixBuf, &isamp, &osamp);
+                cSamplesRead -= isamp;
+                offRead += isamp;
+                offWrite += osamp;
+                cSamplesMixed += isamp;
+            }
+            if (!acquired)
+            {
+                *stop = 1;
+                break;
+            }
+            pThis->pDrv[lun]->pfnConvStSampleToDevFmt(pThis->pDrv[lun], u8DupBuf, MixBuf, cSamplesMixed);
+            temp  -= acquired;
+            //addr  += acquired;
+            //addr  += (ctotalSamplexMixed << voice->Props.cShift);
+            //nread += (cSamplesMixed << voice->Props.cShift);
+            nread += acquired;
+            LogFlow(("DevIchAC97: looping temp = %d\n", temp));
+            cTotalSamplesRead = audio_MAX(cTotalSamplesRead, nread);
+            cTotalSamplesMixed = audio_MAX(cTotalSamplesMixed, cSamplesMixed);
+        }
+    }
+    if (cTotalSamplesMixed)
+        PDMDevHlpPCIPhysWrite(pDevIns, addr, u8DupBuf, (cTotalSamplesMixed << voice[0]->Props.cShift));
+    addr  += (cTotalSamplesMixed << voice[0]->Props.cShift);
+    nread = cTotalSamplesRead;
+#else
+    uint8_t tmpbuf[4096];
     while (temp)
     {
@@ -737,5 +975,5 @@
         nread += acquired;
     }
-
+#endif
     pReg->bd.addr = addr;
     return nread;
@@ -806,5 +1044,4 @@
                 break;
         }
-
         Log(("pReg->picb = %d\n", pReg->picb));
 
@@ -814,5 +1051,7 @@
 
             if (pReg->bd.ctl_len & BD_IOC)
+            {
                 new_sr |= SR_BCIS;
+            }
 
             if (pReg->civ == pReg->lvi)
@@ -1262,5 +1501,5 @@
                     {
                         mixer_store(pThis, AC97_MIC_ADC_Rate, 0xbb80);
-                        open_voice(pThis, MC_INDEX, 48000);
+                         open_voice(pThis, MC_INDEX, 48000);
                     }
                     Log(("ac97: Setting extended audio control to %#x\n", u32));
@@ -1378,7 +1617,14 @@
 
     uint8_t active[LAST_INDEX];
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    /* writing only host backend values here and ignoring for webm and VRDE */
+    active[PI_INDEX] = pThis->pDrv[0]->pfnIsActiveIn(pThis->pDrv[0],  pThis->voice_pi[0]) ? 1 : 0;
+    active[PO_INDEX] = pThis->pDrv[0]->pfnIsActiveOut(pThis->pDrv[0], pThis->voice_po[0]) ? 1 : 0;
+    active[MC_INDEX] = pThis->pDrv[0]->pfnIsActiveIn(pThis->pDrv[0],  pThis->voice_mc[0]) ? 1 : 0;
+#else
     active[PI_INDEX] = AUD_is_active_in( pThis->voice_pi) ? 1 : 0;
     active[PO_INDEX] = AUD_is_active_out(pThis->voice_po) ? 1 : 0;
     active[MC_INDEX] = AUD_is_active_in( pThis->voice_mc) ? 1 : 0;
+#endif
     SSMR3PutMem(pSSM, active, sizeof(active));
 
@@ -1543,4 +1789,24 @@
      * Attach driver.
      */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    for (uint32_t lun = 0; lun < 2; lun++)
+    {
+        rc = PDMDevHlpDriverAttach(pDevIns, lun, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port");
+        if (RT_SUCCESS(rc))
+        {
+            pThis->pDrv[lun] = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
+            AssertMsgReturn(pThis->pDrv[lun],
+                            ("Configuration error: instance %d has no host audio interface!\n", iInstance),
+                            VERR_PDM_MISSING_INTERFACE);
+        }
+        else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
+            Log(("ac97: No attached driver!\n"));
+        else if (RT_FAILURE(rc))
+        {
+            AssertMsgFailed(("Failed to attach AC97 LUN #%d! rc=%Rrc\n", lun, rc));
+            return rc;
+        }
+    }
+#else
     rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port");
     if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
@@ -1551,9 +1817,25 @@
         return rc;
     }
-
+#endif
+
+
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    pThis->pDrv[0]->pfnRegisterCard(pThis->pDrv[0], "ICH0" );
+#else
     AUD_register_card("ICH0", &pThis->card);
-
+#endif
     ac97Reset(pDevIns);
 
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    for (uint32_t lun =0; lun < 2; lun++)
+    {
+        if (!pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_pi[lun]))
+            LogRel(("AC97: WARNING: Unable to open PCM IN!\n"));
+        if (!pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_mc[lun]))
+            LogRel(("AC97: WARNING: Unable to open PCM MC!\n"));
+        if (!pThis->pDrv[lun]->pfnIsHostVoiceOutOK(pThis->pDrv[lun], pThis->voice_po[lun]))
+            LogRel(("AC97: WARNING: Unable to open PCM OUT!\n"));
+    }
+#else
     if (!AUD_is_host_voice_in_ok(pThis->voice_pi))
         LogRel(("AC97: WARNING: Unable to open PCM IN!\n"));
@@ -1563,12 +1845,58 @@
         LogRel(("AC97: WARNING: Unable to open PCM OUT!\n"));
 
+#endif
+
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    for (uint32_t lun = 0; lun < 2; lun++)
+    {
+        if (   !pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_pi[lun])
+            && !pThis->pDrv[lun]->pfnIsHostVoiceOutOK(pThis->pDrv[lun], pThis->voice_po[lun])
+            && !pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_mc[lun]))
+        {
+        /* Was not able initialize *any* voice. Select the NULL audio driver instead */
+            pThis->pDrv[lun]->pfnCloseIn(pThis->pDrv[lun], pThis->voice_pi[lun]);
+            pThis->pDrv[lun]->pfnCloseOut(pThis->pDrv[lun], pThis->voice_po[lun]);
+            pThis->pDrv[lun]->pfnCloseIn(pThis->pDrv[lun], pThis->voice_mc[lun]);
+
+            pThis->voice_po[lun] = NULL;
+            pThis->voice_pi[lun] = NULL;
+            pThis->voice_mc[lun] = NULL;
+
+            pThis->pDrv[lun]->pfnInitNull(pThis->pDrv[lun]);
+            ac97Reset(pDevIns);
+
+            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
+                N_("No audio devices could be opened. Selecting the NULL audio backend "
+                   "with the consequence that no sound is audible"));
+        }
+        else if (   !pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_pi[lun])
+                 || !pThis->pDrv[lun]->pfnIsHostVoiceOutOK(pThis->pDrv[lun], pThis->voice_po[lun])
+                 || !pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_mc[lun]))
+        {
+            char   szMissingVoices[128];
+            size_t len = 0;
+            if (!pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_pi[lun]))
+                len = RTStrPrintf(szMissingVoices, sizeof(szMissingVoices), "PCM_in");
+            if (!pThis->pDrv[lun]->pfnIsHostVoiceOutOK(pThis->pDrv[lun], pThis->voice_po[lun]))
+                len += RTStrPrintf(szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_out" : "PCM_out");
+            if (!pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_mc[lun]))
+                len += RTStrPrintf(szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_mic" : "PCM_mic");
+
+            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
+                N_("Some audio devices (%s) could not be opened. Guest applications generating audio "
+                "output or depending on audio input may hang. Make sure your host audio device "
+                "is working properly. Check the logfile for error messages of the audio "
+                "subsystem"), szMissingVoices);
+        }
+    }
+#else
     if (   !AUD_is_host_voice_in_ok( pThis->voice_pi)
         && !AUD_is_host_voice_out_ok(pThis->voice_po)
         && !AUD_is_host_voice_in_ok( pThis->voice_mc))
     {
-        /* Was not able initialize *any* voice. Select the NULL audio driver instead */
-        AUD_close_in( &pThis->card, pThis->voice_pi);
+        AUD_close_in(&pThis->card, pThis->voice_pi);
         AUD_close_out(&pThis->card, pThis->voice_po);
-        AUD_close_in( &pThis->card, pThis->voice_mc);
+        AUD_close_in(&pThis->card, pThis->voice_mc);
+
         pThis->voice_po = NULL;
         pThis->voice_pi = NULL;
@@ -1600,5 +1928,5 @@
                "subsystem"), szMissingVoices);
     }
-
+#endif
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/Devices/Audio/DevIchHda.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchHda.cpp	(revision 50685)
+++ /trunk/src/VBox/Devices/Audio/DevIchHda.cpp	(revision 50686)
@@ -25,4 +25,7 @@
 #define LOG_GROUP LOG_GROUP_DEV_AUDIO
 #include <VBox/vmm/pdmdev.h>
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+#include <VBox/vmm/pdmaudioifs.h>
+#endif
 #include <VBox/version.h>
 
@@ -38,7 +41,9 @@
 #include "VBoxDD.h"
 
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
 extern "C" {
 #include "audio.h"
 }
+#endif
 #include "DevIchHdaCodec.h"
 
@@ -547,5 +552,9 @@
 
     /** Pointer to the connector of the attached audio driver. */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pDrv[2];
+#else
     R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pDrv;
+#endif
     /** Pointer to the attached audio driver. */
     R3PTRTYPE(PPDMIBASE)               pDrvBase;
@@ -577,6 +586,10 @@
     /** Flag whether the RC part is enabled. */
     bool                               fRCEnabled;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     /** The HDA codec state. */
+    R3PTRTYPE(PHDACODEC)               pCodec[2];
+#else
     R3PTRTYPE(PHDACODEC)               pCodec;
+#endif
     uint64_t                           u64BaseTS;
     /** 1.2.3.4.5.6.7. - someone please tell me what I'm counting! - .8.9.10... */
@@ -1108,5 +1121,10 @@
         corbRp++;
         cmd = pThis->pu32CorbBuf[corbRp];
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        for (uint32_t lun = 0; lun < 1; lun++)
+            rc = pThis->pCodec[lun]->pfnLookup(pThis->pCodec[lun], cmd, &pfn);
+#else
         rc = pThis->pCodec->pfnLookup(pThis->pCodec, cmd, &pfn);
+#endif
         if (RT_FAILURE(rc))
             AssertRCReturn(rc, rc);
@@ -1115,5 +1133,12 @@
 
         if (RT_LIKELY(pfn))
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        {
+            for (uint32_t lun = 0; lun < 1; lun++)
+                rc = pfn(pThis->pCodec[lun], cmd, &resp);
+        }
+#else
             rc = pfn(pThis->pCodec, cmd, &resp);
+#endif
         else
             rc = VERR_INVALID_FUNCTION;
@@ -1433,8 +1458,18 @@
             {
                 case HDA_REG_SD0CTL:
+ #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                    for (uint32_t lun = 0; lun < 1; lun++)
+                        pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceIn, fRun);
+ #else
                     AUD_set_active_in(pThis->pCodec->SwVoiceIn, fRun);
+ #endif
                     break;
                 case HDA_REG_SD4CTL:
+ #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                    for (uint32_t lun = 0; lun < 1; lun++)
+                        pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceOut, fRun);
+ #else
                     AUD_set_active_out(pThis->pCodec->SwVoiceOut, fRun);
+ #endif
                     break;
                 default:
@@ -1524,8 +1559,14 @@
 
 #ifdef IN_RING3
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+static void hdaSdFmtToAudSettings(uint32_t u32SdFmt, uint32_t * pFrequency, uint32_t * pChannels, audfmt_e *pFormat, uint32_t *pEndian)
+# else
 static void hdaSdFmtToAudSettings(uint32_t u32SdFmt, audsettings_t *pAudSetting)
-{
+# endif
+{
+# ifndef VBOX_WITH_PDM_AUDIO_DRIVER
     Assert((pAudSetting));
-#define EXTRACT_VALUE(v, mask, shift) ((v & ((mask) << (shift))) >> (shift))
+# endif
+# define EXTRACT_VALUE(v, mask, shift) ((v & ((mask) << (shift))) >> (shift))
     uint32_t u32Hz = (u32SdFmt & HDA_SDFMT_BASE_RATE_SHIFT) ? 44100 : 48000;
     uint32_t u32HzMult = 1;
@@ -1551,5 +1592,9 @@
         case 7: u32HzDiv = 8; break;
     }
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    *pFrequency = u32Hz * u32HzMult / u32HzDiv;
+# else
     pAudSetting->freq = u32Hz * u32HzMult / u32HzDiv;
+# endif
 
     switch (EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT))
@@ -1557,9 +1602,17 @@
         case 0:
             Log(("hda: %s requested 8-bit\n", __FUNCTION__));
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            *pFormat = AUD_FMT_S8;
+# else
             pAudSetting->fmt = AUD_FMT_S8;
+# endif
             break;
         case 1:
             Log(("hda: %s requested 16-bit\n", __FUNCTION__));
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            *pFormat = AUD_FMT_S16;
+# else
             pAudSetting->fmt = AUD_FMT_S16;
+# endif
             break;
         case 2:
@@ -1571,13 +1624,23 @@
         case 4:
             Log(("hda: %s requested 32-bit\n", __FUNCTION__));
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            *pFormat = AUD_FMT_S32;
+# else
             pAudSetting->fmt = AUD_FMT_S32;
+# endif
             break;
         default:
             AssertMsgFailed(("Unsupported"));
     }
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    *pChannels = (u32SdFmt & 0xf) + 1;
+    *pFormat = AUD_FMT_S16;
+    *pEndian = 0;
+# else
     pAudSetting->nchannels = (u32SdFmt & 0xf) + 1;
     pAudSetting->fmt = AUD_FMT_S16;
     pAudSetting->endianness = 0;
-#undef EXTRACT_VALUE
+# endif
+# undef EXTRACT_VALUE
 }
 #endif
@@ -1589,16 +1652,34 @@
     /** @todo a bit more investigation is required here. */
     int rc = 0;
-    audsettings_t as;
     /* no reason to reopen voice with same settings */
     if (u32Value == HDA_REG_IND(pThis, iReg))
         return VINF_SUCCESS;
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    uint32_t uFrequency;
+    uint32_t cChannels;
+    audfmt_e Format;
+    uint32_t Endian;
+    hdaSdFmtToAudSettings(u32Value, &uFrequency, &cChannels, &Format, &Endian);
+# else
+    audsettings_t as;
     hdaSdFmtToAudSettings(u32Value, &as);
+# endif
     switch (iReg)
     {
         case HDA_REG_SD0FMT:
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            for (uint32_t lun = 0; lun < 1; lun++)
+                rc = hdaCodecOpenVoice(pThis->pCodec[lun], PI_INDEX, uFrequency, cChannels, Format, Endian);
+# else
             rc = hdaCodecOpenVoice(pThis->pCodec, PI_INDEX, &as);
+# endif
             break;
         case HDA_REG_SD4FMT:
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            for (uint32_t lun = 0; lun < 1; lun++)
+                rc = hdaCodecOpenVoice(pThis->pCodec[lun], PO_INDEX, uFrequency, cChannels, Format, Endian);
+# else
             rc = hdaCodecOpenVoice(pThis->pCodec, PO_INDEX, &as);
+# endif
             break;
         default:
@@ -1668,8 +1749,18 @@
         HDA_REG(pThis, IRS) = HDA_REG_FIELD_FLAG_MASK(IRS, ICB);  /* busy */
         Log(("hda: IC:%x\n", cmd));
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        for (uint32_t lun = 0; lun < 1; lun++)
+            rc = pThis->pCodec[lun]->pfnLookup(pThis->pCodec[lun], cmd, &pfn);
+# else
         rc = pThis->pCodec->pfnLookup(pThis->pCodec, cmd, &pfn);
+# endif
         if (RT_FAILURE(rc))
             AssertRCReturn(rc, rc);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        for (uint32_t lun = 0; lun < 1; lun++)
+            rc = pfn(pThis->pCodec[lun], cmd, &resp);
+#else
         rc = pfn(pThis->pCodec, cmd, &resp);
+#endif
         if (RT_FAILURE(rc))
             AssertRCReturn(rc, rc);
@@ -1974,5 +2065,10 @@
          * read from backend input line to the last unreported position or at the begining.
          */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        //cbBackendCopy = pThis->pDrv[0]->pfnRead(pThis->pDrv[0], pThis->pCodec[0]->SwVoiceIn, pBdle->au8HdaBuffer, cb2Copy);
+        //cbBackendCopy = pThis->pDrv[0]->pfnRead(pThis->pDrv[0], pThis->pCodec[1]->SwVoiceIn, pBdle->au8HdaBuffer, cb2Copy);
+#else
         cbBackendCopy = AUD_read(pThis->pCodec->SwVoiceIn, pBdle->au8HdaBuffer, cb2Copy);
+#endif
         /*
          * write the HDA DMA buffer
@@ -2025,5 +2121,11 @@
              * Feed the newly fetched samples, including unreported ones, to the backend.
              */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            for (uint32_t lun = 0; lun < 1; lun++)
+                cbBackendCopy = pThis->pDrv[lun]->pfnWrite(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceOut, pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW);
+            LogFlow(("cbBackendCopy write %d bytes \n", cbBackendCopy));
+#else
             cbBackendCopy = AUD_write (pThis->pCodec->SwVoiceOut, pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW);
+#endif
             hdaBackendWriteTransferReported(pBdle, cb2Copy, cbBackendCopy, &cbTransferred, pu32Avail);
         }
@@ -2548,5 +2650,9 @@
     PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     /* Save Codec nodes states */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    hdaCodecSaveState(pThis->pCodec[0], pSSM);
+#else
     hdaCodecSaveState(pThis->pCodec, pSSM);
+#endif
 
     /* Save MMIO registers */
@@ -2575,5 +2681,9 @@
      * Load Codec nodes states.
      */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    int rc = hdaCodecLoadState(pThis->pCodec[0], pSSM, uVersion);
+#else
     int rc = hdaCodecLoadState(pThis->pCodec, pSSM, uVersion);
+#endif
     if (RT_FAILURE(rc))
         return rc;
@@ -2637,6 +2747,14 @@
      * Update stuff after the state changes.
      */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    for (uint32_t lun = 0; lun < 1; lun++)
+    {
+        pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceIn, SDCTL(pThis, 0) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
+        pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceOut, SDCTL(pThis, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
+    }
+#else
     AUD_set_active_in(pThis->pCodec->SwVoiceIn, SDCTL(pThis, 0) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
     AUD_set_active_out(pThis->pCodec->SwVoiceOut, SDCTL(pThis, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
+#endif
 
     pThis->u64CORBBase = RT_MAKE_U64(HDA_REG(pThis, CORBLBASE), HDA_REG(pThis, CORBUBASE));
@@ -2813,8 +2931,16 @@
 {
     PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    for (uint32_t lun = 0; lun < 1; lun++)
+        if (pThis->pCodec[lun]->pfnCodecDbgListNodes)
+            pThis->pCodec[lun]->pfnCodecDbgListNodes(pThis->pCodec[lun], pHlp, pszArgs);
+        else
+            pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n");
+#else
     if (pThis->pCodec->pfnCodecDbgListNodes)
         pThis->pCodec->pfnCodecDbgListNodes(pThis->pCodec, pHlp, pszArgs);
     else
         pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n");
+#endif
 }
 
@@ -2826,8 +2952,16 @@
 {
     PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    for (uint32_t lun = 0; lun < 1; lun++)
+        if (pThis->pCodec[lun]->pfnCodecDbgSelector)
+            pThis->pCodec[lun]->pfnCodecDbgSelector(pThis->pCodec[lun], pHlp, pszArgs);
+        else
+            pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n");
+#else
     if (pThis->pCodec->pfnCodecDbgSelector)
         pThis->pCodec->pfnCodecDbgSelector(pThis->pCodec, pHlp, pszArgs);
     else
         pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n");
+#endif
 }
 
@@ -2922,4 +3056,16 @@
     PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
 
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    for (uint32_t lun = 0; lun < 1; lun++)
+    {
+        if (pThis->pCodec[lun])
+        {
+            int rc = hdaCodecDestruct(pThis->pCodec[lun]);
+            AssertRC(rc);
+            RTMemFree(pThis->pCodec[lun]);
+            pThis->pCodec[lun] = NULL;
+        }
+    }
+#else
     if (pThis->pCodec)
     {
@@ -2930,4 +3076,5 @@
         pThis->pCodec = NULL;
     }
+#endif
 
     RTMemFree(pThis->pu32CorbBuf);
@@ -3082,5 +3229,46 @@
     if (RT_FAILURE(rc))
         return rc;
-
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    //for (iter = 0; i < 3; i++)
+    {
+        /*
+        * Attach driver.
+        */
+        rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port");
+        if (RT_SUCCESS(rc))
+        {
+            pThis->pDrv[0] = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
+            AssertMsgReturn(pThis->pDrv,
+                            ("Configuration error: instance %d has no host audio interface!\n", iInstance),
+                            VERR_PDM_MISSING_INTERFACE);
+        }
+        else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
+        {
+            Log(("ac97: No attached driver!\n"));
+        }
+        else if (RT_FAILURE(rc))
+        {
+            AssertMsgFailed(("Failed to attach AC97 LUN #0! rc=%Rrc\n", rc));
+            return rc;
+        }
+        rc = PDMDevHlpDriverAttach(pDevIns, 1, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port");
+        if (RT_SUCCESS(rc))
+        {
+            pThis->pDrv[1] = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
+            AssertMsgReturn(pThis->pDrv[1],
+                            ("Configuration error: instance %d has no host audio interface!\n", iInstance),
+                            VERR_PDM_MISSING_INTERFACE);
+        }
+        else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
+        {
+            Log(("ac97: No attached driver! LUN#1\n"));
+        }
+        else if (RT_FAILURE(rc))
+        {
+            AssertMsgFailed(("Failed to attach AC97 LUN #1! rc=%Rrc\n", rc));
+            return rc;
+        }
+    }
+#else
     /*
      * Attach driver.
@@ -3094,6 +3282,47 @@
         return rc;
     }
-
+#endif
     /* Construct codec state. */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    pThis->pCodec[0] = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC));
+    if (!pThis->pCodec[0])
+        return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("HDA: Out of memory allocating codec state"));
+    pThis->pCodec[1] = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC));
+    if (!pThis->pCodec[1])
+        return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("HDA: Out of memory allocating codec state"));
+
+    pThis->pCodec[0]->pvHDAState = pThis;
+    pThis->pCodec[1]->pvHDAState = pThis;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    pThis->pCodec[0]->pDrv = pThis->pDrv[0];
+    //pThis->pCodec[1]->pDrv = pThis->pDrv[1];
+#endif
+    rc = hdaCodecConstruct(pDevIns, pThis->pCodec[0], pCfgHandle);
+    if (RT_FAILURE(rc))
+        AssertRCReturn(rc, rc);
+    rc = hdaCodecConstruct(pDevIns, pThis->pCodec[1], pCfgHandle);
+    if (RT_FAILURE(rc))
+        AssertRCReturn(rc, rc);
+
+    /* ICH6 datasheet defines 0 values for SVID and SID (18.1.14-15), which together with values returned for
+       verb F20 should provide device/codec recognition. */
+    Assert(pThis->pCodec[0]->u16VendorId);
+    Assert(pThis->pCodec[0]->u16DeviceId);
+    Assert(pThis->pCodec[1]->u16VendorId);
+    Assert(pThis->pCodec[1]->u16DeviceId);
+    PCIDevSetSubSystemVendorId(&pThis->PciDev, pThis->pCodec[0]->u16VendorId); /* 2c ro - intel.) */
+    PCIDevSetSubSystemId(      &pThis->PciDev, pThis->pCodec[0]->u16DeviceId); /* 2e ro. */
+    PCIDevSetSubSystemVendorId(&pThis->PciDev, pThis->pCodec[1]->u16VendorId); /* 2c ro - intel.) */
+    PCIDevSetSubSystemId(      &pThis->PciDev, pThis->pCodec[1]->u16DeviceId); /* 2e ro. */
+
+    hdaReset(pDevIns);
+    pThis->pCodec[0]->id = 0;
+    pThis->pCodec[0]->pfnTransfer = hdaTransfer;
+    pThis->pCodec[0]->pfnReset = hdaCodecReset;
+    pThis->pCodec[1]->id = 0;
+    pThis->pCodec[1]->pfnTransfer = hdaTransfer;
+    pThis->pCodec[1]->pfnReset = hdaCodecReset;
+#else
+
     pThis->pCodec = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC));
     if (!pThis->pCodec)
@@ -3123,5 +3352,5 @@
     HDA_REG(pThis, WAKEEN)   = 0x0;
     HDA_REG(pThis, STATESTS) = 0x0;
-
+#endif
     /*
      * Debug and string formatter types.
Index: /trunk/src/VBox/Devices/Audio/DevIchHdaCodec.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchHdaCodec.cpp	(revision 50685)
+++ /trunk/src/VBox/Devices/Audio/DevIchHdaCodec.cpp	(revision 50686)
@@ -26,4 +26,7 @@
 #define LOG_GROUP LOG_GROUP_DEV_AUDIO
 #include <VBox/vmm/pdmdev.h>
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+#include <VBox/vmm/pdmaudioifs.h>
+#endif
 #include <iprt/assert.h>
 #include <iprt/uuid.h>
@@ -34,7 +37,9 @@
 
 #include "VBoxDD.h"
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
 extern "C" {
 #include "audio.h"
 }
+#endif
 #include "DevIchHdaCodec.h"
 
@@ -696,6 +701,4 @@
 } CODECNODE, *PCODECNODE;
 AssertNodeSize(CODECNODE, 60 + 6);
-
-
 /*******************************************************************************
 *   Global Variables                                                           *
@@ -1160,6 +1163,9 @@
  * Misc helpers.
  */
-
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+static int hdaCodecToAudVolume(PHDACODEC pThis, AMPLIFIER *pAmp, audmixerctl_t mt)
+#else
 static int hdaCodecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt)
+#endif
 {
     uint32_t dir = AMPLIFIER_OUT;
@@ -1180,5 +1186,10 @@
     uint8_t lVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & 0x7f;
     uint8_t rVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & 0x7f;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+     /* @todo in SetVolume no passing audmixerctl_in as its not used in DrvAudio.c */
+    pThis->pDrv->pfnSetVolume(pThis->pDrv, &mute, &lVol, &rVol);
+#else
     AUD_set_volume(mt, &mute, &lVol, &rVol);
+#endif
     return VINF_SUCCESS;
 }
@@ -1328,7 +1339,15 @@
     }
     if (CODEC_NID(cmd) == pThis->u8DacLineOut)
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        hdaCodecToAudVolume(pThis, pAmplifier, AUD_MIXER_VOLUME);
+#else
         hdaCodecToAudVolume(pAmplifier, AUD_MIXER_VOLUME);
+#endif
     if (CODEC_NID(cmd) == pThis->u8AdcVolsLineIn) /* Microphone */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        hdaCodecToAudVolume(pThis, pAmplifier, AUD_MIXER_LINE_IN);
+#else
         hdaCodecToAudVolume(pAmplifier, AUD_MIXER_LINE_IN);
+#endif
     return VINF_SUCCESS;
 }
@@ -2238,5 +2257,4 @@
 
 
-
 /*
  * APIs exposed to DevHDA.
@@ -2252,19 +2270,43 @@
  *       format) before enabling.
  */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+int hdaCodecOpenVoice(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, uint32_t uFrequency, uint32_t cChannels,
+                      audfmt_e fmt, uint32_t Endian)
+#else
 int hdaCodecOpenVoice(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, audsettings_t *pAudioSettings)
+#endif
 {
     int rc;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    Assert(pThis);
+    if (!pThis)
+        return -1;
+#else
     Assert(pThis && pAudioSettings);
     if (   !pThis
         || !pAudioSettings)
         return -1;
+#endif
     switch (enmSoundSource)
     {
         case PI_INDEX:
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            /* old and new stream settings are not same. Then only call open */
+
+            //if (!hdaCodecCompareAudioSettings(&(pThis->SwVoiceIn)->info, pAudioSettings) && !pThis->SwVoiceIn)
+                rc = pThis->pDrv->pfnOpenIn(pThis->pDrv, &pThis->SwVoiceIn, "hda.in", pThis, pi_callback, uFrequency,
+                                            cChannels, fmt, Endian);
+#else
             pThis->SwVoiceIn = AUD_open_in(&pThis->card, pThis->SwVoiceIn, "hda.in", pThis, pi_callback, pAudioSettings);
+#endif
             rc = pThis->SwVoiceIn ? 0 : 1;
             break;
         case PO_INDEX:
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            rc = pThis->pDrv->pfnOpenOut(pThis->pDrv, &pThis->SwVoiceOut, "hda.out", pThis, po_callback, uFrequency,
+                                         cChannels, fmt, Endian);
+#else
             pThis->SwVoiceOut = AUD_open_out(&pThis->card, pThis->SwVoiceOut, "hda.out", pThis, po_callback, pAudioSettings);
+#endif
             rc = pThis->SwVoiceOut ? 0 : 1;
             break;
@@ -2273,5 +2315,9 @@
     }
     if (!rc)
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        LogRel(("HdaCodec: can't open %s fmt(freq: %d)\n", enmSoundSource == PI_INDEX? "in" : "out", uFrequency));
+#else
         LogRel(("HdaCodec: can't open %s fmt(freq: %d)\n", enmSoundSource == PI_INDEX? "in" : "out", pAudioSettings->freq));
+#endif
     return rc;
 }
@@ -2344,8 +2390,17 @@
      */
     if (hdaCodecIsDacNode(pThis, pThis->u8DacLineOut))
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
+#else
         hdaCodecToAudVolume(&pThis->paNodes[pThis->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
+#endif
     else if (hdaCodecIsSpdifOutNode(pThis, pThis->u8DacLineOut))
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, AUD_MIXER_VOLUME);
+    hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
+#else
         hdaCodecToAudVolume(&pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, AUD_MIXER_VOLUME);
     hdaCodecToAudVolume(&pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
+#endif
 
     return VINF_SUCCESS;
@@ -2368,4 +2423,5 @@
     int rc = stac9220Construct(pThis);
     AssertRC(rc);
+
 
     /* common root node initializers */
@@ -2378,5 +2434,8 @@
 
     /// @todo r=michaln: Was this meant to be 'HDA' or something like that? (AC'97 was on ICH0)
-    AUD_register_card ("ICH0", &pThis->card);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    pThis->pDrv->pfnRegisterCard(pThis->pDrv, "ICH0");
+#else
+    AUD_register_card("ICH0", &pThis->card);
 
     /* 44.1 kHz */
@@ -2386,8 +2445,15 @@
     as.fmt = AUD_FMT_S16;
     as.endianness = 0;
+#endif
 
     pThis->paNodes[1].node.au32F00_param[0xA] = CODEC_F00_0A_16_BIT;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    hdaCodecOpenVoice(pThis, PI_INDEX, 44100, 2, AUD_FMT_S16, 0);
+    hdaCodecOpenVoice(pThis, PO_INDEX, 44100, 2, AUD_FMT_S16, 0);
+#else
     hdaCodecOpenVoice(pThis, PI_INDEX, &as);
     hdaCodecOpenVoice(pThis, PO_INDEX, &as);
+#endif
+
     pThis->paNodes[1].node.au32F00_param[0xA] |= CODEC_F00_0A_44_1KHZ;
 
@@ -2399,23 +2465,48 @@
         pThis->pfnCodecNodeReset(pThis, i, &pThis->paNodes[i]);
     }
-
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
+    hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
+#else
     hdaCodecToAudVolume(&pThis->paNodes[pThis->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);
     hdaCodecToAudVolume(&pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
+#endif
 
     /* If no host voices were created, then fallback to nul audio. */
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    if (!pThis->pDrv->pfnIsHostVoiceInOK(pThis->pDrv, pThis->SwVoiceIn))
+        LogRel (("HDA: pfnIsHostVoiceInOK WARNING: Unable to open PCM IN!\n"));
+    if (!pThis->pDrv->pfnIsHostVoiceOutOK(pThis->pDrv, pThis->SwVoiceOut))
+        LogRel (("HDA: pfnIsHostVoiceOutOK WARNING: Unable to open PCM OUT!\n"));
+#else
     if (!AUD_is_host_voice_in_ok(pThis->SwVoiceIn))
         LogRel (("HDA: WARNING: Unable to open PCM IN!\n"));
     if (!AUD_is_host_voice_out_ok(pThis->SwVoiceOut))
         LogRel (("HDA: WARNING: Unable to open PCM OUT!\n"));
-
+#endif
+
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    if (   !pThis->pDrv->pfnIsHostVoiceInOK(pThis->pDrv, pThis->SwVoiceIn)
+        && !pThis->pDrv->pfnIsHostVoiceOutOK(pThis->pDrv, pThis->SwVoiceOut))
+#else
     if (   !AUD_is_host_voice_in_ok(pThis->SwVoiceIn)
         && !AUD_is_host_voice_out_ok(pThis->SwVoiceOut))
+#endif
     {
         /* Was not able initialize *any* voice. Select the NULL audio driver instead */
-        AUD_close_in  (&pThis->card, pThis->SwVoiceIn);
-        AUD_close_out (&pThis->card, pThis->SwVoiceOut);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        pThis->pDrv->pfnCloseIn(pThis->pDrv, pThis->SwVoiceIn);
+        pThis->pDrv->pfnCloseOut(pThis->pDrv, pThis->SwVoiceOut);
+#else
+        AUD_close_in(&pThis->card, pThis->SwVoiceIn);
+        AUD_close_out(&pThis->card, pThis->SwVoiceOut);
+#endif
         pThis->SwVoiceOut = NULL;
         pThis->SwVoiceIn = NULL;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        pThis->pDrv->pfnInitNull(pThis->pDrv);
+#else
         AUD_init_null ();
+#endif
 
         PDMDevHlpVMSetRuntimeError (pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
@@ -2423,9 +2514,21 @@
                 "with the consequence that no sound is audible"));
     }
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    else if (   !pThis->pDrv->pfnIsHostVoiceInOK(pThis->pDrv, pThis->SwVoiceIn)
+             || !pThis->pDrv->pfnIsHostVoiceOutOK(pThis->pDrv, pThis->SwVoiceOut))
+
+#else
     else if (   !AUD_is_host_voice_in_ok(pThis->SwVoiceIn)
              || !AUD_is_host_voice_out_ok(pThis->SwVoiceOut))
+#endif
     {
         char   szMissingVoices[128];
         size_t len = 0;
+ #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        if (!pThis->pDrv->pfnIsHostVoiceInOK(pThis->pDrv, pThis->SwVoiceIn))
+            len = RTStrPrintf (szMissingVoices, sizeof(szMissingVoices), "PCM_in");
+        if (!pThis->pDrv->pfnIsHostVoiceOutOK(pThis->pDrv, pThis->SwVoiceOut))
+            len += RTStrPrintf (szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_out" : "PCM_out");
+ #else
         if (!AUD_is_host_voice_in_ok(pThis->SwVoiceIn))
             len = RTStrPrintf (szMissingVoices, sizeof(szMissingVoices), "PCM_in");
@@ -2433,4 +2536,5 @@
             len += RTStrPrintf (szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_out" : "PCM_out");
 
+ #endif
         PDMDevHlpVMSetRuntimeError (pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
             N_ ("Some audio devices (%s) could not be opened. Guest applications generating audio "
Index: /trunk/src/VBox/Devices/Audio/DevIchHdaCodec.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchHdaCodec.h	(revision 50685)
+++ /trunk/src/VBox/Devices/Audio/DevIchHdaCodec.h	(revision 50686)
@@ -18,10 +18,14 @@
 #ifndef DEV_CODEC_H
 #define DEV_CODEC_H
-
+//#include <VBox/vmm/pdmdev.h>
 /** The ICH HDA (Intel) codec state. */
 typedef struct HDACODEC HDACODEC;
 /** Pointer to the Intel ICH HDA codec state. */
 typedef HDACODEC *PHDACODEC;
-
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+typedef struct PDMIAUDIOCONNECTOR * PPDMIAUDIOCONNECTOR;
+typedef struct PDMGSTVOICEOUT *PPDMGSTVOICEOUT;
+typedef struct PDMGSTVOICEIN  *PPDMGSTVOICEIN;
+#endif
 /**
  * Verb processor method.
@@ -72,4 +76,10 @@
     uint8_t                 u8BSKU;
     uint8_t                 u8AssemblyId;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pDrv;
+    /** Pointer to the attached audio driver. */
+    R3PTRTYPE(PPDMIBASE)               pDrvBase;
+#endif
+
 #ifndef VBOX_WITH_HDA_CODEC_EMU
     CODECVERB const        *paVerbs;
@@ -79,4 +89,11 @@
 #endif
     PCODECNODE              paNodes;
+
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    /** PCM in */
+    R3PTRTYPE(PPDMGSTVOICEIN)         SwVoiceIn;
+    /** PCM out */
+    R3PTRTYPE(PPDMGSTVOICEOUT)        SwVoiceOut;
+#else
     QEMUSoundCard           card;
     /** PCM in */
@@ -84,4 +101,5 @@
     /** PCM out */
     SWVoiceOut              *SwVoiceOut;
+#endif
     void                   *pvHDAState;
     bool                    fInReset;
Index: /trunk/src/VBox/Devices/Audio/DevSB16.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 50685)
+++ /trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 50686)
@@ -34,4 +34,7 @@
 #define LOG_GROUP LOG_GROUP_DEV_AUDIO
 #include <VBox/vmm/pdmdev.h>
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+#include <VBox/vmm/pdmaudioifs.h>
+#endif
 #include <iprt/assert.h>
 #include <iprt/string.h>
@@ -39,25 +42,13 @@
 #include "vl_vbox.h"
 
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
 extern "C" {
 #include "audio.h"
 }
-
-#ifndef VBOX
-
+#endif
+
+#ifndef VBOX
 #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
-
-#define dolog(...) AUD_log ("sb16", __VA_ARGS__)
-
-/* #define DEBUG */
-/* #define DEBUG_SB16_MOST */
-
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
-
 #else /* VBOX */
-
 /** Current saved state version. */
 #define SB16_SAVE_STATE_VERSION         2
@@ -65,29 +56,4 @@
  * the config dump. */
 #define SB16_SAVE_STATE_VERSION_VBOX_30 1
-
-DECLINLINE(void) dolog (const char *fmt, ...)
-{
-    va_list ap;
-    va_start (ap, fmt);
-    AUD_vlog ("sb16", fmt, ap);
-    va_end (ap);
-}
-
-# ifdef DEBUG
-static void ldebug (const char *fmt, ...)
-{
-    va_list ap;
-
-    va_start (ap, fmt);
-    AUD_vlog ("sb16", fmt, ap);
-    va_end (ap);
-}
-# else
-DECLINLINE(void) ldebug (const char *fmt, ...)
-{
-    (void)fmt;
-}
-# endif
-
 #endif /* VBOX */
 
@@ -122,9 +88,16 @@
 typedef struct SB16State {
 #ifdef VBOX
+    /** Pointer to the device instance. */
     PPDMDEVINSR3 pDevIns;
-#endif
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    /** Pointer to the connector of the attached audio driver. */
+    PPDMIAUDIOCONNECTOR     pDrv;
+# endif
+#endif
+#ifndef VBOX
+    qemu_irq *pic;
+#endif
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
     QEMUSoundCard card;
-#ifndef VBOX
-    qemu_irq *pic;
 #endif
 #ifdef VBOX /* lazy bird */
@@ -182,5 +155,9 @@
     int align;
     int audio_free;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    PPDMGSTVOICEOUT voice;
+#else
     SWVoiceOut *voice;
+#endif
 
 #ifndef VBOX
@@ -211,5 +188,5 @@
         return 8;
     default:
-        dolog ("bad irq %d\n", irq);
+        LogFlow(("SB16: bad irq %d\n", irq));
         return 2;
     }
@@ -228,5 +205,5 @@
         return 10;
     default:
-        dolog ("bad irq magic %d\n", magic);
+        LogFlow(("SB16: bad irq magic %d\n", magic));
         return -1;
     }
@@ -259,5 +236,5 @@
     s->dma_running = hold;
 
-    ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
+    LogFlow(("SB16: hold %d high %d dma %d\n", hold, s->use_hdma, dma));
 
 #ifndef VBOX
@@ -275,10 +252,18 @@
         PDMDevHlpDMASetDREQ (s->pDevIns, dma, 1);
         PDMDevHlpDMASchedule (s->pDevIns);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        s->pDrv->pfnEnableOut(s->pDrv, s->voice, 1);
+#else
         AUD_set_active_out (s->voice, 1);
+#endif
     }
     else
     {
         PDMDevHlpDMASetDREQ (s->pDevIns, dma, 0);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        s->pDrv->pfnEnableOut(s->pDrv, s->voice, 0);
+#else
         AUD_set_active_out (s->voice, 0);
+#endif
     }
 #endif /* VBOX */
@@ -306,14 +291,21 @@
 static void continue_dma8 (SB16State *s)
 {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    int rc;
+#endif
     if (s->freq > 0) {
+
+        s->audio_free = 0;
+
+
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        rc = s->pDrv->pfnOpenOut(s->pDrv, &s->voice, "sb16", s, SB_audio_callback, s->freq, 1 << s->fmt_stereo,
+                                 s->fmt, 0);
+#else
         audsettings_t as;
-
-        s->audio_free = 0;
-
         as.freq = s->freq;
         as.nchannels = 1 << s->fmt_stereo;
         as.fmt = s->fmt;
         as.endianness = 0;
-
         s->voice = AUD_open_out (
             &s->card,
@@ -324,4 +316,5 @@
             &as
             );
+#endif
     }
 
@@ -367,12 +360,12 @@
 
     if (s->block_size & s->align) {
-        dolog ("warning: misaligned block size %d, alignment %d\n",
-               s->block_size, s->align + 1);
-    }
-
-    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
+        LogFlow(("SB16: warning: misaligned block size %d, alignment %d\n",
+               s->block_size, s->align + 1));
+    }
+
+    LogFlow(("SB16: freq %d, stereo %d, sign %d, bits %d, "
             "dma %d, auto %d, fifo %d, high %d\n",
             s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
-            s->block_size, s->dma_auto, s->fifo, s->highspeed);
+            s->block_size, s->dma_auto, s->fifo, s->highspeed));
 
     continue_dma8 (s);
@@ -419,8 +412,8 @@
     }
 
-    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
+    LogFlow(("SB16: freq %d, stereo %d, sign %d, bits %d, "
             "dma %d, auto %d, fifo %d, high %d\n",
             s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
-            s->block_size, s->dma_auto, s->fifo, s->highspeed);
+            s->block_size, s->dma_auto, s->fifo, s->highspeed));
 
     if (16 == s->fmt_bits) {
@@ -447,18 +440,22 @@
     s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
     if (s->block_size & s->align) {
-        dolog ("warning: misaligned block size %d, alignment %d\n",
-               s->block_size, s->align + 1);
+        LogFlow(("SB16: warning: misaligned block size %d, alignment %d\n",
+               s->block_size, s->align + 1));
     }
 
     if (s->freq) {
+
+        s->audio_free = 0;
+
+
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    int rc;
+        rc = s->pDrv->pfnOpenOut(s->pDrv, &s->voice, "sb16", s,SB_audio_callback, s->freq, 1 << s->fmt_stereo, s->fmt, 0);
+#else
         audsettings_t as;
-
-        s->audio_free = 0;
-
         as.freq = s->freq;
         as.nchannels = 1 << s->fmt_stereo;
         as.fmt = s->fmt;
         as.endianness = 0;
-
         s->voice = AUD_open_out (
             &s->card,
@@ -469,4 +466,5 @@
             &as
             );
+#endif
     }
 
@@ -477,5 +475,5 @@
 static inline void dsp_out_data (SB16State *s, uint8_t val)
 {
-    ldebug ("outdata %#x\n", val);
+    LogFlow(("SB16: outdata %#x\n", val));
     if ((size_t) s->out_data_len < sizeof (s->out_data)) {
         s->out_data[s->out_data_len++] = val;
@@ -489,5 +487,5 @@
     }
     else {
-        dolog ("buffer underflow\n");
+        LogFlow(("SB16: buffer underflow\n"));
         return 0;
     }
@@ -496,9 +494,9 @@
 static void command (SB16State *s, uint8_t cmd)
 {
-    ldebug ("command %#x\n", cmd);
+    LogFlow(("SB16: command %#x\n", cmd));
 
     if (cmd > 0xaf && cmd < 0xd0) {
         if (cmd & 8) {
-            dolog ("ADC not yet supported (command %#x)\n", cmd);
+            LogFlow(("SB16: ADC not yet supported (command %#x)\n", cmd));
         }
 
@@ -508,5 +506,5 @@
             break;
         default:
-            dolog ("%#x wrong bits\n", cmd);
+            LogFlow(("SB16: %#x wrong bits\n", cmd));
         }
         s->needed_bytes = 3;
@@ -562,5 +560,5 @@
 
         case 0x35:
-            dolog ("0x35 - MIDI command not implemented\n");
+            LogFlow(("SB16: 0x35 - MIDI command not implemented\n"));
             break;
 
@@ -596,32 +594,30 @@
         case 0x74:
             s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
-            dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
+            LogFlow(("SB16: 0x75 - DMA DAC, 4-bit ADPCM not implemented\n"));
             break;
 
         case 0x75:              /* DMA DAC, 4-bit ADPCM Reference */
             s->needed_bytes = 2;
-            dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
+            LogFlow(("SB16: 0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n"));
             break;
 
         case 0x76:              /* DMA DAC, 2.6-bit ADPCM */
             s->needed_bytes = 2;
-            dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
+            LogFlow(("SB16: 0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n"));
             break;
 
         case 0x77:              /* DMA DAC, 2.6-bit ADPCM Reference */
             s->needed_bytes = 2;
-            dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
+            LogFlow(("SB16: 0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n"));
             break;
 
         case 0x7d:
-            dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
-            dolog ("not implemented\n");
+            LogFlow(("SB16: 0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n"));
+            LogFlow(("SB16: not implemented\n"));
             break;
 
         case 0x7f:
-            dolog (
-                "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
-                );
-            dolog ("not implemented\n");
+            LogFlow(("SB16: 0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"));
+            LogFlow(("SB16: not implemented\n"));
             break;
 
@@ -695,5 +691,5 @@
 
         case 0xe7:
-            dolog ("Attempt to probe for ESS (0xe7)?\n");
+            LogFlow(("SB16: Attempt to probe for ESS (0xe7)?\n"));
             break;
 
@@ -726,5 +722,5 @@
 
         default:
-            dolog ("Unrecognized command %#x\n", cmd);
+            LogFlow(("SB16: Unrecognized command %#x\n", cmd));
             break;
         }
@@ -732,5 +728,5 @@
 
     if (!s->needed_bytes) {
-        ldebug ("\n");
+        LogFlow(("\n"));
     }
 
@@ -745,6 +741,6 @@
 
  warn:
-    dolog ("warning: command %#x,%d is not truly understood yet\n",
-           cmd, s->needed_bytes);
+    LogFlow(("SB16: warning: command %#x,%d is not truly understood yet\n",
+           cmd, s->needed_bytes));
     goto exit;
 
@@ -768,6 +764,6 @@
 {
     int d0, d1, d2;
-    ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
-            s->cmd, s->in_index, s->needed_bytes);
+    LogFlow(("SB16: complete command %#x, in_index %d, needed_bytes %d\n",
+            s->cmd, s->in_index, s->needed_bytes));
 
     if (s->cmd > 0xaf && s->cmd < 0xd0) {
@@ -777,10 +773,10 @@
 
         if (s->cmd & 8) {
-            dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
-                   s->cmd, d0, d1, d2);
+            LogFlow(("SB16: ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
+                   s->cmd, d0, d1, d2));
         }
         else {
-            ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
-                    s->cmd, d0, d1, d2);
+            LogFlow(("SB16: cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
+                    s->cmd, d0, d1, d2));
             dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
         }
@@ -792,5 +788,5 @@
             s->csp_reg83r = 0;
             s->csp_reg83w = 0;
-            ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
+            LogFlow(("SB16: CSP command 0x04: mode=%#x\n", s->csp_mode));
             break;
 
@@ -798,7 +794,7 @@
             s->csp_param = dsp_get_data (s);
             s->csp_value = dsp_get_data (s);
-            ldebug ("CSP command 0x05: param=%#x value=%#x\n",
+            LogFlow(("SB16: CSP command 0x05: param=%#x value=%#x\n",
                     s->csp_param,
-                    s->csp_value);
+                    s->csp_value));
             break;
 
@@ -806,7 +802,7 @@
             d0 = dsp_get_data (s);
             d1 = dsp_get_data (s);
-            ldebug ("write CSP register %d <- %#x\n", d1, d0);
+            LogFlow(("SB16: write CSP register %d <- %#x\n", d1, d0));
             if (d1 == 0x83) {
-                ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
+                LogFlow(("SB16: 0x83[%d] <- %#x\n", s->csp_reg83r, d0));
                 s->csp_reg83[s->csp_reg83r % 4] = d0;
                 s->csp_reg83r += 1;
@@ -819,10 +815,10 @@
         case 0x0f:
             d0 = dsp_get_data (s);
-            ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
-                    d0, s->csp_regs[d0], s->csp_mode);
+            LogFlow(("SB16: read CSP register %#x -> %#x, mode=%#x\n",
+                    d0, s->csp_regs[d0], s->csp_mode));
             if (d0 == 0x83) {
-                ldebug ("0x83[%d] -> %#x\n",
+                LogFlow(("SB16: 0x83[%d] -> %#x\n",
                         s->csp_reg83w,
-                        s->csp_reg83[s->csp_reg83w % 4]);
+                        s->csp_reg83[s->csp_reg83w % 4]));
                 dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
                 s->csp_reg83w += 1;
@@ -835,5 +831,5 @@
         case 0x10:
             d0 = dsp_get_data (s);
-            dolog ("cmd 0x10 d0=%#x\n", d0);
+            LogFlow(("SB16: cmd 0x10 d0=%#x\n", d0));
             break;
 
@@ -844,5 +840,5 @@
         case 0x40:
             s->time_const = dsp_get_data (s);
-            ldebug ("set time const %d\n", s->time_const);
+            LogFlow(("SB16: set time const %d\n", s->time_const));
             break;
 
@@ -853,10 +849,10 @@
         case 0x41:
             s->freq = dsp_get_hilo (s);
-            ldebug ("set freq %d\n", s->freq);
+            LogFlow(("SB16: set freq %d\n", s->freq));
             break;
 
         case 0x48:
             s->block_size = dsp_get_lohi (s) + 1;
-            ldebug ("set dma block len %d\n", s->block_size);
+            LogFlow(("SB16: set dma block len %d\n", s->block_size));
             break;
 
@@ -889,5 +885,5 @@
                     }
                 }
-                ldebug ("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks);
+                LogFlow(("SB16: mix silence %d %d %" PRId64 "\n", samples, bytes, ticks));
 #else  /* VBOX */
                 ticks = (bytes * TMTimerGetFreq(s->pTimer)) / freq;
@@ -896,5 +892,5 @@
                 else
                     TMTimerSet(s->pTimer, TMTimerGet(s->pTimer) + ticks);
-                ldebug ("mix silence %d %d % %RU64\n", samples, bytes, ticks);
+                LogFlow(("SB16: mix silence %d %d % %RU64\n", samples, bytes, ticks));
 #endif /* VBOX */
             }
@@ -904,5 +900,5 @@
             d0 = dsp_get_data (s);
             s->out_data_len = 0;
-            ldebug ("E0 data = %#x\n", d0);
+            LogFlow(("SB16: E0 data = %#x\n", d0));
             dsp_out_data (s, ~d0);
             break;
@@ -910,5 +906,5 @@
         case 0xe2:
             d0 = dsp_get_data (s);
-            ldebug ("E2 = %#x\n", d0);
+            LogFlow(("SB16:E2 = %#x\n", d0));
             break;
 
@@ -919,5 +915,5 @@
         case 0xf9:
             d0 = dsp_get_data (s);
-            ldebug ("command 0xf9 with %#x\n", d0);
+            LogFlow(("SB16: command 0xf9 with %#x\n", d0));
             switch (d0) {
             case 0x0e:
@@ -940,10 +936,10 @@
 
         default:
-            dolog ("complete: unrecognized command %#x\n", s->cmd);
+            LogFlow(("SB16: complete: unrecognized command %#x\n", s->cmd));
             return;
         }
     }
 
-    ldebug ("\n");
+    LogFlow(("\n"));
     s->cmd = -1;
     return;
@@ -952,5 +948,4 @@
 static void legacy_reset (SB16State *s)
 {
-    audsettings_t as;
 
     s->freq = 11025;
@@ -959,9 +954,13 @@
     s->fmt_stereo = 0;
 
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    int rc;
+    rc = s->pDrv->pfnOpenOut(s->pDrv, &s->voice, "sb16", s, SB_audio_callback, 11025, 1, AUD_FMT_U8, 0);
+#else
+    audsettings_t as;
     as.freq = s->freq;
     as.nchannels = 1;
     as.fmt = AUD_FMT_U8;
     as.endianness = 0;
-
     s->voice = AUD_open_out (
         &s->card,
@@ -973,4 +972,5 @@
         );
 
+#endif
     /* Not sure about that... */
     /* AUD_set_active_out (s->voice, 1); */
@@ -1016,5 +1016,5 @@
     int iport = nport - s->port;
 
-    ldebug ("write %#x <- %#x\n", nport, val);
+    LogFlow(("SB16: write %#x <- %#x\n", nport, val));
     switch (iport) {
     case 0x06:
@@ -1077,5 +1077,5 @@
         else {
             if (s->in_index == sizeof (s->in2_data)) {
-                dolog ("in data overrun\n");
+                LogFlow(("SB16: in data overrun\n"));
             }
             else {
@@ -1093,5 +1093,5 @@
 
     default:
-        ldebug ("(nport=%#x, val=%#x)\n", nport, val);
+        LogFlow(("SB16: nport=%#x, val=%#x)\n", nport, val));
         break;
     }
@@ -1125,6 +1125,6 @@
         else {
             if (s->cmd != -1) {
-                dolog ("empty output buffer for command %#x\n",
-                       s->cmd);
+                LogFlow(("SB16: empty output buffer for command %#x\n",
+                       s->cmd));
             }
             retval = s->last_read_byte;
@@ -1173,5 +1173,5 @@
 
     if (!ack) {
-        ldebug ("read %#x -> %#x\n", nport, retval);
+        LogFlow(("SB16: read %#x -> %#x\n", nport, retval));
     }
 
@@ -1184,5 +1184,5 @@
 
  error:
-    dolog ("warning: dsp_read %#x error\n", nport);
+    LogFlow(("SB16: warning: dsp_read %#x error\n", nport));
 #ifndef VBOX
     return 0xff;
@@ -1232,4 +1232,20 @@
 #endif
 }
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+uint32_t popcount (uint32_t u)
+{
+    u = ((u&0x55555555) + ((u>>1)&0x55555555));
+    u = ((u&0x33333333) + ((u>>2)&0x33333333));
+    u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));
+    u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));
+    u = ( u&0x0000ffff) + (u>>16);
+    return u;
+}
+
+uint32_t lsbindex (uint32_t u)
+{
+    return popcount ((u&-u)-1);
+}
+#endif
 
 static IO_WRITE_PROTO(mixer_write_datab)
@@ -1240,5 +1256,5 @@
 
     (void) nport;
-    ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
+    LogFlow(("SB16: mixer_write [%#x] <- %#x\n", s->mixer_nreg, val));
 
     switch (s->mixer_nreg) {
@@ -1291,5 +1307,5 @@
         {
             int irq = irq_of_magic (val);
-            ldebug ("setting irq to %d (val=%#x)\n", irq, val);
+            LogFlow(("SB16: setting irq to %d (val=%#x)\n", irq, val));
             if (irq > 0) {
                 s->irq = irq;
@@ -1305,8 +1321,8 @@
             hdma = lsbindex (val & 0xf0);
             if (dma != s->dma || hdma != s->hdma) {
-                dolog (
-                    "attempt to change DMA "
+                LogFlow((
+                    "SB16: attempt to change DMA "
                     "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
-                    dma, s->dma, hdma, s->hdma, val);
+                    dma, s->dma, hdma, s->hdma, val));
             }
 #if 0
@@ -1318,6 +1334,6 @@
 
     case 0x82:
-        dolog ("attempt to write into IRQ status register (val=%#x)\n",
-               val);
+        LogFlow(("SB16: attempt to write into IRQ status register (val=%#x)\n",
+               val));
 #ifdef VBOX
         return VINF_SUCCESS;
@@ -1326,5 +1342,5 @@
     default:
         if (s->mixer_nreg >= 0x80) {
-            ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
+            LogFlow(("SB16: attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val));
         }
         break;
@@ -1340,5 +1356,10 @@
         uint8_t lvol = s->mixer_regs[0x30];
         uint8_t rvol = s->mixer_regs[0x31];
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        /*@todo not passinga audmixer_Ctl values as its not used in DrvAudio.c */
+        s->pDrv->pfnSetVolume(s->pDrv, &mute, &lvol, &rvol);
+#else
         AUD_set_volume(AUD_MIXER_VOLUME, &mute, &lvol, &rvol);
+#endif
     }
     /* Update the voice (PCM) volume. */
@@ -1348,5 +1369,9 @@
         uint8_t lvol = s->mixer_regs[0x32];
         uint8_t rvol = s->mixer_regs[0x33];
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        s->pDrv->pfnSetVolume(s->pDrv, &mute, &lvol, &rvol);
+#else
         AUD_set_volume(AUD_MIXER_PCM, &mute, &lvol, &rvol);
+#endif
     }
 #endif /* VBOX */
@@ -1397,10 +1422,10 @@
 #ifndef DEBUG_SB16_MOST
     if (s->mixer_nreg != 0x82) {
-        ldebug ("mixer_read[%#x] -> %#x\n",
-                s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
-    }
-#else
-    ldebug ("mixer_read[%#x] -> %#x\n",
-            s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
+        LogFlow(("SB16: mixer_read[%#x] -> %#x\n",
+                s->mixer_nreg, s->mixer_regs[s->mixer_nreg]));
+    }
+#else
+    LogFlow(("SB16: mixer_read[%#x] -> %#x\n",
+            s->mixer_nreg, s->mixer_regs[s->mixer_nreg]));
 #endif
 #ifndef VBOX
@@ -1444,5 +1469,9 @@
 #endif
 
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        copied = s->pDrv->pfnWrite(s->pDrv, s->voice, tmpbuf, copied);
+#else
         copied = AUD_write (s->voice, tmpbuf, copied);
+#endif
 
         temp -= copied;
@@ -1468,6 +1497,6 @@
 
     if (s->block_size <= 0) {
-        dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
-               s->block_size, nchan, dma_pos, dma_len);
+        LogFlow(("SB16: invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
+               s->block_size, nchan, dma_pos, dma_len));
         return dma_pos;
     }
@@ -1491,6 +1520,6 @@
 
 #ifdef DEBUG_SB16_MOST
-    dolog ("pos:%06d %d till:%d len:%d\n",
-           dma_pos, free, till, dma_len);
+    LogFlow(("SB16: pos:%06d %d till:%d len:%d\n",
+           dma_pos, free, till, dma_len));
 #endif
 
@@ -1523,7 +1552,7 @@
 
 #ifdef DEBUG_SB16_MOST
-    ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
+    LogFlow(("SB16: pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
             dma_pos, free, dma_len, s->left_till_irq, copy, written,
-            s->block_size);
+            s->block_size));
 #endif
 
@@ -1663,5 +1692,9 @@
 
     if (s->voice) {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        s->pDrv->pfnCloseOut(s->pDrv, s->voice);
+#else
         AUD_close_out (&s->card, s->voice);
+#endif
         s->voice = NULL;
     }
@@ -1669,13 +1702,16 @@
     if (s->dma_running) {
         if (s->freq) {
+
+            s->audio_free = 0;
+
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            int rc;
+            rc = s->pDrv->pfnOpenOut(s->pDrv, &s->voice, "sb16", s, SB_audio_callback, s->freq, 1 << s->fmt_stereo, s->fmt, 0);
+#else
             audsettings_t as;
-
-            s->audio_free = 0;
-
             as.freq = s->freq;
             as.nchannels = 1 << s->fmt_stereo;
             as.fmt = s->fmt;
             as.endianness = 0;
-
             s->voice = AUD_open_out (
                 &s->card,
@@ -1686,4 +1722,5 @@
                 &as
                 );
+#endif
         }
 
@@ -1706,5 +1743,5 @@
 
     if (!audio) {
-        dolog ("No audio state\n");
+        LogFlow(("SB16: No audio state\n"));
         return -1;
     }
@@ -1712,6 +1749,6 @@
     s = qemu_mallocz (sizeof (*s));
     if (!s) {
-        dolog ("Could not allocate memory for SB16 (%zu bytes)\n",
-               sizeof (*s));
+        LogFlow(("SB16: Could not allocate memory for SB16 (%zu bytes)\n",
+               sizeof (*s)));
         return -1;
     }
@@ -1735,5 +1772,5 @@
     s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
     if (!s->aux_ts) {
-        dolog ("warning: Could not create auxiliary timer\n");
+        LogFlow(("SB16: warning: Could not create auxiliary timer\n"));
     }
 
@@ -1756,5 +1793,5 @@
 
     register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
-    AUD_register_card (audio, "sb16", &s->card);
+    AUD_register_card (audio, "sb16");
     return 0;
 }
@@ -1943,18 +1980,48 @@
 
     rc = PDMDevHlpDriverAttach(pDevIns, 0, &s->IBase, &s->pDrvBase, "Audio Driver Port");
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    if(RT_SUCCESS(rc))
+    {
+        s->pDrv = PDMIBASE_QUERY_INTERFACE(s->pDrvBase, PDMIAUDIOCONNECTOR);
+        AssertMsgReturn(s->pDrv,
+                        ("Configuration error: instance %d has no host audio interface!\n", iInstance),
+                        VERR_PDM_MISSING_INTERFACE);
+    }
+    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
+#else
     if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
-        Log(("sb16: No attached driver!\n"));
+#endif
+        Log(("ac97: No attached driver!\n"));
     else if (RT_FAILURE(rc))
-        AssertMsgFailedReturn(("Failed to attach SB16 LUN #0! rc=%Rrc\n", rc), rc);
-
+    {
+        AssertMsgFailed(("Failed to attach AC97 LUN #0! rc=%Rrc\n", rc));
+        return rc;
+    }
+
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+     s->pDrv->pfnRegisterCard(s->pDrv, "sb16");
+#else
     AUD_register_card("sb16", &s->card);
+#endif
     legacy_reset(s);
 
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    if (!s->pDrv->pfnIsHostVoiceOutOK(s->pDrv,s->voice))
+#else
     if (!AUD_is_host_voice_out_ok(s->voice))
+#endif
     {
         LogRel (("SB16: WARNING: Unable to open PCM OUT!\n"));
-        AUD_close_out(&s->card, s->voice);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        s->pDrv->pfnCloseOut(s->pDrv, s->voice );
+#else
+        AUD_close_out (&s->card, s->voice);
+#endif
         s->voice = NULL;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        s->pDrv->pfnInitNull(s->pDrv);
+#else
         AUD_init_null();
+#endif
         PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
             N_("No audio devices could be opened. Selecting the NULL audio backend "
Index: /trunk/src/VBox/Devices/Audio/mixeng.c
===================================================================
--- /trunk/src/VBox/Devices/Audio/mixeng.c	(revision 50685)
+++ /trunk/src/VBox/Devices/Audio/mixeng.c	(revision 50686)
@@ -26,5 +26,4 @@
 #include "VBoxDD.h"
 #include "vl_vbox.h"
-#include "audio.h"
 #ifdef VBOX
 # include <iprt/asm-math.h>
@@ -33,5 +32,10 @@
 
 #define AUDIO_CAP "mixeng"
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+#include "DrvAudio.h"
+#else
+#include "audio.h"
 #include "audio_int.h"
+#endif
 
 #ifndef VBOX
@@ -309,9 +313,12 @@
 void *st_rate_start (int inrate, int outrate)
 {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    struct rate *rate = (struct rate *)RTMemAllocZ(1 * sizeof (*rate));
+#else
     struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate));
+#endif
 
     if (!rate) {
-        dolog ("Could not allocate resampler (%" FMTZ "u bytes)\n",
-               sizeof (*rate));
+        LogFlow(("Could not allocate resampler %u bytes)\n", sizeof (*rate)));
         return NULL;
     }
@@ -338,15 +345,33 @@
 void st_rate_stop (void *opaque)
 {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    RTMemFree(opaque);
+#else
     qemu_free (opaque);
-}
-
+#endif
+}
+
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+void mixeng_clear(PPDMHOSTSTEREOSAMPLE buf, int len)
+{
+    memset (buf, 0, len * sizeof (PDMHOSTSTEREOSAMPLE));
+}
+#else
 void mixeng_clear (st_sample_t *buf, int len)
 {
     memset (buf, 0, len * sizeof (st_sample_t));
 }
-
+#endif
+
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+void mixeng_sniff_and_clear (PPDMHOSTVOICEOUT hw, PPDMHOSTSTEREOSAMPLE src, int len)
+#else
 void mixeng_sniff_and_clear (HWVoiceOut *hw, st_sample_t *src, int len)
-{
+#endif
+{
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
+    LogFlow(("mixeng: sniffer_run_out\n"));
     sniffer_run_out (hw, src, len);
+#endif
     mixeng_clear (src, len);
 }
Index: /trunk/src/VBox/Devices/Audio/mixeng.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/mixeng.h	(revision 50685)
+++ /trunk/src/VBox/Devices/Audio/mixeng.h	(revision 50686)
@@ -29,5 +29,7 @@
 #ifdef VBOX
 /* use faster ASMMult2xS32RetS64 */
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
 typedef struct { int mute;  uint32_t r; uint32_t l; } volume_t;
+#endif
 typedef struct { int64_t l; int64_t r; } st_sample_t;
 #else /* !VBOX */
@@ -41,7 +43,8 @@
 #endif
 #endif /* VBOX */
-
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
 typedef void (t_sample) (st_sample_t *dst, const void *src,
                          int samples, volume_t *vol);
+#endif
 typedef void (f_sample) (void *dst, const st_sample_t *src, int samples);
 
@@ -55,6 +58,11 @@
                        int *isamp, int *osamp);
 void st_rate_stop (void *opaque);
+# ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+void mixeng_clear(PPDMHOSTSTEREOSAMPLE buf, int len);
+void mixeng_sniff_and_clear(PPDMHOSTVOICEOUT hw, PPDMHOSTSTEREOSAMPLE src, int len);
+# else
 void mixeng_clear (st_sample_t *buf, int len);
 void mixeng_sniff_and_clear (struct HWVoiceOut *hw, st_sample_t *src, int len);
+# endif
 
 #endif  /* mixeng.h */
Index: /trunk/src/VBox/Devices/Audio/mixeng_template.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/mixeng_template.h	(revision 50685)
+++ /trunk/src/VBox/Devices/Audio/mixeng_template.h	(revision 50686)
@@ -114,7 +114,15 @@
 
 static void glue (glue (conv_, ET), _to_stereo)
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    (PPDMHOSTSTEREOSAMPLE dst, const void *src, int samples, volume_t *vol)
+#else
     (st_sample_t *dst, const void *src, int samples, volume_t *vol)
-{
+#endif
+{
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    PPDMHOSTSTEREOSAMPLE out = dst;
+#else
     st_sample_t *out = dst;
+#endif
     IN_T *in = (IN_T *) src;
 #ifndef NOVOL
@@ -127,6 +135,11 @@
 #endif
     while (samples--) {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        out->u64LSample = VOL (glue (conv_, ET) (*in++), vol->l);
+        out->u64RSample = VOL (glue (conv_, ET) (*in++), vol->r);
+#else
         out->l = VOL (glue (conv_, ET) (*in++), vol->l);
         out->r = VOL (glue (conv_, ET) (*in++), vol->r);
+#endif
         out += 1;
     }
@@ -134,7 +147,15 @@
 
 static void glue (glue (conv_, ET), _to_mono)
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    (PPDMHOSTSTEREOSAMPLE dst, const void *src, int samples, volume_t *vol)
+#else
     (st_sample_t *dst, const void *src, int samples, volume_t *vol)
-{
+#endif
+{
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    PPDMHOSTSTEREOSAMPLE out = dst;
+#else
     st_sample_t *out = dst;
+#endif
     IN_T *in = (IN_T *) src;
 #ifndef NOVOL
@@ -147,6 +168,12 @@
 #endif
     while (samples--) {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        out->u64LSample = VOL (glue (conv_, ET) (in[0]), vol->l);
+        out->u64RSample = out->u64LSample;
+#else
         out->l = VOL (glue (conv_, ET) (in[0]), vol->l);
         out->r = out->l;
+
+#endif
         out += 1;
         in += 1;
Index: /trunk/src/VBox/Devices/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Devices/Makefile.kmk	(revision 50685)
+++ /trunk/src/VBox/Devices/Makefile.kmk	(revision 50686)
@@ -165,9 +165,5 @@
  	Parallel/DevParallel.cpp \
 	\
- 	Audio/audio.c \
- 	Audio/audiosniffer.c \
  	Audio/mixeng.c \
- 	Audio/noaudio.c \
- 	Audio/filteraudio.c \
  	Input/DrvKeyboardQueue.cpp \
  	Input/DrvMouseQueue.cpp \
@@ -497,20 +493,54 @@
  # --- Audio bits. ---
 
+ ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+   VBoxDD_DEFS         +=VBOX_WITH_PDM_AUDIO_DRIVER
+ endif
+ ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+   VBoxDD_SOURCES += Audio/DrvAudio.c \
+	 Audio/DrvAudioUtil.c \
+	 Audio/DrvHostNullAudio.c
+ else
+   VBoxDD_SOURCES += Audio/audio.c \
+ 	 Audio/audiosniffer.c \
+ 	 Audio/noaudio.c \
+ 	 Audio/filteraudio.c 
+ endif
+
  ifdef VBOX_WITH_ALSA
   VBoxDD_DEFS.linux     += VBOX_WITH_ALSA
-  VBoxDD_SOURCES.linux  += \
- 	Audio/alsaaudio.c \
- 	Audio/alsa_stubs.c
+  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    VBoxDD_DEFS.linux     += VBOX_WITH_WITH_PDM_AUDIO_DRIVER
+    VBoxDD_SOURCES.linux  += \
+ 	  Audio/DrvHostAlsaAudio.c \
+      Audio/alsa_stubs.c
+  else
+    VBoxDD_SOURCES.linux  += \
+ 	  Audio/alsaaudio.c \
+ 	  Audio/alsa_stubs.c
+  endif
  endif
 
  ifdef VBOX_WITH_PULSE
   VBoxDD_DEFS.linux     += VBOX_WITH_PULSE
-  VBoxDD_SOURCES.linux  += \
- 	Audio/pulseaudio.c \
- 	Audio/pulse_stubs.c
+  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    VBoxDD_DEFS.linux     += VBOX_WITH_PDM_AUDIO_DRIVER
+    VBoxDD_SOURCES.linux  += \
+ 	  Audio/DrvHostPulseAudio.c \
+      Audio/pulse_stubs.c
+  else
+    VBoxDD_SOURCES.linux  += \
+ 	  Audio/pulseaudio.c \
+ 	  Audio/pulse_stubs.c
+  endif
   VBoxDD_DEFS.freebsd   += VBOX_WITH_PULSE
-  VBoxDD_SOURCES.freebsd+= \
- 	Audio/pulseaudio.c \
- 	Audio/pulse_stubs.c
+  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    VBoxDD_SOURCES.freebsd+= \
+ 	  Audio/DrvHostPulseAudio.c \
+	  Audio/pulse_stubs.c
+  else
+    VBoxDD_SOURCES.freebsd+= \
+ 	  Audio/pulseaudio.c \
+ 	  Audio/pulse_stubs.c
+  endif
  endif
 
@@ -631,18 +661,34 @@
 
  ifeq ($(KBUILD_TARGET),freebsd)
-  VBoxDD_SOURCES        := \
-  	$(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) \
-  	Audio/ossaudio.c \
-  	Serial/DrvHostSerial.cpp
-  VBoxDD_SOURCES.freebsd += \
- 	Network/DrvTAP.cpp
+  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    VBoxDD_SOURCES        := \
+  	  $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) \
+  	  Audio/DrvHostOssAudio.c \
+  	  Serial/DrvHostSerial.cpp
+    VBoxDD_SOURCES.freebsd += \
+ 	  Network/DrvTAP.cpp
+  else
+    VBoxDD_SOURCES        := \
+  	  $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) \
+  	  Audio/ossaudio.c \
+  	  Serial/DrvHostSerial.cpp
+    VBoxDD_SOURCES.freebsd += \
+ 	  Network/DrvTAP.cpp
+  endif
  endif # freebsd
 
  VBoxDD_SOURCES.linux  += \
  	Network/DrvTAP.cpp \
- 	Audio/ossaudio.c \
  	Parallel/DrvHostParallel.cpp \
  	Serial/DrvHostSerial.cpp
 
+ ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+  VBoxDD_SOURCES.linux  += \
+    Audio/DrvHostOssAudio.c
+ else
+   VBoxDD_SOURCES.linux  += \
+ 	 Audio/ossaudio.c 
+ endif
+  
  ifeq ($(KBUILD_TARGET),os2)
  VBoxDD_SOURCES        := $(filter-out Storage/DrvHost%, $(VBoxDD_SOURCES))
@@ -650,11 +696,21 @@
 
  ifeq ($(KBUILD_TARGET),solaris)
- VBoxDD_SOURCES        := $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES))
- VBoxDD_SOURCES.solaris += \
- 	Audio/solaudio.c \
+  VBoxDD_SOURCES        := $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES))
+  VBoxDD_SOURCES.solaris += \
  	Serial/DrvHostSerial.cpp
+  ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    VBoxDD_SOURCES.solaris += \
+ 	  Audio/DrvHostSolAudio.c
+  else
+    VBoxDD_SOURCES.solaris += \
+ 	  Audio/solaudio.c 
+  endif
   ifdef VBOX_WITH_SOLARIS_OSS
-   VBoxDD_SOURCES += Audio/ossaudio.c
-   VBoxDD_DEFS += VBOX_WITH_SOLARIS_OSS
+    ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+      VBoxDD_SOURCES += Audio/DrvHostOssAudio.c
+    else
+      VBoxDD_SOURCES += Audio/ossaudio.c
+    endif
+    VBoxDD_DEFS += VBOX_WITH_SOLARIS_OSS
   endif
   ifdef VBOX_WITH_SUID_WRAPPER
@@ -664,8 +720,18 @@
 
  VBoxDD_DEFS.win       += VBOX_WITH_WIN_PARPORT_SUP
+ ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+   VBoxDD_DEFS.win       += VBOX_WITH_PDM_AUDIO_DRIVER
+ endif
  VBoxDD_SOURCES.win    += \
- 	Audio/dsoundaudio.c \
  	Serial/DrvHostSerial.cpp \
 	Parallel/DrvHostParallel.cpp
+
+ ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+ VBoxDD_SOURCES.win    += \
+   Audio/DrvHostDSound.c
+ else
+ VBoxDD_SOURCES.win    += \
+   Audio/dsoundaudio.c 
+ endif
 
  if defined(VBOX_WITH_NETFLT)
Index: /trunk/src/VBox/Devices/build/VBoxDD.cpp
===================================================================
--- /trunk/src/VBox/Devices/build/VBoxDD.cpp	(revision 50685)
+++ /trunk/src/VBox/Devices/build/VBoxDD.cpp	(revision 50686)
@@ -127,7 +127,13 @@
     if (RT_FAILURE(rc))
         return rc;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    //rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceAudioVRDE);
+    //if (RT_FAILURE(rc))
+    //    return rc;
+#else
     rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceAudioSniffer);
     if (RT_FAILURE(rc))
         return rc;
+#endif
 #ifdef VBOX_WITH_VUSB
     rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceOHCI);
@@ -266,4 +272,31 @@
     if (RT_FAILURE(rc))
         return rc;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+# if defined(RT_OS_WINDOWS)
+    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostDSound);
+    if (RT_FAILURE(rc))
+        return rc;
+# endif
+# if defined(RT_OS_LINUX)
+    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostPulseAudio);
+    if (RT_FAILURE(rc))
+        return rc;
+# endif
+# if defined(RT_OS_FREEBSD)
+    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostOssAudio);
+    if (RT_FAILURE(rc))
+        return rc;
+# endif
+# if defined(RT_OS_DARWIN)
+    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostCoreAudio);
+    if (RT_FAILURE(rc))
+        return rc;
+# endif
+# if defined(RT_OS_SOLARIS)
+    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostSolAudio);
+    if (RT_FAILURE(rc))
+        return rc;
+# endif
+#endif
     rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvACPI);
     if (RT_FAILURE(rc))
Index: /trunk/src/VBox/Devices/build/VBoxDD.h
===================================================================
--- /trunk/src/VBox/Devices/build/VBoxDD.h	(revision 50685)
+++ /trunk/src/VBox/Devices/build/VBoxDD.h	(revision 50686)
@@ -56,5 +56,7 @@
 extern const PDMDEVREG g_DeviceSB16;
 extern const PDMDEVREG g_DeviceICH6_HDA;
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
 extern const PDMDEVREG g_DeviceAudioSniffer;
+#endif
 extern const PDMDEVREG g_DeviceOHCI;
 extern const PDMDEVREG g_DeviceEHCI;
@@ -111,4 +113,21 @@
 extern const PDMDRVREG g_DrvNetSniffer;
 extern const PDMDRVREG g_DrvAUDIO;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+# if defined(RT_OS_WINDOWS)
+extern const PDMDRVREG g_DrvHostDSound;
+# endif
+# if defined(RT_OS_LINUX)
+extern const PDMDRVREG g_DrvHostPulseAudio;
+# endif
+# if defined(RT_OS_DARWIN)
+extern const PDMDRVREG g_DrvHostCoreAudio;
+# endif
+# if defined(RT_OS_SOLARIS)
+extern const PDMDRVREG g_DrvHostSolAudio;
+# endif
+# if defined(RT_OS_FREEBSD)
+extern const PDMDRVREG g_DrvHostOssAudio;
+# endif
+#endif
 extern const PDMDRVREG g_DrvACPI;
 extern const PDMDRVREG g_DrvAcpiCpu;
Index: /trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Main/Makefile.kmk	(revision 50685)
+++ /trunk/src/VBox/Main/Makefile.kmk	(revision 50686)
@@ -282,4 +282,5 @@
 	$(if $(VBOX_WITH_S3),VBOX_WITH_S3,) \
 	$(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,) \
+	$(if $(VBOX_WITH_PDM_AUDIO_DRIVER),VBOX_WITH_PDM_AUDIO_DRIVER,) \
 	$(if $(VBOX_WITH_NAT_SERVICE),VBOX_WITH_NAT_SERVICE,) \
 	$(if $(VBOX_WITH_CROGL),VBOX_WITH_CROGL,) \
@@ -615,5 +616,6 @@
 	$(if $(VBOX_WITH_EXTPACK),VBOX_WITH_EXTPACK,) \
 	$(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,) \
-	$(if $(VBOX_WITH_VPX),VBOX_WITH_VPX,)
+	$(if $(VBOX_WITH_VPX),VBOX_WITH_VPX,) \
+	$(if $(VBOX_WITH_PDM_AUDIO_DRIVER),VBOX_WITH_PDM_AUDIO_DRIVER,)
 ifdef VBOX_WITH_CRHGSMI
  VBoxC_DEFS += VBOX_WITH_CRHGSMI
@@ -693,5 +695,4 @@
 	src-client/Nvram.cpp \
 	src-client/AdditionsFacilityImpl.cpp \
-	src-client/AudioSnifferInterface.cpp \
 	src-client/BusAssignmentManager.cpp \
 	$(if $(VBOX_WITH_PCI_PASSTHROUGH),src-client/PCIRawDevImpl.cpp,) \
@@ -721,4 +722,11 @@
 	$(VBOX_AUTOGEN_EVENT_CPP) \
 	$(VBOX_XML_SCHEMADEFS_CPP)
+ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+ VBoxC_SOURCES += \
+	src-client/DrvAudioVRDE.cpp
+else
+ VBoxC_SOURCES += \
+	src-client/AudioSnifferInterface.cpp
+endif 
 VBoxC_SOURCES.win = \
 	src-client/win/dllmain.cpp \
Index: /trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 50685)
+++ /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 50686)
@@ -34,5 +34,9 @@
 class VRDEServerInfo;
 class EmulatedUSB;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+class AudioVRDE;
+#else
 class AudioSniffer;
+#endif
 class Nvram;
 #ifdef VBOX_WITH_USB_CARDREADER
@@ -190,5 +194,9 @@
     Display *getDisplay() const { return mDisplay; }
     MachineDebugger *getMachineDebugger() const { return mDebugger; }
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    AudioVRDE *getAudioVRDE() const { return mAudioVRDE; }
+#else
     AudioSniffer *getAudioSniffer() const { return mAudioSniffer; }
+#endif
 
     const ComPtr<IMachine> &machine() const { return mMachine; }
@@ -235,5 +243,10 @@
     int hgcmLoadService(const char *pszServiceLibrary, const char *pszServiceName);
     VMMDev *getVMMDev() { return m_pVMMDev; }
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    AudioVRDE *getAudioVRDE() { return mAudioVRDE; }
+#else
     AudioSniffer *getAudioSniffer() { return mAudioSniffer; }
+#endif
+
 #ifdef VBOX_WITH_EXTPACK
     ExtPackManager *getExtPackManager();
@@ -825,5 +838,9 @@
 
     VMMDev * m_pVMMDev;
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    AudioVRDE * const mAudioVRDE;
+#else
     AudioSniffer * const mAudioSniffer;
+#endif
     Nvram   * const mNvram;
 #ifdef VBOX_WITH_USB_CARDREADER
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 50685)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 50686)
@@ -56,5 +56,9 @@
 #include "RemoteUSBDeviceImpl.h"
 #include "SharedFolderImpl.h"
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+#include "DrvAudioVRDE.h"
+#else
 #include "AudioSnifferInterface.h"
+#endif
 #include "Nvram.h"
 #ifdef VBOX_WITH_USB_CARDREADER
@@ -404,5 +408,7 @@
     , mpVmm2UserMethods(NULL)
     , m_pVMMDev(NULL)
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
     , mAudioSniffer(NULL)
+#endif
     , mNvram(NULL)
 #ifdef VBOX_WITH_USB_CARDREADER
@@ -564,6 +570,11 @@
         //     AssertReturn(mVMMDev, E_FAIL);
 
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        unconst(mAudioVRDE) = new AudioVRDE(this);
+        AssertComRCReturnRC(rc);
+#else
         unconst(mAudioSniffer) = new AudioSniffer(this);
         AssertReturn(mAudioSniffer, E_FAIL);
+#endif
 
         FirmwareType_T enmFirmwareType;
@@ -683,5 +694,5 @@
     }
 #endif
-
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
     if (mAudioSniffer)
     {
@@ -689,4 +700,5 @@
         unconst(mAudioSniffer) = NULL;
     }
+#endif
 
     // if the VM had a VMMDev with an HGCM thread, then remove that here
@@ -1389,4 +1401,5 @@
         if (mcAudioRefs <= 0)
         {
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
             if (mAudioSniffer)
             {
@@ -1397,4 +1410,5 @@
                 }
             }
+#endif
         }
     }
@@ -1430,8 +1444,9 @@
     AutoCaller autoCaller(this);
     AssertComRCReturnVoid(autoCaller.rc());
-
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
     LogFlowFunc(("mAudioSniffer %p, u32ClientId %d.\n",
                  mAudioSniffer, u32ClientId));
     NOREF(u32ClientId);
+#endif
 
     ++mcAudioRefs;
@@ -1439,4 +1454,5 @@
     if (mcAudioRefs == 1)
     {
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
         if (mAudioSniffer)
         {
@@ -1447,4 +1463,5 @@
             }
         }
+#endif
     }
 
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 50685)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 50686)
@@ -2503,4 +2503,5 @@
         attachStatusDriver(pInst, &mapSharedFolderLed, 0, 0, NULL, NULL, 0);
 
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
         /*
          * Audio Sniffer Device
@@ -2516,4 +2517,5 @@
         AudioSniffer *pAudioSniffer = mAudioSniffer;
         InsertConfigInteger(pCfg,  "Object", (uintptr_t)pAudioSniffer);
+#endif
 
         /*
@@ -2569,5 +2571,11 @@
             /* the Audio driver */
             InsertConfigNode(pInst,    "LUN#0", &pLunL0);
-            InsertConfigString(pLunL0, "Driver",               "AUDIO");
+            InsertConfigString(pLunL0, "Driver", "AUDIO");
+
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
+            InsertConfigString(pLunL1, "Driver", "PulseAudio");
+#endif
+
             InsertConfigNode(pLunL0,   "Config", &pCfg);
 
@@ -2591,5 +2599,9 @@
                 case AudioDriverType_DirectSound:
                 {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                    InsertConfigString(pCfg, "AudioDriver", "DSoundAudio");
+#else
                     InsertConfigString(pCfg, "AudioDriver", "dsound");
+#endif
                     break;
                 }
@@ -2606,5 +2618,9 @@
                 case AudioDriverType_ALSA:
                 {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                    InsertConfigString(pCfg, "AudioDriver", "AlsaAudio");
+#else
                     InsertConfigString(pCfg, "AudioDriver", "alsa");
+#endif
                     break;
                 }
@@ -2613,5 +2629,9 @@
                 case AudioDriverType_Pulse:
                 {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                    InsertConfigString(pCfg, "AudioDriver", "PulseAudio");
+#else
                     InsertConfigString(pCfg, "AudioDriver", "pulse");
+#endif
                     break;
                 }
@@ -2629,5 +2649,9 @@
                 case AudioDriverType_Pulse:
                 {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                    InsertConfigString(pCfg, "AudioDriver", "PulseAudio");
+#else
                     InsertConfigString(pCfg, "AudioDriver", "pulse");
+#endif
                     break;
                 }
@@ -2644,4 +2668,18 @@
             hrc = pMachine->COMGETTER(Name)(bstr.asOutParam());                             H();
             InsertConfigString(pCfg, "StreamName", bstr);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            /* the Audio driver */
+            InsertConfigNode(pInst, "LUN#1", &pLunL0);
+            InsertConfigString(pLunL0, "Driver", "AUDIO");
+            InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
+            InsertConfigString(pLunL1, "Driver", "AudioVRDE");
+            InsertConfigNode(pLunL0, "Config", &pCfg);
+            InsertConfigString(pCfg, "AudioDriver", "AudioVRDE");
+            InsertConfigString(pCfg, "StreamName", bstr);
+            InsertConfigNode(pLunL1, "Config", &pCfg);
+            InsertConfigInteger(pCfg,  "Object", (uintptr_t)mAudioVRDE);
+            InsertConfigInteger(pCfg,  "ObjectVRDPServer", (uintptr_t)mConsoleVRDPServer);
+
+#endif
         }
 
Index: /trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp	(revision 50685)
+++ /trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp	(revision 50686)
@@ -21,5 +21,9 @@
 #include "KeyboardImpl.h"
 #include "MouseImpl.h"
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+#include "DrvAudioVRDE.h"
+#else
 #include "AudioSnifferInterface.h"
+#endif
 #ifdef VBOX_WITH_EXTPACK
 # include "ExtPackManagerImpl.h"
@@ -947,4 +951,7 @@
         ASMAtomicWriteU32(&server->mu32AudioInputClientId, 0);
 
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+        server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputIntercept(false);
+#else
         PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->getAudioSniffer()->getAudioSnifferPort();
         if (pPort)
@@ -956,4 +963,5 @@
             AssertFailed();
         }
+#endif
     }
 
@@ -1010,5 +1018,7 @@
             {
                 Log(("AUDIOIN: connected client %u\n", u32ClientId));
-
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+                server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputIntercept(true);
+#else
                 PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->getAudioSniffer()->getAudioSnifferPort();
                 if (pPort)
@@ -1026,4 +1036,5 @@
                     rc = VERR_NOT_SUPPORTED;
                 }
+#endif
             }
             else
@@ -1294,6 +1305,7 @@
 {
     ConsoleVRDPServer *server = static_cast<ConsoleVRDPServer*>(pvCallback);
-
+#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
     PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->getAudioSniffer()->getAudioSnifferPort();
+#endif
 
     switch (u32Event)
@@ -1302,5 +1314,12 @@
         {
             const VRDEAUDIOINBEGIN *pParms = (const VRDEAUDIOINBEGIN *)pvData;
-
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventBegin(pvCtx,
+                                                                                   VRDE_AUDIO_FMT_SAMPLE_FREQ(pParms->fmt),
+                                                                                   VRDE_AUDIO_FMT_CHANNELS(pParms->fmt),
+                                                                                   VRDE_AUDIO_FMT_BITS_PER_SAMPLE(pParms->fmt),
+                                                                                   VRDE_AUDIO_FMT_SIGNED(pParms->fmt)
+                                                                                  );
+#else
             pPort->pfnAudioInputEventBegin (pPort, pvCtx,
                                             VRDE_AUDIO_FMT_SAMPLE_FREQ(pParms->fmt),
@@ -1309,14 +1328,23 @@
                                             VRDE_AUDIO_FMT_SIGNED(pParms->fmt)
                                            );
+#endif
         } break;
 
         case VRDE_AUDIOIN_DATA:
         {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventData(pvCtx, pvData, cbData);
+#else
             pPort->pfnAudioInputEventData (pPort, pvCtx, pvData, cbData);
+#endif
         } break;
 
         case VRDE_AUDIOIN_END:
         {
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventEnd(pvCtx);
+#else
             pPort->pfnAudioInputEventEnd (pPort, pvCtx);
+#endif
         } break;
 
@@ -1336,5 +1364,4 @@
     mcClipboardRefs = 0;
     mpfnClipboardCallback = NULL;
-
 #ifdef VBOX_WITH_USB
     mUSBBackends.pHead = NULL;
@@ -3880,8 +3907,12 @@
                                             audioFormat,
                                             cSamples);
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+            //*ppvUserCtx = NULL;
+#else
             *ppvUserCtx = NULL; /* This is the ConsoleVRDPServer context.
-                                 * Currently not used because only one client is allowed to
-                                 * do audio input and the client id is saved by the ConsoleVRDPServer.
-                                 */
+-                                * Currently not used because only one client is allowed to
+-                                * do audio input and the client id is saved by the ConsoleVRDPServer.
+-                                */
+#endif
 
             return VINF_SUCCESS;
Index: /trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp	(revision 50686)
+++ /trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp	(revision 50686)
@@ -0,0 +1,1059 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox Audio VRDE backend
+ */
+
+/*
+ * Copyright (C) 2006-2010 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.
+ */
+#include "DrvAudioVRDE.h"
+#include "ConsoleImpl.h"
+#include "ConsoleVRDPServer.h"
+
+#include "Logging.h"
+
+#include <VBox/vmm/pdmaudioifs.h>
+#include <VBox/vmm/pdmdrv.h>
+#include <VBox/RemoteDesktop/VRDE.h>
+#include <VBox/vmm/cfgm.h>
+#include <VBox/err.h>
+#include <iprt/mem.h>
+#include <iprt/cdefs.h>
+
+
+/*******************************************************************************
+ *
+ * IO Ring Buffer section
+ *
+ ******************************************************************************/
+
+/* Implementation of a lock free ring buffer which could be used in a multi
+ * threaded environment. Note that only the acquire, release and getter
+ * functions are threading aware. So don't use reset if the ring buffer is
+ * still in use. */
+typedef struct IORINGBUFFER
+{
+    /* The current read position in the buffer */
+    uint32_t uReadPos;
+    /* The current write position in the buffer */
+    uint32_t uWritePos;
+    /* How much space of the buffer is currently in use */
+    volatile uint32_t cBufferUsed;
+    /* How big is the buffer */
+    uint32_t cBufSize;
+    /* The buffer itself */
+    char *pBuffer;
+} IORINGBUFFER;
+/* Pointer to an ring buffer structure */
+typedef IORINGBUFFER* PIORINGBUFFER;
+
+PPDMDRVINS gpDrvIns; //@todo handle this bad programming;
+
+static void IORingBufferCreate(PIORINGBUFFER *ppBuffer, uint32_t cSize)
+{
+    PIORINGBUFFER pTmpBuffer;
+
+    AssertPtr(ppBuffer);
+
+    *ppBuffer = NULL;
+    pTmpBuffer = RTMemAllocZ(sizeof(IORINGBUFFER));
+    if (pTmpBuffer)
+    {
+        pTmpBuffer->pBuffer = RTMemAlloc(cSize);
+        if(pTmpBuffer->pBuffer)
+        {
+            pTmpBuffer->cBufSize = cSize;
+            *ppBuffer = pTmpBuffer;
+        }
+        else
+            RTMemFree(pTmpBuffer);
+    }
+}
+
+static void IORingBufferDestroy(PIORINGBUFFER pBuffer)
+{
+    if (pBuffer)
+    {
+        if (pBuffer->pBuffer)
+            RTMemFree(pBuffer->pBuffer);
+        RTMemFree(pBuffer);
+    }
+}
+
+DECL_FORCE_INLINE(void) IORingBufferReset(PIORINGBUFFER pBuffer)
+{
+    AssertPtr(pBuffer);
+
+    pBuffer->uReadPos = 0;
+    pBuffer->uWritePos = 0;
+    pBuffer->cBufferUsed = 0;
+}
+
+DECL_FORCE_INLINE(uint32_t) IORingBufferFree(PIORINGBUFFER pBuffer)
+{
+    AssertPtr(pBuffer);
+    return pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed);
+}
+
+DECL_FORCE_INLINE(uint32_t) IORingBufferUsed(PIORINGBUFFER pBuffer)
+{
+    AssertPtr(pBuffer);
+    return ASMAtomicReadU32(&pBuffer->cBufferUsed);
+}
+
+DECL_FORCE_INLINE(uint32_t) IORingBufferSize(PIORINGBUFFER pBuffer)
+{
+    AssertPtr(pBuffer);
+    return pBuffer->cBufSize;
+}
+
+static void IORingBufferAquireReadBlock(PIORINGBUFFER pBuffer, uint32_t cReqSize, char **ppStart, uint32_t *pcSize)
+{
+    uint32_t uUsed = 0;
+    uint32_t uSize = 0;
+
+    AssertPtr(pBuffer);
+
+    *ppStart = 0;
+    *pcSize = 0;
+
+    /* How much is in use? */
+    uUsed = ASMAtomicReadU32(&pBuffer->cBufferUsed);
+    if (uUsed > 0)
+    {
+        /* Get the size out of the requested size, the read block till the end
+         * of the buffer & the currently used size. */
+        uSize = RT_MIN(cReqSize, RT_MIN(pBuffer->cBufSize - pBuffer->uReadPos, uUsed));
+        if (uSize > 0)
+        {
+            /* Return the pointer address which point to the current read
+             * position. */
+            *ppStart = pBuffer->pBuffer + pBuffer->uReadPos;
+            *pcSize = uSize;
+        }
+    }
+}
+
+DECL_FORCE_INLINE(void) IORingBufferReleaseReadBlock(PIORINGBUFFER pBuffer, uint32_t cSize)
+{
+    AssertPtr(pBuffer);
+
+    /* Split at the end of the buffer. */
+    pBuffer->uReadPos = (pBuffer->uReadPos + cSize) % pBuffer->cBufSize;
+    ASMAtomicSubU32(&pBuffer->cBufferUsed, cSize);
+}
+
+static void IORingBufferAquireWriteBlock(PIORINGBUFFER pBuffer, uint32_t cReqSize, char **ppStart, uint32_t *pcSize)
+{
+    uint32_t uFree;
+    uint32_t uSize;
+
+    AssertPtr(pBuffer);
+
+    *ppStart = 0;
+    *pcSize = 0;
+
+    /* How much is free? */
+    uFree = pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed);
+    if (uFree > 0)
+    {
+        /* Get the size out of the requested size, the write block till the end
+         * of the buffer & the currently free size. */
+        uSize = RT_MIN(cReqSize, RT_MIN(pBuffer->cBufSize - pBuffer->uWritePos, uFree));
+        if (uSize > 0)
+        {
+            /* Return the pointer address which point to the current write
+             * position. */
+            *ppStart = pBuffer->pBuffer + pBuffer->uWritePos;
+            *pcSize = uSize;
+        }
+    }
+}
+
+DECL_FORCE_INLINE(void) IORingBufferReleaseWriteBlock(PIORINGBUFFER pBuffer, uint32_t cSize)
+{
+    AssertPtr(pBuffer);
+
+    /* Split at the end of the buffer. */
+    pBuffer->uWritePos = (pBuffer->uWritePos + cSize) % pBuffer->cBufSize;
+
+    ASMAtomicAddU32(&pBuffer->cBufferUsed, cSize);
+}
+
+/****************** Ring Buffer Function Ends *****************/
+
+//@todo need to see if they need to move to pdmifs.h
+#define AUDIO_HOST_ENDIANNESS 0
+#define VOICE_ENABLE 1
+#define VOICE_DISABLE 2
+
+
+/* Initialization status indicator used for the recreation of the AudioUnits. */
+#define CA_STATUS_UNINIT    UINT32_C(0) /* The device is uninitialized */
+#define CA_STATUS_IN_INIT   UINT32_C(1) /* The device is currently initializing */
+#define CA_STATUS_INIT      UINT32_C(2) /* The device is initialized */
+#define CA_STATUS_IN_UNINIT UINT32_C(3) /* The device is currently uninitializing */
+
+//@todo move t_sample as a PDM interface
+//typedef struct { int mute;  uint32_t r; uint32_t l; } volume_t;
+
+#define INT_MAX         0x7fffffff
+volume_t nominal_volume = {
+    0,
+    INT_MAX,
+    INT_MAX
+};
+
+/* The desired buffer length in milliseconds. Will be the target total stream
+ * latency on newer version of pulse. Apparent latency can be less (or more.)
+ * In case its need to be used. Currently its not used.
+ */
+#if 0
+static struct
+{
+    int         buffer_msecs_out;
+    int         buffer_msecs_in;
+} confAudioVRDE
+=
+{
+    INIT_FIELD (.buffer_msecs_out = ) 100,
+    INIT_FIELD (.buffer_msecs_in  = ) 100,
+};
+#endif
+/**
+ * Audio VRDE driver instance data.
+ *
+ * @extends PDMIAUDIOSNIFFERCONNECTOR
+ */
+typedef struct DRVAUDIOVRDE
+{
+    /** Pointer to audio VRDE object */
+    AudioVRDE           *pAudioVRDE;
+    PPDMDRVINS          pDrvIns;
+    /** Pointer to the driver instance structure. */
+    PDMIHOSTAUDIO       IHostAudioR3;
+    ConsoleVRDPServer *pConsoleVRDPServer;
+    /** Pointer to the DrvAudio port interface that is above it. */
+    PPDMIAUDIOCONNECTOR       pUpPort;
+} DRVAUDIOVRDE, *PDRVAUDIOVRDE;
+typedef struct PDMHOSTVOICEOUT PDMHOSTVOICEOUT;
+typedef PDMHOSTVOICEOUT *PPDMHOSTVOICEOUT;
+
+typedef struct VRDEVoice
+{
+    /* Audio and audio details for recording */
+    PDMHOSTVOICEIN   pHostVoiceIn;
+    void * pvUserCtx;
+    /* Number of bytes per frame (bitsPerSample * channels) of the actual input format. */
+    uint32_t cBytesPerFrame;
+    /* Frequency of the actual audio format. */
+    uint32_t uFrequency;
+    /* If the actual format frequence differs from the requested format, this is not NULL. */
+    void *rate;
+    /* Temporary buffer for st_sample_t representation of the input audio data. */
+    void *pvSamplesBuffer;
+    /* buffer for bytes of samples (not rate converted) */
+    uint32_t cbSamplesBufferAllocated;
+    /* Temporary buffer for frequency conversion. */
+    void *pvRateBuffer;
+    /* buffer for bytes rate converted samples */
+    uint32_t cbRateBufferAllocated;
+    /* A ring buffer for transferring data to the playback thread */
+    PIORINGBUFFER pRecordedVoiceBuf;
+    t_sample * convAudioDevFmtToStSampl;
+    uint32_t fIsInit;
+    uint32_t status;
+};
+typedef VRDEVoice *PVRDEVoice;
+
+typedef struct VRDEVoiceOut
+{
+    PDMHOSTVOICEOUT pHostVoiceOut;
+    uint64_t old_ticks;
+    uint64_t cSamplesSentPerSec;
+};
+typedef VRDEVoiceOut * PVRDEVoiceOut;
+
+/** Makes a PDRVBLOCK out of a PPDMIBLOCK. */
+#define PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface)        ( (PDRVAUDIOVRDE)((uintptr_t)pInterface - RT_OFFSETOF(DRVAUDIOVRDE, IHostAudioR3)) )
+
+AudioVRDE::AudioVRDE(Console *console)
+    : mpDrv(NULL),
+      mParent(console)
+{
+}
+
+AudioVRDE::~AudioVRDE()
+{
+    if (mpDrv)
+    {
+        mpDrv->pAudioVRDE = NULL;
+        mpDrv = NULL;
+    }
+}
+
+PPDMIAUDIOCONNECTOR AudioVRDE::getDrvAudioPort()
+{
+    Assert(mpDrv);
+    return mpDrv->pUpPort;
+}
+
+void AudioVRDE::handleVRDESvrCmdAudioInputIntercept(bool fIntercept)
+{
+    LogFlow(("AudioVRDE: handleVRDPCmdInputIntercept\n"));
+}
+
+static DECLCALLBACK(void *)  drvAudioVRDEInit(PPDMIHOSTAUDIO pInterface)
+{
+    LogFlow(("drvAudioVRDEInit \n"));
+    return 1;
+}
+
+static void drvAudioVRDEPcmInitInfo(PDMPCMPROPERTIES * pProps, audsettings_t *as)
+{
+    int bits = 8, sign = 0, shift = 0;
+    LogFlow(("AudioVRDE: PcmInitInfo \n"));
+
+    switch (as->fmt) {
+    case AUD_FMT_S8:
+        sign = 1;
+    case AUD_FMT_U8:
+        break;
+
+    case AUD_FMT_S16:
+        sign = 1;
+    case AUD_FMT_U16:
+        bits = 16;
+        shift = 1;
+        break;
+
+    case AUD_FMT_S32:
+        sign = 1;
+    case AUD_FMT_U32:
+        bits = 32;
+        shift = 2;
+        break;
+    }
+
+    pProps->uFrequency = as->freq;
+    pProps->cBits = bits;
+    pProps->fSigned = sign;
+    pProps->cChannels = as->nchannels;
+    pProps->cShift = (as->nchannels == 2) + shift;
+    pProps->fAlign = (1 << pProps->cShift) - 1;
+    pProps->cbPerSec = pProps->uFrequency << pProps->cShift;
+    pProps->fSwapEndian = (as->endianness != AUDIO_HOST_ENDIANNESS);
+}
+
+/*
+ * Hard voice (playback)
+ */
+static int audio_pcm_hw_find_min_out (PPDMHOSTVOICEOUT hw, int *nb_livep)
+{
+    PPDMGSTVOICEOUT sw;
+    PPDMGSTVOICEOUT pIter;
+    int m = INT_MAX;
+    int nb_live = 0;
+    LogFlow(("Hard Voice Playback \n"));
+
+    RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut)
+    {
+        sw = pIter;
+        if (sw->State.fActive || !sw->State.fEmpty)
+        {
+            m = audio_MIN (m, sw->cSamplesMixed);
+            nb_live += 1;
+        }
+    }
+
+    *nb_livep = nb_live;
+    return m;
+}
+
+int audio_pcm_hw_get_live_out2 (PPDMHOSTVOICEOUT hw, int *nb_live)
+{
+    int smin;
+
+    smin = audio_pcm_hw_find_min_out (hw, nb_live);
+
+    if (!*nb_live) {
+        return 0;
+    }
+    else
+    {
+        int live = smin;
+
+        if (live < 0 || live > hw->cSamples)
+        {
+            LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
+            return 0;
+        }
+        return live;
+    }
+}
+
+
+int audio_pcm_hw_get_live_out (PPDMHOSTVOICEOUT hw)
+{
+    int nb_live;
+    int live;
+
+    live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
+    if (live < 0 || live > hw->cSamples)
+    {
+        LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
+        return 0;
+    }
+    return live;
+}
+
+/*
+ * Hard voice (capture)
+ */
+static int audio_pcm_hw_find_min_in (PPDMHOSTVOICEIN hw)
+{
+    PPDMGSTVOICEIN pIter;
+    int m = hw->cSamplesCaptured;
+
+    RTListForEach(&hw->HeadGstVoiceIn, pIter, PDMGSTVOICEIN, ListGstVoiceIn)
+    {
+        if (pIter->State.fActive)
+        {
+            m = audio_MIN (m, pIter->cHostSamplesAcquired);
+        }
+    }
+    return m;
+}
+
+int audio_pcm_hw_get_live_in (PPDMHOSTVOICEIN hw)
+{
+    int live = hw->cSamplesCaptured - audio_pcm_hw_find_min_in (hw);
+    if (live < 0 || live > hw->cSamples)
+    {
+        LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
+        return 0;
+    }
+    return live;
+}
+
+static inline void *advance (void *p, int incr)
+{
+    uint8_t *d = (uint8_t*)p;
+    return (d + incr);
+}
+
+uint64_t audio_get_ticks_per_sec (void)
+{
+    return PDMDrvHlpTMGetVirtualFreq (gpDrvIns);
+}
+
+uint64_t audio_get_clock (void)
+{
+    return PDMDrvHlpTMGetVirtualTime (gpDrvIns);
+}
+
+void VRDEReallocSampleBuf(PVRDEVoice pVRDEVoice, uint32_t cSamples)
+{
+    uint32_t cbBuffer = cSamples * sizeof(PDMHOSTSTEREOSAMPLE);
+    if (cbBuffer > pVRDEVoice->cbSamplesBufferAllocated)
+    {
+        if (pVRDEVoice->pvSamplesBuffer)
+        {
+            RTMemFree(pVRDEVoice->pvSamplesBuffer);
+            pVRDEVoice->pvSamplesBuffer = NULL;
+        }
+        pVRDEVoice->pvSamplesBuffer = RTMemAlloc(cbBuffer);
+        if (pVRDEVoice->pvSamplesBuffer)
+            pVRDEVoice->cbSamplesBufferAllocated = cbBuffer;
+        else
+            pVRDEVoice->cbSamplesBufferAllocated = 0;
+    }
+
+}
+
+void VRDEReallocRateAdjSampleBuf(PVRDEVoice pVRDEVoice, uint32_t cSamples)
+{
+    uint32_t cbBuffer = cSamples * sizeof(PDMHOSTSTEREOSAMPLE);
+    if (cbBuffer > pVRDEVoice->cbRateBufferAllocated)
+    {
+        RTMemFree(pVRDEVoice->pvRateBuffer);
+        pVRDEVoice->pvRateBuffer = RTMemAlloc(cbBuffer);
+        if (pVRDEVoice->pvRateBuffer)
+            pVRDEVoice->cbRateBufferAllocated = cbBuffer;
+        else
+            pVRDEVoice->cbRateBufferAllocated = 0;
+    }
+}
+
+/*******************************************************************************
+ *
+ * AudioVRDE input section
+ *
+ ******************************************************************************/
+
+/*
+ * Callback to feed audio input buffer. Samples format is be the same as
+ * in the voice. The caller prepares st_sample_t.
+ *
+ * @param cbSamples Size of pvSamples array in bytes.
+ * @param pvSamples Points to an array of samples.
+ *
+ * @return IPRT status code.
+ */
+static int fltRecordingCallback(PVRDEVoice pVRDEVoice, uint32_t cbSamples, const void *pvSamples)
+{
+    int rc = VINF_SUCCESS;
+    uint32_t csAvail = 0;
+    uint32_t csToWrite = 0;
+    uint32_t cbToWrite = 0;
+    uint32_t csWritten = 0;
+    char *pcDst = NULL;
+
+    LogFlow(("audio-filter: fltRecordingCallback\n"));
+
+    Assert((cbSamples % sizeof(PDMHOSTSTEREOSAMPLE)) == 0);
+
+    if (!pVRDEVoice->fIsInit)
+        return VINF_SUCCESS;
+
+    /* If nothing is pending return immediately. */
+    if (cbSamples == 0)
+        return VINF_SUCCESS;
+
+    /* How much space is free in the ring buffer? */
+    PPDMHOSTSTEREOSAMPLE psSrc;
+    csAvail = IORingBufferFree(pVRDEVoice->pRecordedVoiceBuf) / sizeof(PDMHOSTSTEREOSAMPLE); /* bytes -> samples */
+
+    /* How much space is used in the audio buffer. Use the smaller size of the too. */
+    csAvail = RT_MIN(csAvail, cbSamples / sizeof(PDMHOSTSTEREOSAMPLE));
+
+    /* Iterate as long as data is available */
+    while(csWritten < csAvail)
+    {
+        /* How much is left? */
+        csToWrite = csAvail - csWritten;
+        cbToWrite = csToWrite * sizeof(PDMHOSTSTEREOSAMPLE);
+
+        /* Try to acquire the necessary space from the ring buffer. */
+        IORingBufferAquireWriteBlock(pVRDEVoice->pRecordedVoiceBuf, cbToWrite, &pcDst, &cbToWrite);
+
+        /* How much do we get? */
+        csToWrite = cbToWrite / sizeof(PDMHOSTSTEREOSAMPLE);
+
+            /* Break if nothing is free anymore. */
+        if (RT_UNLIKELY(csToWrite == 0))
+            break;
+
+        /* Copy the data from the audio buffer to the ring buffer in PVRDEVoice. */
+        memcpy(pcDst, (uint8_t *)pvSamples + (csWritten * sizeof(PDMHOSTSTEREOSAMPLE)), cbToWrite);
+
+        /* Release the ring buffer, so the main thread could start reading this data. */
+        IORingBufferReleaseWriteBlock(pVRDEVoice->pRecordedVoiceBuf, cbToWrite);
+
+        csWritten += csToWrite;
+    }
+
+    LogFlow(("AudioVRDE: [Input] Finished writing buffer with %RU32 samples (%RU32 bytes)\n",
+              csWritten, csWritten * sizeof(PDMHOSTSTEREOSAMPLE)));
+
+    return rc;
+}
+
+
+STDMETHODIMP AudioVRDE::handleVRDESvrCmdAudioInputEventBegin(void *pvContext, int iSampleHz, int cChannels, int cBits, bool fUnsigned)
+{
+    int bitIdx;
+    PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext;
+    LogFlow(("AudioVRDE: handleVRDPCmdInputEventBegin\n"));
+    /* Prepare a format convertion for the actually used format. */
+    pVRDEVoice->cBytesPerFrame = ((cBits + 7) / 8) * cChannels;
+    if (cBits == 16)
+    {
+        bitIdx = 1;
+    }
+    else if (cBits == 32)
+    {
+        bitIdx = 2;
+    }
+    else
+    {
+        bitIdx = 0;
+    }
+    //PPDMIAUDIOCONNECTOR pPort = server->mConsole->getAudioVRDE()->getDrvAudioPort();
+    /* Call DrvAudio interface to get the t_sample type conversion function */
+    pVRDEVoice->convAudioDevFmtToStSampl = mpDrv->pUpPort->pfnConvDevFmtToStSample(mpDrv->pUpPort,
+                                                                                   (cChannels == 2) ? 1 : 0,
+                                                                                   !fUnsigned, 0, bitIdx
+                                                                                  );
+    if (pVRDEVoice->convAudioDevFmtToStSampl)
+    {
+        LogFlow(("AudioVRDE: Failed to get the conversion function \n"));
+    }
+    LogFlow(("AudioVRDE: Required freq as requested by VRDP Server = %d\n", iSampleHz));
+    //if (iSampleHz && iSampleHz != pVRDEVoice->pHostVoiceIn.Props.uFrequency)
+    {
+        /* @todo if the above condition is false then pVRDEVoice->uFrequency will remain 0 */
+        pVRDEVoice->rate = mpDrv->pUpPort->pfnPrepareAudioConversion(mpDrv->pUpPort, iSampleHz,
+                                                                     pVRDEVoice->pHostVoiceIn.Props.uFrequency);
+        pVRDEVoice->uFrequency = iSampleHz;
+        LogFlow(("AudioVRDE: pVRDEVoice assigned requested freq =%d\n", pVRDEVoice->uFrequency));
+    }
+    return VINF_SUCCESS;
+}
+
+/*
+ * pvContext: pointer to VRDP voice returned by the VRDP server. The is same pointer that we initialized in
+ *            drvAudioVRDEDisableEnableIn VOICE_ENABLE case.
+ */
+void AudioVRDE::handleVRDESvrCmdAudioInputEventData(void *pvContext, const void *pvData, uint32_t cbData)
+{
+    PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext;
+    PPDMHOSTSTEREOSAMPLE pHostStereoSampleBuf; /* target sample buffer */
+    PPDMHOSTSTEREOSAMPLE pConvertedSampleBuf; /* samples adjusted for rate */
+    uint32_t cSamples = cbData / pVRDEVoice->cBytesPerFrame; /* Count of samples */
+    void * pTmpSampleBuf = NULL;
+    uint32_t cConvertedSamples; /* samples adjusted for rate */
+    uint32_t cbSamples; /* count of bytes occupied by samples */
+    uint32_t rc;
+    LogFlow(("AudioVRDE: handleVRDPCmdInputEventData cbData = %d, bytesperfram=%d\n",
+              cbData, pVRDEVoice->cBytesPerFrame));
+
+    VRDEReallocSampleBuf(pVRDEVoice, cSamples);
+    pHostStereoSampleBuf = (PPDMHOSTSTEREOSAMPLE)pVRDEVoice->pvSamplesBuffer;
+    pVRDEVoice->convAudioDevFmtToStSampl(pHostStereoSampleBuf, pvData, cSamples, &nominal_volume);
+
+    /* count of rate adjusted samples */
+    pVRDEVoice->uFrequency = 22100; /* @todo handle this. How pVRDEVoice will get proper value */
+    cConvertedSamples = (cSamples * pVRDEVoice->pHostVoiceIn.Props.uFrequency) / pVRDEVoice->uFrequency;
+    VRDEReallocRateAdjSampleBuf(pVRDEVoice, cConvertedSamples);
+
+    pConvertedSampleBuf = (PPDMHOSTSTEREOSAMPLE)pVRDEVoice->pvRateBuffer;
+
+    if (pConvertedSampleBuf)
+    {
+        uint32_t cSampleSrc = cSamples;
+        uint32_t cSampleDst = cConvertedSamples;
+        mpDrv->pUpPort->pfnDoRateConversion(mpDrv->pUpPort, pVRDEVoice->rate, pHostStereoSampleBuf,
+                                            pConvertedSampleBuf, &cSampleSrc, &cConvertedSamples);
+        pTmpSampleBuf = pConvertedSampleBuf;
+        cbSamples =  cConvertedSamples * sizeof(PDMHOSTSTEREOSAMPLE);
+    }
+
+    if (cbSamples)
+    {
+        rc = fltRecordingCallback(pVRDEVoice, cbSamples, pTmpSampleBuf);
+    }
+}
+
+/*
+ * pvContext: pointer to VRDP voice returned by the VRDP server. The is same pointer that we initialized in
+ *            drvAudioVRDEDisableEnableIn VOICE_ENABLE case.
+ */
+void AudioVRDE::handleVRDESvrCmdAudioInputEventEnd(void *pvContext)
+{
+    PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext;
+    LogFlow(("AudioVRDE: handleVRDPCmdInputEventEnd\n"));
+     /* The caller will not use this context anymore. */
+    if (pVRDEVoice->rate)
+    {
+        mpDrv->pUpPort->pfnEndAudioConversion(mpDrv->pUpPort, pVRDEVoice->rate);
+    }
+
+    if (pVRDEVoice->pvSamplesBuffer)
+    {
+        RTMemFree(pVRDEVoice->pvSamplesBuffer);
+        pVRDEVoice->pvSamplesBuffer = NULL;
+    }
+    if(pVRDEVoice->pvRateBuffer)
+    {
+        RTMemFree(pVRDEVoice->pvRateBuffer);
+        pVRDEVoice->pvRateBuffer = NULL;
+    }
+}
+
+static DECLCALLBACK(int)  drvAudioVRDEInitOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut, audsettings_t *as)
+{
+    PDRVAUDIOVRDE pDrv =  PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
+    PVRDEVoiceOut pVRDEVoiceOut = (PVRDEVoiceOut)pHostVoiceOut;
+    LogFlow(("DrvAudioVRDEInitOut: audio input begin cShift=%d\n", pHostVoiceOut->Props.cShift));
+    pHostVoiceOut->cSamples =  6174;
+    drvAudioVRDEPcmInitInfo(&pVRDEVoiceOut->pHostVoiceOut.Props, as);
+    return VINF_SUCCESS;
+
+}
+
+static DECLCALLBACK(int) drvAudioVRDEInitIn (PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn, audsettings_t *as)
+{
+    LogFlow(("DrvAudioVRDE: drvAudioVRDEInitIn \n"));
+    PDRVAUDIOVRDE pDrv =  PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
+    PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn;
+    pHostVoiceIn->cSamples =  6174;
+    drvAudioVRDEPcmInitInfo(&pVRDEVoice->pHostVoiceIn.Props, as);
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) drvAudioVRDEPlayIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn)
+{
+    uint32_t cbAvlblRingBuffer = 0;
+    uint32_t cSamplesRingBuffer = 0;
+    uint32_t cSamplesToRead = 0;
+    uint32_t cSamplesRead = 0;
+    uint32_t cbToRead;
+    char *pcSrc;
+    PDMHOSTSTEREOSAMPLE * psDst;
+    //@todo take care of the size of the buffer allocated to pHostVoiceIn
+    PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn;
+    LogFlow(("DrvAudioVRDE: drvAudioVRDEPlayIn \n"));
+
+ /* use this from DrvHostCoreAudio.c */
+    if (ASMAtomicReadU32(&pVRDEVoice->status) != CA_STATUS_INIT)
+    {
+        LogFlow(("AudioVRDE: VRDE voice not initialized \n"));
+        return 0;
+    }
+
+    /* how much space is used in the ring buffer in pRecordedVocieBuf with pAudioVRDE . Bytes-> samples*/
+    cSamplesRingBuffer = IORingBufferUsed(pVRDEVoice->pRecordedVoiceBuf) / sizeof(PDMHOSTSTEREOSAMPLE);
+
+    /* How much space is available in the mix buffer. Use the smaller size of the too. */
+    cSamplesRingBuffer = RT_MIN(cSamplesRingBuffer, (uint32_t)(pVRDEVoice->pHostVoiceIn.cSamples -
+                               audio_pcm_hw_get_live_in (&pVRDEVoice->pHostVoiceIn)));
+    LogFlow(("AudioVRDE: [Input] Start reading buffer with %d samples (%d bytes)\n", cSamplesRingBuffer,
+              cSamplesRingBuffer * sizeof(PDMHOSTSTEREOSAMPLE)));
+
+    /* Iterate as long as data is available */
+    while (cSamplesRead < cSamplesRingBuffer)
+    {
+        /* How much is left? Split request at the end of our samples buffer. */
+        cSamplesToRead = RT_MIN(cSamplesRingBuffer - cSamplesRead,
+                                (uint32_t)(pVRDEVoice->pHostVoiceIn.cSamples - pVRDEVoice->pHostVoiceIn.offWrite));
+        cbToRead = cSamplesToRead * sizeof(PDMHOSTSTEREOSAMPLE);
+        LogFlow(("AudioVRDE: [Input] Try reading %RU32 samples (%RU32 bytes)\n", cSamplesToRead, cbToRead));
+
+        /* Try to acquire the necessary block from the ring buffer. Remeber in fltRecrodCallback we
+         * we are filling this buffer with the audio data available from VRDP. Here we are reading it
+         */
+        /*todo do I need to introduce a thread to fill the buffer in fltRecordcallback. So that
+         * filling is in separate thread and the reading of that buffer is in separate thread
+         */
+        IORingBufferAquireReadBlock(pVRDEVoice->pRecordedVoiceBuf, cbToRead, &pcSrc, &cbToRead);
+
+        /* How much to we get? */
+        cSamplesToRead = cbToRead / sizeof(PDMHOSTSTEREOSAMPLE);
+        LogFlow(("AuderVRDE: [Input] There are %d samples (%d bytes) available\n", cSamplesToRead, cbToRead));
+
+        /* Break if nothing is used anymore. */
+        if (cSamplesToRead == 0)
+        {
+            LogFlow(("AudioVRDE: Nothing to read \n"));
+            break;
+        }
+
+        /* Copy the data from our ring buffer to the mix buffer. */
+        psDst = pVRDEVoice->pHostVoiceIn.pConversionBuf + pVRDEVoice->pHostVoiceIn.offWrite;
+        memcpy(psDst, pcSrc, cbToRead);
+
+        /* Release the read buffer, so it could be used for new data. */
+        IORingBufferReleaseReadBlock(pVRDEVoice->pRecordedVoiceBuf, cbToRead);
+
+        pVRDEVoice->pHostVoiceIn.offWrite = (pVRDEVoice->pHostVoiceIn.offWrite + cSamplesToRead)
+                                              % pVRDEVoice->pHostVoiceIn.cSamples;
+
+        /* How much have we reads so far. */
+        cSamplesRead += cSamplesToRead;
+    }
+    LogFlow(("AudioVRDE: [Input] Finished reading buffer with %d samples (%d bytes)\n",
+               cSamplesRead, cSamplesRead * sizeof(PDMHOSTSTEREOSAMPLE)));
+
+    return cSamplesRead;
+}
+
+static DECLCALLBACK(int) drvAudioVRDEPlayOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut)
+{
+    PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
+    PVRDEVoiceOut pVRDEVoiceOut = (PVRDEVoiceOut)pHostVoiceOut;
+    int live;
+    uint8_t     *pu8Dst;
+    int cSamplesPlayed;
+    int cSamplesToSend = 0;
+    /*
+     * Just call the VRDP server with the data.
+     */
+    live = audio_pcm_hw_get_live_out (pHostVoiceOut);
+    uint64_t now = audio_get_clock();
+    uint64_t ticks = now  - pVRDEVoiceOut->old_ticks;
+    uint64_t ticks_per_second = audio_get_ticks_per_sec();
+    cSamplesPlayed = (int)((2 * ticks * pHostVoiceOut->Props.uFrequency + ticks_per_second) / ticks_per_second / 2);
+    if (cSamplesPlayed < 0)
+        cSamplesPlayed = live;
+    pHostVoiceOut->Props.cBits = 128;
+    VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(pHostVoiceOut->Props.uFrequency,
+                                                 pHostVoiceOut->Props.cChannels,
+                                                 pHostVoiceOut->Props.cBits, /* bits per sample */
+                                                 !pHostVoiceOut->Props.fSigned);
+    LogFlow(("DrvAudioVRDE: send audio sample freq=%d, chan=%d, cBits = %d, fsigned = %d, cSamples=%d format=%d \n",
+             pHostVoiceOut->Props.uFrequency, pHostVoiceOut->Props.cChannels,
+             pHostVoiceOut->Props.cBits, pHostVoiceOut->Props.fSigned,
+             pHostVoiceOut->cSamples, format)
+            );
+    pVRDEVoiceOut->old_ticks = now;
+    cSamplesToSend = RT_MIN(live, cSamplesPlayed);
+    if (pHostVoiceOut->offRead + cSamplesToSend > pHostVoiceOut->cSamples)
+    {
+        /* send the samples till the end of pHostStereoSampleBuf */
+        pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[pHostVoiceOut->offRead],
+                                                   (pHostVoiceOut->cSamples - pHostVoiceOut->offRead), format);
+        /*pHostStereoSampleBuff already has the samples which exceeded its space. They have overwriten the old
+         * played sampled starting from offset 0. So based on the number of samples that we had to play,
+         * read the number of samples from offset 0 .
+         */
+        pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[0],
+                                                   (cSamplesToSend - (pHostVoiceOut->cSamples -
+                                                                     pHostVoiceOut->offRead)),
+                                                   format);
+    }
+    else
+    {
+        pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[pHostVoiceOut->offRead],
+                                                   cSamplesToSend, format);
+    }
+        pHostVoiceOut->offRead = (pHostVoiceOut->offRead + cSamplesToSend) % pHostVoiceOut->cSamples;
+    return  cSamplesToSend;
+}
+
+static DECLCALLBACK(void) drvAudioVRDEFiniIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN hw)
+{
+    PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
+    LogFlow(("DrvAudioVRDE: drvAudioVRDEFiniIn \n"));
+    pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL);
+}
+
+static DECLCALLBACK(void) drvAudioVRDEFiniOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut)
+{
+    PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
+    LogFlow(("DrvAudioVRDE: audio input end\n"));
+}
+
+static DECLCALLBACK(int) drvAudioVRDEDisableEnableOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT hw, int cmd)
+{
+    LogFlow(("DrvAudioVRDE: drvAudioVRDEDisableEnableOut \n"));
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) drvAudioVRDEDisableEnableIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn, int cmd)
+{
+    PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
+
+    /* Initialize  VRDEVoice and return to VRDP server which returns this struct back to us
+     * in the form void * pvContext
+     */
+    PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn;
+    LogFlow(("DrvAudioVRDE: drvAudioVRDEDisableEnableIn \n"));
+    /* initialize only if not already done */
+    if (cmd == VOICE_ENABLE)
+    {
+        //@todo if (!pVRDEVoice->fIsInit)
+        //    IORingBufferReset(pVRDEVoice->pRecordedVoiceBuf);
+        LogFlow(("DrvAudioVRDE: Intializing the VRDE params and buffer \n"));
+        pVRDEVoice->fIsInit = 1;
+        pVRDEVoice->pHostVoiceIn = *pHostVoiceIn;
+        pVRDEVoice->cBytesPerFrame =1 ;
+        pVRDEVoice->uFrequency = 0;
+        pVRDEVoice->rate = NULL;
+        pVRDEVoice->cbSamplesBufferAllocated = 0;
+        pVRDEVoice->pvRateBuffer = NULL;
+        pVRDEVoice->cbRateBufferAllocated = 0;
+
+        pVRDEVoice->pHostVoiceIn.cSamples = 2048;
+        /* Initialize the hardware info section with the audio settings */
+
+        ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_IN_INIT);
+
+        /* Create the internal ring buffer. */
+        IORingBufferCreate(&pVRDEVoice->pRecordedVoiceBuf,
+                           pVRDEVoice->pHostVoiceIn.cSamples * sizeof(PDMHOSTSTEREOSAMPLE));
+
+        if (!RT_VALID_PTR(pVRDEVoice->pRecordedVoiceBuf))
+        {
+            LogRel(("AudioVRDE: [Input] Failed to create internal ring buffer\n"));
+            return  VERR_NO_MEMORY;
+        }
+
+        ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_INIT);
+        return pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, pVRDEVoice, pHostVoiceIn->cSamples,
+                                                             pHostVoiceIn->Props.uFrequency,
+                                                             pHostVoiceIn->Props.cChannels, pHostVoiceIn->Props.cBits);
+    }
+    else if (cmd == VOICE_DISABLE)
+    {
+        LogFlow(("DrvAudioVRDE: Cmd to disable VRDE \n"));
+        pVRDEVoice->fIsInit = 0;
+        ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_IN_UNINIT);
+        IORingBufferDestroy(pVRDEVoice->pRecordedVoiceBuf);
+        pVRDEVoice->pRecordedVoiceBuf = NULL;
+        ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_UNINIT);
+        pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL);
+    }
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(void) drvAudioVRDEGetConf(PPDMIBASE pInterface, PPDMAUDIOCONF pAudioConf)
+{
+    LogFlow(("drvAudioVRDE: drvAudioVRDEGetConf \n"));
+    /* @todo check if szHostVoiceOut = sizeof VRDEVoice works. VRDEVoice doesn't contain HOSTVOICEOUT. */
+    pAudioConf->szHostVoiceOut = sizeof(VRDEVoice);
+    pAudioConf->szHostVoiceIn = sizeof(VRDEVoice);
+    pAudioConf->MaxHostVoicesOut = 1;
+    pAudioConf->MaxHostVoicesIn = 1;
+}
+
+/**
+ * @interface_method_impl{PDMIBASE,pfnQueryInterface}
+ */
+static DECLCALLBACK(void *) drvAudioVRDEQueryInterface(PPDMIBASE pInterface, const char *pszIID)
+{
+    PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
+    PDRVAUDIOVRDE  pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, &pThis->IHostAudioR3);
+    return NULL;
+}
+
+
+static DECLCALLBACK(void) drvAudioVRDEDestruct(PPDMDRVINS pDrvIns)
+{
+}
+
+/**
+ * Construct a DirectSound Audio driver instance.
+ *
+ * @copydoc FNPDMDRVCONSTRUCT
+ */
+DECLCALLBACK(int) AudioVRDE::drvAudioVRDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
+{
+    PDRVAUDIOVRDE pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE);
+    LogRel(("drvAudioVRDEConstruct\n"));
+
+    /* we save the address of AudioVRDE in Object node in CFGM tree and address of VRDP server in
+     * ObjectVRDPServer node. So presence of both is necessary.
+     */
+    //if (!CFGMR3AreValuesValid(pCfg, "Object\0") || !CFGMR3AreValuesValid(pCfg, "ObjectVRDPServer\0"))
+    //   return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
+    AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
+                    ("Configuration error: Not possible to attach anything to this driver!\n"),
+                    VERR_PDM_DRVINS_NO_ATTACH);
+
+    /*
+     * Init the static parts.
+     */
+    pThis->pDrvIns                          = pDrvIns;
+    gpDrvIns = pDrvIns;
+    /* IBase */
+    pDrvIns->IBase.pfnQueryInterface        = drvAudioVRDEQueryInterface;
+    pThis->IHostAudioR3.pfnInitIn           = drvAudioVRDEInitIn;
+    pThis->IHostAudioR3.pfnInitOut          = drvAudioVRDEInitOut;
+    pThis->IHostAudioR3.pfnDisableEnableOut = drvAudioVRDEDisableEnableOut;
+    pThis->IHostAudioR3.pfnDisableEnableIn  = drvAudioVRDEDisableEnableIn;
+    pThis->IHostAudioR3.pfnFiniIn           = drvAudioVRDEFiniIn;
+    pThis->IHostAudioR3.pfnFiniOut          = drvAudioVRDEFiniOut;
+    pThis->IHostAudioR3.pfnPlayIn           = drvAudioVRDEPlayIn;
+    pThis->IHostAudioR3.pfnPlayOut          = drvAudioVRDEPlayOut;
+    pThis->IHostAudioR3.pfnGetConf          = drvAudioVRDEGetConf;
+    pThis->IHostAudioR3.pfnInit             = drvAudioVRDEInit;
+
+    /* Get VRDPServer pointer */
+    void *pv;
+    int rc = CFGMR3QueryPtr(pCfg, "ObjectVRDPServer", &pv);
+    if (RT_FAILURE(rc))
+    {
+        AssertMsgFailed(("DrvAudioVRDE Confguration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
+        return rc;
+    }
+    /* CFGM tree saves the pointer to ConsoleVRDPServer in the Object node of AudioVRDE */
+    pThis->pConsoleVRDPServer = (ConsoleVRDPServer *)pv;
+    pv = NULL;
+
+    rc = CFGMR3QueryPtr(pCfg, "Object", &pv);
+    if (RT_FAILURE(rc))
+    {
+        AssertMsgFailed(("DrvAudioVRDE Confguration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
+        return rc;
+    }
+    pThis->pAudioVRDE = (AudioVRDE *)pv;
+    pThis->pAudioVRDE->mpDrv = pThis;
+    /*
+     * Get the interface for the above driver (DrvAudio) to make mixer/conversion calls .
+     * Described in CFGM tree.
+     */
+    pThis->pUpPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIOCONNECTOR);
+    if (!pThis->pUpPort)
+    {
+        AssertMsgFailed(("Configuration error: No Audio Sniffer port interface above!\n"));
+        return VERR_PDM_MISSING_INTERFACE_ABOVE;
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Char driver registration record.
+ */
+const PDMDRVREG g_DrvAudioVRDE =
+{
+     PDM_DRVREG_VERSION,
+   /* szName */
+    "AudioVRDE",
+    /* szRCMod */
+    "",
+    /* szR0Mod */
+    "",
+    /* pszDescription */
+    "Audio VRDE",
+    /* fFlags */
+    PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
+    /* fClass. */
+    PDM_DRVREG_CLASS_AUDIO,
+    /* cMaxInstances */
+    ~0U,
+    /* cbInstance */
+    sizeof(DRVAUDIOVRDE),
+    /* pfnConstruct */
+    AudioVRDE::drvAudioVRDEConstruct,
+    /* pfnDestruct */
+    drvAudioVRDEDestruct,
+    /* pfnRelocate */
+    NULL,
+    /* pfnIOCtl */
+    NULL,
+    /* pfnPowerOn */
+    NULL,
+    /* pfnReset */
+    NULL,
+    /* pfnSuspend */
+    NULL,
+    /* pfnResume */
+    NULL,
+    /* pfnAttach */
+    NULL,
+    /* pfnDetach */
+    NULL,
+    /* pfnPowerOff */
+    NULL,
+    /* pfnSoftReset */
+    NULL,
+    /* u32EndVersion */
+    PDM_DRVREG_VERSION
+};
+
+
+
Index: /trunk/src/VBox/Main/src-client/VBoxDriversRegister.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/VBoxDriversRegister.cpp	(revision 50685)
+++ /trunk/src/VBox/Main/src-client/VBoxDriversRegister.cpp	(revision 50686)
@@ -24,5 +24,9 @@
 #include "DisplayImpl.h"
 #include "VMMDev.h"
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+#include "DrvAudioVRDE.h"
+#else
 #include "AudioSnifferInterface.h"
+#endif
 #include "Nvram.h"
 #include "UsbWebcamInterface.h"
@@ -67,6 +71,9 @@
     if (RT_FAILURE(rc))
         return rc;
-
+#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
+    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvAudioVRDE);
+#else
     rc = pCallbacks->pfnRegister(pCallbacks, &AudioSniffer::DrvReg);
+#endif
     if (RT_FAILURE(rc))
         return rc;
