Index: trunk/src/VBox/Devices/Audio/AudioMixer.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/AudioMixer.cpp	(revision 61164)
+++ trunk/src/VBox/Devices/Audio/AudioMixer.cpp	(revision 61166)
@@ -105,59 +105,4 @@
 }
 
-int AudioMixerCreateStream(PAUDIOMIXER pMixer,
-                           PPDMIAUDIOCONNECTOR pConn, PPDMAUDIOSTREAMCFG pCfg, uint32_t fFlags, PAUDMIXSTREAM *ppStream)
-{
-    AssertPtrReturn(pMixer, VERR_INVALID_POINTER);
-    AssertPtrReturn(pConn,  VERR_INVALID_POINTER);
-    AssertPtrReturn(pCfg,   VERR_INVALID_POINTER);
-    /** @todo Validate fFlags. */
-    /* ppStream is optional. */
-
-    PAUDMIXSTREAM pMixStream = (PAUDMIXSTREAM)RTMemAllocZ(sizeof(AUDMIXSTREAM));
-    if (!pMixStream)
-        return VERR_NO_MEMORY;
-
-    pMixStream->pszName = RTStrDup(pCfg->szName);
-    if (!pMixStream->pszName)
-    {
-        RTMemFree(pMixStream);
-        return VERR_NO_MEMORY;
-    }
-
-    LogFlowFunc(("[%s]: fFlags=0x%x (enmDir=%ld, %s, %RU8 channels, %RU32Hz)\n",
-                 pMixer->pszName, fFlags, pCfg->enmDir, DrvAudioAudFmtToStr(pCfg->enmFormat), pCfg->cChannels, pCfg->uHz));
-
-    PPDMAUDIOSTREAM pStream;
-    int rc = pConn->pfnStreamCreate(pConn, pCfg, &pStream);
-    if (RT_SUCCESS(rc))
-    {
-        /* Save the audio stream pointer to this mixing stream. */
-        pMixStream->pStream = pStream;
-
-        /* Increase the stream's reference count to let others know
-         * we're reyling on it to be around now. */
-        pConn->pfnStreamAddRef(pConn, pStream);
-    }
-
-    if (RT_SUCCESS(rc))
-    {
-        pMixStream->fFlags = fFlags;
-        pMixStream->pConn  = pConn;
-
-        if (ppStream)
-            *ppStream = pMixStream;
-    }
-    else if (pMixStream)
-    {
-        RTStrFree(pMixStream->pszName);
-        pMixStream->pszName = NULL;
-
-        RTMemFree(pMixStream);
-        pMixStream = NULL;
-    }
-
-    return rc;
-}
-
 int AudioMixerCreate(const char *pszName, uint32_t uFlags, PAUDIOMIXER *ppMixer)
 {
@@ -417,4 +362,64 @@
 
     LogFlowFunc(("[%s]: cStreams=%RU8, rc=%Rrc\n", pSink->pszName, pSink->cStreams, rc));
+    return rc;
+}
+
+int AudioMixerSinkCreateStream(PAUDMIXSINK pSink,
+                               PPDMIAUDIOCONNECTOR pConn, PPDMAUDIOSTREAMCFG pCfg, uint32_t fFlags, PAUDMIXSTREAM *ppStream)
+{
+    AssertPtrReturn(pSink,  VERR_INVALID_POINTER);
+    AssertPtrReturn(pConn,  VERR_INVALID_POINTER);
+    AssertPtrReturn(pCfg,   VERR_INVALID_POINTER);
+    /** @todo Validate fFlags. */
+    /* ppStream is optional. */
+
+    PAUDMIXSTREAM pMixStream = (PAUDMIXSTREAM)RTMemAllocZ(sizeof(AUDMIXSTREAM));
+    if (!pMixStream)
+        return VERR_NO_MEMORY;
+
+    pMixStream->pszName = RTStrDup(pCfg->szName);
+    if (!pMixStream->pszName)
+    {
+        RTMemFree(pMixStream);
+        return VERR_NO_MEMORY;
+    }
+
+    LogFlowFunc(("[%s]: fFlags=0x%x (enmDir=%ld, %s, %RU8 channels, %RU32Hz)\n",
+                 pSink->pszName, fFlags, pCfg->enmDir, DrvAudioAudFmtToStr(pCfg->enmFormat), pCfg->cChannels, pCfg->uHz));
+
+    PDMAUDIOSTREAMCFG CfgSink;
+    int rc = DrvAudioPCMPropsToStreamCfg(&pSink->PCMProps, &CfgSink);
+    AssertRCReturn(rc, rc);
+
+    /* Always use the sink's PCM audio format as the host side when creating a stream for it. */
+    PPDMAUDIOSTREAM pStream;
+    rc = pConn->pfnStreamCreate(pConn, &CfgSink, pCfg, &pStream);
+    if (RT_SUCCESS(rc))
+    {
+        /* Save the audio stream pointer to this mixing stream. */
+        pMixStream->pStream = pStream;
+
+        /* Increase the stream's reference count to let others know
+         * we're reyling on it to be around now. */
+        pConn->pfnStreamAddRef(pConn, pStream);
+    }
+
+    if (RT_SUCCESS(rc))
+    {
+        pMixStream->fFlags = fFlags;
+        pMixStream->pConn  = pConn;
+
+        if (ppStream)
+            *ppStream = pMixStream;
+    }
+    else if (pMixStream)
+    {
+        RTStrFree(pMixStream->pszName);
+        pMixStream->pszName = NULL;
+
+        RTMemFree(pMixStream);
+        pMixStream = NULL;
+    }
+
     return rc;
 }
Index: trunk/src/VBox/Devices/Audio/AudioMixer.h
===================================================================
--- trunk/src/VBox/Devices/Audio/AudioMixer.h	(revision 61164)
+++ trunk/src/VBox/Devices/Audio/AudioMixer.h	(revision 61166)
@@ -156,5 +156,4 @@
 int AudioMixerCreate(const char *pszName, uint32_t uFlags, PAUDIOMIXER *ppMixer);
 int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PAUDMIXSINK *ppSink);
-int AudioMixerCreateStream(PAUDIOMIXER pMixer, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg, uint32_t fFlags, PAUDMIXSTREAM *ppStream);
 void AudioMixerDestroy(PAUDIOMIXER pMixer);
 int AudioMixerGetDeviceFormat(PAUDIOMIXER pMixer, PPDMAUDIOSTREAMCFG pCfg);
@@ -166,4 +165,5 @@
 
 int AudioMixerSinkAddStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
+int AudioMixerSinkCreateStream(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg, uint32_t fFlags, PAUDMIXSTREAM *ppStream);
 int AudioMixerSinkCtl(PAUDMIXSINK pSink, AUDMIXSINKCMD enmCmd);
 void AudioMixerSinkDestroy(PAUDMIXSINK pSink);
Index: trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 61164)
+++ trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 61166)
@@ -760,5 +760,5 @@
         pStream->pMixStrm = NULL;
 
-        int rc2 = AudioMixerCreateStream(pThis->pMixer, pDrv->pConnector, pCfg, 0 /* fFlags */ , &pStream->pMixStrm);
+        int rc2 = AudioMixerSinkCreateStream(pSink, pDrv->pConnector, pCfg, 0 /* fFlags */ , &pStream->pMixStrm);
         if (RT_SUCCESS(rc2))
         {
@@ -805,5 +805,5 @@
         pDrv->Out.pMixStrm = NULL;
 
-        int rc2 = AudioMixerCreateStream(pThis->pMixer, pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm);
+        int rc2 = AudioMixerSinkCreateStream(pThis->pSinkOutput, pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm);
         if (RT_SUCCESS(rc2))
         {
Index: trunk/src/VBox/Devices/Audio/DevIchHda.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevIchHda.cpp	(revision 61164)
+++ trunk/src/VBox/Devices/Audio/DevIchHda.cpp	(revision 61166)
@@ -3775,5 +3775,5 @@
 
             PAUDMIXSTREAM pMixStrm;
-            rc2 = AudioMixerCreateStream(pThis->pMixer, pDrv->pConnector, pCfg, 0 /* fFlags */, &pMixStrm);
+            rc2 = AudioMixerSinkCreateStream(pSink->pMixSink, pDrv->pConnector, pCfg, 0 /* fFlags */, &pMixStrm);
             if (RT_SUCCESS(rc2))
             {
Index: trunk/src/VBox/Devices/Audio/DevSB16.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 61164)
+++ trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 61166)
@@ -2054,5 +2054,5 @@
         pDrv->Out.pMixStrm = NULL;
 
-        int rc2 = AudioMixerCreateStream(pThis->pMixer, pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm);
+        int rc2 = AudioMixerSinkCreateStream(pThis->pSinkOutput, pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm);
         if (RT_SUCCESS(rc2))
         {
Index: trunk/src/VBox/Devices/Audio/DrvAudio.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 61164)
+++ trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 61166)
@@ -1455,9 +1455,11 @@
 #endif
 
-static DECLCALLBACK(int) drvAudioStreamCreate(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAMCFG pCfg,
+static DECLCALLBACK(int) drvAudioStreamCreate(PPDMIAUDIOCONNECTOR pInterface,
+                                              PPDMAUDIOSTREAMCFG pCfgHost, PPDMAUDIOSTREAMCFG pCfgGuest,
                                               PPDMAUDIOSTREAM *ppStream)
 {
     AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
-    AssertPtrReturn(pCfg,       VERR_INVALID_POINTER);
+    AssertPtrReturn(pCfgHost,   VERR_INVALID_POINTER);
+    AssertPtrReturn(pCfgGuest,  VERR_INVALID_POINTER);
     AssertPtrReturn(ppStream,   VERR_INVALID_POINTER);
 
@@ -1468,7 +1470,8 @@
         return rc;
 
-    LogFlowFunc(("szName=%s\n", pCfg->szName));
+    LogFlowFunc(("Host=%s, Guest=%s\n", pCfgHost->szName, pCfgGuest->szName));
 #ifdef DEBUG
-    DrvAudioStreamCfgPrint(pCfg);
+    DrvAudioStreamCfgPrint(pCfgHost);
+    DrvAudioStreamCfgPrint(pCfgGuest);
 #endif
 
@@ -1486,5 +1489,12 @@
     do
     {
-        if (!DrvAudioStreamCfgIsValid(pCfg))
+        if (   !DrvAudioStreamCfgIsValid(pCfgHost)
+            || !DrvAudioStreamCfgIsValid(pCfgGuest))
+        {
+            RC_BREAK(VERR_INVALID_PARAMETER);
+        }
+
+        /* Make sure that both configurations actually intend the same thing. */
+        if (pCfgHost->enmDir != pCfgGuest->enmDir)
             RC_BREAK(VERR_INVALID_PARAMETER);
 
@@ -1492,5 +1502,5 @@
          *       which the host backend will need. */
         size_t cbHstStrm;
-        if (pCfg->enmDir == PDMAUDIODIR_IN)
+        if (pCfgHost->enmDir == PDMAUDIODIR_IN)
         {
             if (!pThis->cStreamsFreeIn)
@@ -1542,9 +1552,9 @@
 
         RTStrPrintf(pHstStrm->szName, RT_ELEMENTS(pHstStrm->szName), "%s (Host)",
-                    strlen(pCfg->szName) ? pCfg->szName : "<Untitled>");
+                    strlen(pCfgHost->szName) ? pCfgHost->szName : "<Untitled>");
 
         /* Note: Direction is always from child -> parent. */
         uint32_t cSamples = 0;
-        rc = pThis->pHostDrvAudio->pfnStreamCreate(pThis->pHostDrvAudio, pHstStrm, pCfg, &cSamples);
+        rc = pThis->pHostDrvAudio->pfnStreamCreate(pThis->pHostDrvAudio, pHstStrm, pCfgHost, &cSamples);
         if (RT_FAILURE(rc))
         {
@@ -1554,9 +1564,9 @@
 
         pHstStrm->enmCtx   = PDMAUDIOSTREAMCTX_HOST;
-        pHstStrm->enmDir   = pCfg->enmDir;
+        pHstStrm->enmDir   = pCfgHost->enmDir;
         pHstStrm->fStatus |= PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
         pHstStrm->pPair    = pGstStrm;
 
-        rc = DrvAudioStreamCfgToProps(pCfg, &pHstStrm->Props);
+        rc = DrvAudioStreamCfgToProps(pCfgHost, &pHstStrm->Props);
         AssertRCBreak(rc);
 
@@ -1569,7 +1579,7 @@
 
         RTStrPrintf(pGstStrm->szName, RT_ELEMENTS(pGstStrm->szName), "%s (Guest)",
-                    strlen(pCfg->szName) ? pCfg->szName : "<Untitled>");
-
-        rc = DrvAudioStreamCfgToProps(pCfg, &pGstStrm->Props);
+                    strlen(pCfgGuest->szName) ? pCfgGuest->szName : "<Untitled>");
+
+        rc = DrvAudioStreamCfgToProps(pCfgGuest, &pGstStrm->Props);
         AssertRCBreak(rc);
 
@@ -1577,5 +1587,5 @@
         if (RT_SUCCESS(rc))
         {
-            if (pCfg->enmDir == PDMAUDIODIR_IN)
+            if (pCfgGuest->enmDir == PDMAUDIODIR_IN)
             {
                 rc = AudioMixBufLinkTo(&pHstStrm->MixBuf, &pGstStrm->MixBuf);
@@ -1588,5 +1598,5 @@
 
         pGstStrm->enmCtx   = PDMAUDIOSTREAMCTX_GUEST;
-        pGstStrm->enmDir   = pCfg->enmDir;
+        pGstStrm->enmDir   = pCfgGuest->enmDir;
         pGstStrm->fStatus |= PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
         pGstStrm->pPair    = pHstStrm;
@@ -1628,5 +1638,5 @@
         pHstStrm->cRefs = 1;
 
-        if (pCfg->enmDir == PDMAUDIODIR_IN)
+        if (pCfgHost->enmDir == PDMAUDIODIR_IN)
         {
             Assert(pThis->cStreamsFreeIn);
Index: trunk/src/VBox/Devices/Audio/DrvAudio.h
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvAudio.h	(revision 61164)
+++ trunk/src/VBox/Devices/Audio/DrvAudio.h	(revision 61166)
@@ -111,8 +111,12 @@
     ( (PDRVAUDIO)((uintptr_t)pInterface - RT_OFFSETOF(DRVAUDIO, IAudioConnector)) )
 
+
+bool DrvAudioAudFmtIsSigned(PDMAUDIOFMT enmFmt);
+uint8_t DrvAudioAudFmtToBits(PDMAUDIOFMT enmFmt);
 const char *DrvAudioAudFmtToStr(PDMAUDIOFMT enmFmt);
 void DrvAudioClearBuf(PPDMPCMPROPS pPCMInfo, void *pvBuf, size_t cbBuf, uint32_t cSamples);
-bool DrvAudioPCMPropsAreEqual(PPDMPCMPROPS pProps1, PPDMPCMPROPS pProps2);
-bool DrvAudioPCMPropsAreEqual(PPDMPCMPROPS pPCMInfo, PPDMAUDIOSTREAMCFG pCfg);
+bool DrvAudioPCMPropsAreEqual(PPDMPCMPROPS pPCMProps1, PPDMPCMPROPS pPCMProps2);
+bool DrvAudioPCMPropsAreEqual(PPDMPCMPROPS pPCMProps, PPDMAUDIOSTREAMCFG pCfg);
+int DrvAudioPCMPropsToStreamCfg(PPDMPCMPROPS pPCMProps, PPDMAUDIOSTREAMCFG pCfg);
 const char *DrvAudRecSrcToStr(PDMAUDIORECSOURCE enmRecSource);
 void DrvAudioStreamCfgPrint(PPDMAUDIOSTREAMCFG pCfg);
Index: trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp	(revision 61164)
+++ trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp	(revision 61166)
@@ -61,4 +61,40 @@
 #include "AudioMixBuffer.h"
 
+
+/**
+ * Retrieves the matching PDMAUDIOFMT for given bits + signing flag.
+ *
+ * @return  IPRT status code.
+ * @return  PDMAUDIOFMT         Resulting audio format or PDMAUDIOFMT_INVALID if invalid.
+ * @param   cBits               Bits to retrieve audio format for.
+ * @param   fSigned             Signed flag for bits to retrieve audio format for.
+ */
+PDMAUDIOFMT DrvAudioAudFmtBitsToAudFmt(uint8_t cBits, bool fSigned)
+{
+    if (fSigned)
+    {
+        switch (cBits)
+        {
+            case 8:  return PDMAUDIOFMT_S8;
+            case 16: return PDMAUDIOFMT_S16;
+            case 32: return PDMAUDIOFMT_S32;
+            default: break;
+        }
+    }
+    else
+    {
+        switch (cBits)
+        {
+            case 8:  return PDMAUDIOFMT_U8;
+            case 16: return PDMAUDIOFMT_U16;
+            case 32: return PDMAUDIOFMT_U32;
+            default: break;
+        }
+    }
+
+    AssertMsgFailed(("Bogus audio bits %RU8\n", cBits));
+    return PDMAUDIOFMT_INVALID;
+}
+
 /**
  * Clears a sample buffer by the given amount of audio samples.
@@ -150,4 +186,64 @@
     AssertMsgFailed(("Invalid recording source %ld\n", enmRecSrc));
     return "Unknown";
+}
+
+/**
+ * Returns wether the given audio format has signed bits or not.
+ *
+ * @return  IPRT status code.
+ * @return  bool                @true for signed bits, @false for unsigned.
+ * @param   enmFmt              Audio format to retrieve value for.
+ */
+bool DrvAudioAudFmtIsSigned(PDMAUDIOFMT enmFmt)
+{
+    switch (enmFmt)
+    {
+        case PDMAUDIOFMT_S8:
+        case PDMAUDIOFMT_S16:
+        case PDMAUDIOFMT_S32:
+            return true;
+
+        case PDMAUDIOFMT_U8:
+        case PDMAUDIOFMT_U16:
+        case PDMAUDIOFMT_U32:
+            return false;
+
+        default:
+            break;
+    }
+
+    AssertMsgFailed(("Bogus audio format %ld\n", enmFmt));
+    return false;
+}
+
+/**
+ * Returns the bits of a given audio format.
+ *
+ * @return  IPRT status code.
+ * @return  uint8_t             Bits of audio format.
+ * @param   enmFmt              Audio format to retrieve value for.
+ */
+uint8_t DrvAudioAudFmtToBits(PDMAUDIOFMT enmFmt)
+{
+    switch (enmFmt)
+    {
+        case PDMAUDIOFMT_S8:
+        case PDMAUDIOFMT_U8:
+            return 8;
+
+        case PDMAUDIOFMT_U16:
+        case PDMAUDIOFMT_S16:
+            return 16;
+
+        case PDMAUDIOFMT_U32:
+        case PDMAUDIOFMT_S32:
+            return 32;
+
+        default:
+            break;
+    }
+
+    AssertMsgFailed(("Bogus audio format %ld\n", enmFmt));
+    return 0;
 }
 
@@ -253,4 +349,25 @@
            && pProps1->cBits       == pProps2->cBits
            && pProps1->fSwapEndian == pProps2->fSwapEndian;
+}
+
+/**
+ * Converts PCM properties to a audio stream configuration.
+ *
+ * @return  IPRT status code.
+ * @param   pPCMProps           Pointer to PCM properties to convert.
+ * @param   pCfg                Pointer to audio stream configuration to store result into.
+ */
+int DrvAudioPCMPropsToStreamCfg(PPDMPCMPROPS pPCMProps, PPDMAUDIOSTREAMCFG pCfg)
+{
+    AssertPtrReturn(pPCMProps, VERR_INVALID_POINTER);
+    AssertPtrReturn(pCfg,      VERR_INVALID_POINTER);
+
+    pCfg->uHz           = pPCMProps->uHz;
+    pCfg->cChannels     = pPCMProps->cChannels;
+    pCfg->enmFormat     = DrvAudioAudFmtBitsToAudFmt(pPCMProps->cBits, pPCMProps->fSigned);
+
+    /** @todo We assume little endian is the default for now. */
+    pCfg->enmEndianness = pPCMProps->fSwapEndian == false ? PDMAUDIOENDIANNESS_LITTLE : PDMAUDIOENDIANNESS_BIG;
+    return VINF_SUCCESS;
 }
 
