Index: trunk/src/VBox/Devices/Audio/AudioHlp.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/AudioHlp.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/AudioHlp.cpp	(revision 88269)
@@ -179,18 +179,20 @@
 bool AudioHlpStreamCfgIsValid(PCPDMAUDIOSTREAMCFG pCfg)
 {
-    AssertPtrReturn(pCfg, false);
-
-    AssertReturn(PDMAudioStrmCfgIsValid(pCfg), false);
-
-    bool fValid = (   pCfg->enmDir == PDMAUDIODIR_IN
-                   || pCfg->enmDir == PDMAUDIODIR_OUT);
-
-    fValid &= (   pCfg->enmLayout == PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED
-               || pCfg->enmLayout == PDMAUDIOSTREAMLAYOUT_RAW);
-
-    if (fValid)
-        fValid = AudioHlpPcmPropsAreValid(&pCfg->Props);
-
-    return fValid;
+    /* Ugly! HDA attach code calls us with uninitialized (all zero) config. */
+    if (   pCfg->enmLayout != PDMAUDIOSTREAMLAYOUT_INVALID
+        || PDMAudioPropsHz(&pCfg->Props) != 0)
+    {
+        if (PDMAudioStrmCfgIsValid(pCfg))
+        {
+            if (   pCfg->enmDir == PDMAUDIODIR_IN
+                || pCfg->enmDir == PDMAUDIODIR_OUT)
+            {
+                if (   pCfg->enmLayout == PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED
+                    || pCfg->enmLayout == PDMAUDIOSTREAMLAYOUT_RAW)
+                    return AudioHlpPcmPropsAreValid(&pCfg->Props);
+            }
+        }
+    }
+    return false;
 }
 
@@ -219,5 +221,6 @@
  *        function will flag such properties as not valid.
  *
- * @todo  r=bird: See note and explain properly.
+ * @todo  r=bird: See note and explain properly. Perhaps rename to
+ *        AudioHlpPcmPropsAreValidAndSupported?
  *
  * @returns @c true if the properties are valid, @c false if not.
@@ -227,46 +230,40 @@
 {
     AssertPtrReturn(pProps, false);
-
     AssertReturn(PDMAudioPropsAreValid(pProps), false);
 
-    /** @todo r=bird: This code is cannot make up its mind whether to return on
-     *        false, or whether to return at the end. (hint: just return
-     *        immediately, duh.) */
-
     /* Minimum 1 channel (mono), maximum 7.1 (= 8) channels. */
-    bool fValid = (   pProps->cChannels >= 1
-                   && pProps->cChannels <= 8);
-
-    if (fValid)
-    {
-        switch (pProps->cbSample)
+    if (PDMAudioPropsChannels(pProps) >= 1 && PDMAudioPropsChannels(pProps) <= 8)
+    {
+        switch (PDMAudioPropsSampleSize(pProps))
         {
             case 1: /* 8 bit */
-               if (pProps->fSigned)
-                   fValid = false;
+               if (PDMAudioPropsIsSigned(pProps))
+                   return false;
                break;
             case 2: /* 16 bit */
-                if (!pProps->fSigned)
-                    fValid = false;
+                if (!PDMAudioPropsIsSigned(pProps))
+                    return false;
                 break;
             /** @todo Do we need support for 24 bit samples? */
             case 4: /* 32 bit */
-                if (!pProps->fSigned)
-                    fValid = false;
+                if (!PDMAudioPropsIsSigned(pProps))
+                    return false;
+                break;
+            case 8: /* 64-bit raw */
+                if (   !PDMAudioPropsIsSigned(pProps)
+                    || !pProps->fRaw)
+                    return false;
                 break;
             default:
-                fValid = false;
-                break;
-        }
-    }
-
-    if (!fValid)
-        return false;
-
-    fValid &= pProps->uHz > 0;
-    fValid &= pProps->cShift == PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pProps->cbSample, pProps->cChannels);
-    fValid &= pProps->fSwapEndian == false; /** @todo Handling Big Endian audio data is not supported yet. */
-
-    return fValid;
+                return false;
+        }
+
+        if (pProps->uHz > 0)
+        {
+            if (!pProps->fSwapEndian) /** @todo Handling Big Endian audio data is not supported yet. */
+                return true;
+        }
+    }
+    return false;
 }
 
@@ -520,4 +517,5 @@
     /** @todo Validate fOpen flags. */
     AssertPtrReturn(pProps,  VERR_INVALID_POINTER);
+    Assert(PDMAudioPropsAreValid(pProps));
 
     int rc;
@@ -529,8 +527,4 @@
     else if (pFile->enmType == PDMAUDIOFILETYPE_WAV)
     {
-        Assert(pProps->cChannels);
-        Assert(pProps->uHz);
-        Assert(pProps->cbSample);
-
         pFile->pvData = (PAUDIOWAVFILEDATA)RTMemAllocZ(sizeof(AUDIOWAVFILEDATA));
         if (pFile->pvData)
@@ -549,9 +543,9 @@
             pData->Hdr.u32Size1         = 16; /* Means PCM. */
             pData->Hdr.u16AudioFormat   = 1;  /* PCM, linear quantization. */
-            pData->Hdr.u16NumChannels   = pProps->cChannels;
+            pData->Hdr.u16NumChannels   = PDMAudioPropsChannels(pProps);
             pData->Hdr.u32SampleRate    = pProps->uHz;
             pData->Hdr.u32ByteRate      = PDMAudioPropsGetBitrate(pProps) / 8;
-            pData->Hdr.u16BlockAlign    = pProps->cChannels * pProps->cbSample;
-            pData->Hdr.u16BitsPerSample = pProps->cbSample * 8;
+            pData->Hdr.u16BlockAlign    = PDMAudioPropsFrameSize(pProps);
+            pData->Hdr.u16BitsPerSample = PDMAudioPropsSampleBits(pProps);
 
             /* Data chunk. */
@@ -584,7 +578,5 @@
 
     if (RT_SUCCESS(rc))
-    {
         LogRel2(("Audio: Opened file '%s'\n", pFile->szName));
-    }
     else
         LogRel(("Audio: Failed opening file '%s', rc=%Rrc\n", pFile->szName, rc));
Index: trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp	(revision 88269)
@@ -47,4 +47,5 @@
 #endif
 #include <VBox/err.h>
+#include <VBox/vmm/pdmaudioinline.h>
 
 #include "AudioMixBuffer.h"
@@ -53,9 +54,11 @@
 # ifdef DEBUG
 #  define AUDMIXBUF_LOG(x) LogFlowFunc(x)
+#  define AUDMIXBUF_LOG_ENABLED
 # else
-# define AUDMIXBUF_LOG(x) do {} while (0)
+#  define AUDMIXBUF_LOG(x) do {} while (0)
 # endif
 #else /* VBOX_AUDIO_TESTCASE */
 # define AUDMIXBUF_LOG(x) RTPrintf x
+# define AUDMIXBUF_LOG_ENABLED
 #endif
 
@@ -136,70 +139,4 @@
 
 /**
- * Peeks for audio frames without any conversion done.
- * This will get the raw frame data out of a mixing buffer.
- *
- * @return  IPRT status code or VINF_AUDIO_MORE_DATA_AVAILABLE if more data is available to read.
- *
- * @param   pMixBuf                 Mixing buffer to acquire audio frames from.
- * @param   cFramesToRead           Number of audio frames to read.
- * @param   paFrameBuf              Buffer where to store the returned audio frames.
- * @param   cFrameBuf               Size (in frames) of the buffer to store audio frames into.
- * @param   pcFramesRead            Returns number of read audio frames. Optional.
- *
- * @remark  This function is not thread safe!
- */
-/** @todo r=bird: This isn't a 'ing Peek function, it's a Read function!
- *        Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaarg!!!!!!!!!!!!!!!!!!! */
-int AudioMixBufPeek(PPDMAUDIOMIXBUF pMixBuf, uint32_t cFramesToRead,
-                    PPDMAUDIOFRAME paFrameBuf, uint32_t cFrameBuf, uint32_t *pcFramesRead)
-{
-    AssertPtrReturn(pMixBuf,    VERR_INVALID_POINTER);
-    AssertPtrReturn(paFrameBuf, VERR_INVALID_POINTER);
-    AssertReturn(cFrameBuf,     VERR_INVALID_PARAMETER);
-    /* pcRead is optional. */
-
-    int rc;
-
-    if (!cFramesToRead)
-    {
-        if (pcFramesRead)
-            *pcFramesRead = 0;
-        return VINF_SUCCESS;
-    }
-
-    uint32_t cRead;
-    if (pMixBuf->offRead + cFramesToRead > pMixBuf->cFrames)
-    {
-        cRead = pMixBuf->cFrames - pMixBuf->offRead;
-        rc = VINF_AUDIO_MORE_DATA_AVAILABLE;
-    }
-    else
-    {
-        cRead = cFramesToRead;
-        rc = VINF_SUCCESS;
-    }
-
-    if (cRead > cFrameBuf)
-    {
-        cRead = cFrameBuf;
-        rc = VINF_AUDIO_MORE_DATA_AVAILABLE;
-    }
-
-    if (cRead)
-    {
-        memcpy(paFrameBuf, &pMixBuf->pFrames[pMixBuf->offRead], sizeof(PDMAUDIOFRAME) * cRead);
-
-        pMixBuf->offRead = (pMixBuf->offRead + cRead) % pMixBuf->cFrames;
-        Assert(pMixBuf->offRead <= pMixBuf->cFrames);
-        pMixBuf->cUsed  -= RT_MIN(cRead, pMixBuf->cUsed);
-    }
-
-    if (pcFramesRead)
-        *pcFramesRead = cRead;
-
-    return rc;
-}
-
-/**
  * Returns a mutable pointer to the mixing buffer's audio frame buffer for writing raw
  * audio frames.
@@ -213,4 +150,6 @@
  * @remark  This function is not thread safe!
  */
+/** @todo r=bird: This isn't a 'ing Peek function, it's a Read function!
+ *        Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaarg!!!!!!!!!!!!!!!!!!! */
 int AudioMixBufPeekMutable(PPDMAUDIOMIXBUF pMixBuf, uint32_t cFrames,
                            PPDMAUDIOFRAME *ppvFrames, uint32_t *pcFramesToWrite)
@@ -281,4 +220,5 @@
     AssertStmt(cFramesToClear <= pMixBuf->cFrames, cFramesToClear = pMixBuf->cFrames);
 
+/** @todo r=bird: Why isn't this done when reading/releaseing ? */
     PPDMAUDIOMIXBUF pIter;
     RTListForEach(&pMixBuf->lstChildren, pIter, PDMAUDIOMIXBUF, Node)
@@ -291,4 +231,5 @@
     }
 
+/** @todo r=bird: waste of time? */
     uint32_t cClearOff;
     uint32_t cClearLen;
@@ -559,4 +500,35 @@
 
 #undef AUDMIXBUF_CONVERT
+
+/*
+ * Manually coded signed 64-bit conversion.
+ */
+#if 0
+DECLCALLBACK(uint32_t) audioMixBufConvFromS64Stereo(PPDMAUDIOFRAME paDst, const void *pvSrc, uint32_t cbSrc,
+                                                    PCPDMAUDMIXBUFCONVOPTS pOpts)
+{
+    _aType const *pSrc = (_aType const *)pvSrc;
+    uint32_t cFrames = RT_MIN(pOpts->cFrames, cbSrc / sizeof(_aType));
+    AUDMIXBUF_MACRO_LOG(("cFrames=%RU32, BpS=%zu, lVol=%RU32, rVol=%RU32\n",
+                         pOpts->cFrames, sizeof(_aType), pOpts->From.Volume.uLeft, pOpts->From.Volume.uRight));
+    for (uint32_t i = 0; i < cFrames; i++)
+    {
+        paDst->i64LSample = ASMMult2xS32RetS64((int32_t)audioMixBufClipFrom##_aName(*pSrc++), pOpts->From.Volume.uLeft ) >> AUDIOMIXBUF_VOL_SHIFT; \
+        paDst->i64RSample = ASMMult2xS32RetS64((int32_t)audioMixBufClipFrom##_aName(*pSrc++), pOpts->From.Volume.uRight) >> AUDIOMIXBUF_VOL_SHIFT; \
+        paDst++;
+    }
+
+    return cFrames;
+}
+#endif
+
+DECLCALLBACK(void) audioMixBufConvToRawS64Stereo(void *pvDst, PCPDMAUDIOFRAME paSrc, PCPDMAUDMIXBUFCONVOPTS pOpts)
+{
+    AssertCompile(sizeof(paSrc[0]) == sizeof(int64_t) * 2);
+    memcpy(pvDst, paSrc, sizeof(int64_t) * 2 * pOpts->cFrames);
+}
+
+
+
 
 #define AUDMIXBUF_MIXOP(_aName, _aOp) \
@@ -674,118 +646,124 @@
 
 /**
- * Looks up the matching conversion (macro) routine for converting
- * audio frames from a source format.
- *
- ** @todo Speed up the lookup by binding it to the actual stream state.
- *
- * @return  PAUDMIXBUF_FN_CONVFROM  Function pointer to conversion macro if found, NULL if not supported.
- * @param   enmFmt                  Audio format to lookup conversion macro for.
- */
-static PFNPDMAUDIOMIXBUFCONVFROM audioMixBufConvFromLookup(PDMAUDIOMIXBUFFMT enmFmt)
-{
-    if (AUDMIXBUF_FMT_SIGNED(enmFmt))
-    {
-        if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 2)
+ * Looks up the matching conversion function for converting audio frames from a
+ * source format.
+ *
+ * @returns Pointer to matching conversion function, NULL if not supported.
+ * @param   pProp       The audio format to find a "from" converter for.
+ */
+static PFNPDMAUDIOMIXBUFCONVFROM audioMixBufConvFromLookup(PCPDMAUDIOPCMPROPS pProps)
+{
+    if (PDMAudioPropsIsSigned(pProps))
+    {
+        switch (PDMAudioPropsChannels(pProps))
         {
-            switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
-            {
-                case 8:  return audioMixBufConvFromS8Stereo;
-                case 16: return audioMixBufConvFromS16Stereo;
-                case 32: return audioMixBufConvFromS32Stereo;
-                default: return NULL;
-            }
+            case 2:
+                switch (PDMAudioPropsSampleSize(pProps))
+                {
+                    case 1:  return audioMixBufConvFromS8Stereo;
+                    case 2:  return audioMixBufConvFromS16Stereo;
+                    case 4:  return audioMixBufConvFromS32Stereo;
+                    //case 8:  return pProps->fRaw ? audioMixBufConvToRawS64Stereo : NULL;
+                    default: return NULL;
+                }
+
+            case 1:
+                switch (PDMAudioPropsSampleSize(pProps))
+                {
+                    case 1:  return audioMixBufConvFromS8Mono;
+                    case 2:  return audioMixBufConvFromS16Mono;
+                    case 4:  return audioMixBufConvFromS32Mono;
+                    default: return NULL;
+                }
+            default:
+                return NULL;
         }
-        else
+    }
+    else /* Unsigned */
+    {
+        switch (PDMAudioPropsChannels(pProps))
         {
-            switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
-            {
-                case 8:  return audioMixBufConvFromS8Mono;
-                case 16: return audioMixBufConvFromS16Mono;
-                case 32: return audioMixBufConvFromS32Mono;
-                default: return NULL;
-            }
+            case 2:
+                switch (PDMAudioPropsSampleSize(pProps))
+                {
+                    case 1:  return audioMixBufConvFromU8Stereo;
+                    case 2:  return audioMixBufConvFromU16Stereo;
+                    case 4:  return audioMixBufConvFromU32Stereo;
+                    default: return NULL;
+                }
+
+            case 1:
+                switch (PDMAudioPropsSampleSize(pProps))
+                {
+                    case 1:  return audioMixBufConvFromU8Mono;
+                    case 2:  return audioMixBufConvFromU16Mono;
+                    case 4:  return audioMixBufConvFromU32Mono;
+                    default: return NULL;
+                }
+            default:
+                return NULL;
         }
     }
+    /* not reached */
+}
+
+/**
+ * Looks up the matching conversion function for converting audio frames to a
+ * destination format.
+ *
+ * @returns Pointer to matching conversion function, NULL if not supported.
+ * @param   pProp       The audio format to find a "to" converter for.
+ */
+static PFNPDMAUDIOMIXBUFCONVTO audioMixBufConvToLookup(PCPDMAUDIOPCMPROPS pProps)
+{
+    if (PDMAudioPropsIsSigned(pProps))
+    {
+        switch (PDMAudioPropsChannels(pProps))
+        {
+            case 2:
+                switch (PDMAudioPropsSampleSize(pProps))
+                {
+                    case 1:  return audioMixBufConvToS8Stereo;
+                    case 2:  return audioMixBufConvToS16Stereo;
+                    case 4:  return audioMixBufConvToS32Stereo;
+                    case 8:  return pProps->fRaw ? audioMixBufConvToRawS64Stereo : NULL;
+                    default: return NULL;
+                }
+
+            case 1:
+                switch (PDMAudioPropsSampleSize(pProps))
+                {
+                    case 1:  return audioMixBufConvToS8Mono;
+                    case 2:  return audioMixBufConvToS16Mono;
+                    case 4:  return audioMixBufConvToS32Mono;
+                    default: return NULL;
+                }
+            default:
+                return NULL;
+        }
+    }
     else /* Unsigned */
     {
-        if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 2)
+        switch (PDMAudioPropsChannels(pProps))
         {
-            switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
-            {
-                case 8:  return audioMixBufConvFromU8Stereo;
-                case 16: return audioMixBufConvFromU16Stereo;
-                case 32: return audioMixBufConvFromU32Stereo;
-                default: return NULL;
-            }
-        }
-        else
-        {
-            switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
-            {
-                case 8:  return audioMixBufConvFromU8Mono;
-                case 16: return audioMixBufConvFromU16Mono;
-                case 32: return audioMixBufConvFromU32Mono;
-                default: return NULL;
-            }
-        }
-    }
-    /* not reached */
-}
-
-/**
- * Looks up the matching conversion (macro) routine for converting
- * audio frames to a destination format.
- *
- ** @todo Speed up the lookup by binding it to the actual stream state.
- *
- * @return  PAUDMIXBUF_FN_CONVTO    Function pointer to conversion macro if found, NULL if not supported.
- * @param   enmFmt                  Audio format to lookup conversion macro for.
- */
-static PFNPDMAUDIOMIXBUFCONVTO audioMixBufConvToLookup(PDMAUDIOMIXBUFFMT enmFmt)
-{
-    if (AUDMIXBUF_FMT_SIGNED(enmFmt))
-    {
-        if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 2)
-        {
-            switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
-            {
-                case 8:  return audioMixBufConvToS8Stereo;
-                case 16: return audioMixBufConvToS16Stereo;
-                case 32: return audioMixBufConvToS32Stereo;
-                default: return NULL;
-            }
-        }
-        else
-        {
-            switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
-            {
-                case 8:  return audioMixBufConvToS8Mono;
-                case 16: return audioMixBufConvToS16Mono;
-                case 32: return audioMixBufConvToS32Mono;
-                default: return NULL;
-            }
-        }
-    }
-    else /* Unsigned */
-    {
-        if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 2)
-        {
-            switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
-            {
-                case 8:  return audioMixBufConvToU8Stereo;
-                case 16: return audioMixBufConvToU16Stereo;
-                case 32: return audioMixBufConvToU32Stereo;
-                default: return NULL;
-            }
-        }
-        else
-        {
-            switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
-            {
-                case 8:  return audioMixBufConvToU8Mono;
-                case 16: return audioMixBufConvToU16Mono;
-                case 32: return audioMixBufConvToU32Mono;
-                default: return NULL;
-            }
+            case 2:
+                switch (PDMAudioPropsSampleSize(pProps))
+                {
+                    case 1:  return audioMixBufConvToU8Stereo;
+                    case 2:  return audioMixBufConvToU16Stereo;
+                    case 4:  return audioMixBufConvToU32Stereo;
+                    default: return NULL;
+                }
+
+            case 1:
+                switch (PDMAudioPropsSampleSize(pProps))
+                {
+                    case 1:  return audioMixBufConvToU8Mono;
+                    case 2:  return audioMixBufConvToU16Mono;
+                    case 4:  return audioMixBufConvToU32Mono;
+                    default: return NULL;
+                }
+            default:
+                return NULL;
         }
     }
@@ -826,9 +804,10 @@
  * @param   cFrames                 Maximum number of audio frames the mixing buffer can hold.
  */
-int AudioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PPDMAUDIOPCMPROPS pProps, uint32_t cFrames)
+int AudioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PCPDMAUDIOPCMPROPS pProps, uint32_t cFrames)
 {
     AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
     AssertPtrReturn(pszName, VERR_INVALID_POINTER);
     AssertPtrReturn(pProps,  VERR_INVALID_POINTER);
+    Assert(PDMAudioPropsAreValid(pProps));
 
     pMixBuf->uMagic  = PDMAUDIOMIXBUF_MAGIC;
@@ -857,23 +836,24 @@
     pMixBuf->pRate = NULL;
 
+    /** @todo r=bird: Why invent a new representation for the mixer?  See also
+     *        comment in pdmaudioifs.h about missing MAKE macros. */
     pMixBuf->uAudioFmt = AUDMIXBUF_AUDIO_FMT_MAKE(pProps->uHz,
-                                                 pProps->cChannels,
-                                                 pProps->cbSample * 8 /* Bit */,
-                                                 pProps->fSigned);
-
-    pMixBuf->pfnConvFrom = audioMixBufConvFromLookup(pMixBuf->uAudioFmt);
-    pMixBuf->pfnConvTo   = audioMixBufConvToLookup(pMixBuf->uAudioFmt);
-
-    pMixBuf->cShift = pProps->cShift;
+                                                  PDMAudioPropsChannels(pProps),
+                                                  PDMAudioPropsSampleBits(pProps),
+                                                  pProps->fSigned);
+
+    pMixBuf->Props       = *pProps;
+    pMixBuf->pfnConvFrom = audioMixBufConvFromLookup(pProps);
+    pMixBuf->pfnConvTo   = audioMixBufConvToLookup(pProps);
+
     pMixBuf->pszName = RTStrDup(pszName);
     if (!pMixBuf->pszName)
         return VERR_NO_MEMORY;
 
-    AUDMIXBUF_LOG(("%s: uHz=%RU32, cChan=%RU8, cBits=%RU8, fSigned=%RTbool\n",
-                   pMixBuf->pszName,
-                   AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->uAudioFmt),
-                   AUDMIXBUF_FMT_CHANNELS(pMixBuf->uAudioFmt),
-                   AUDMIXBUF_FMT_BITS_PER_SAMPLE(pMixBuf->uAudioFmt),
-                   RT_BOOL(AUDMIXBUF_FMT_SIGNED(pMixBuf->uAudioFmt))));
+
+#ifdef AUDMIXBUF_LOG_ENABLED
+    char szTmp[PDMAUDIOPROPSTOSTRING_MAX];
+    AUDMIXBUF_LOG(("%s: %s\n", pMixBuf->pszName, PDMAudioPropsToString(pProps, szTmp, sizeof(szTmp))));
+#endif
 
     return audioMixBufAlloc(pMixBuf, cFrames);
@@ -1456,11 +1436,7 @@
  * @param   pcbRead                 Size (in bytes) of data read. Optional.
  */
-int AudioMixBufReadAt(PPDMAUDIOMIXBUF pMixBuf,
-                      uint32_t offFrames,
-                      void *pvBuf, uint32_t cbBuf,
-                      uint32_t *pcbRead)
-{
-    return AudioMixBufReadAtEx(pMixBuf, pMixBuf->uAudioFmt,
-                               offFrames, pvBuf, cbBuf, pcbRead);
+int AudioMixBufReadAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offFrames, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
+{
+    return AudioMixBufReadAtEx(pMixBuf, &pMixBuf->Props, offFrames, pvBuf, cbBuf, pcbRead);
 }
 
@@ -1471,15 +1447,13 @@
  *
  * @return  IPRT status code.
- * @param   pMixBuf                 Mixing buffer to read audio frames from.
- * @param   enmFmt                  Audio format to use for output.
- * @param   offFrames               Offset (in audio frames) to start reading from.
- * @param   pvBuf                   Pointer to buffer to write output to.
- * @param   cbBuf                   Size (in bytes) of buffer to write to.
- * @param   pcbRead                 Size (in bytes) of data read. Optional.
- */
-int AudioMixBufReadAtEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt,
-                        uint32_t offFrames,
-                        void *pvBuf, uint32_t cbBuf,
-                        uint32_t *pcbRead)
+ * @param   pMixBuf     Mixing buffer to read audio frames from.
+ * @param   pDstProps   The target format.
+ * @param   offFrames   Offset (in audio frames) to start reading from.
+ * @param   pvBuf       Pointer to buffer to write output to.
+ * @param   cbBuf       Size (in bytes) of buffer to write to.
+ * @param   pcbRead     Size (in bytes) of data read. Optional.
+ */
+int AudioMixBufReadAtEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps,
+                        uint32_t offFrames, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
 {
     AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
@@ -1501,9 +1475,8 @@
     {
         PFNPDMAUDIOMIXBUFCONVTO pfnConvTo = NULL;
-        if (pMixBuf->uAudioFmt != enmFmt)
-            pfnConvTo = audioMixBufConvToLookup(enmFmt);
+        if (PDMAudioPropsAreEqual(&pMixBuf->Props, pDstProps))
+            pfnConvTo = pMixBuf->pfnConvTo;
         else
-            pfnConvTo = pMixBuf->pfnConvTo;
-
+            pfnConvTo = audioMixBufConvToLookup(pDstProps);
         if (pfnConvTo)
         {
@@ -1552,15 +1525,16 @@
 int AudioMixBufAcquireReadBlock(PPDMAUDIOMIXBUF pMixBuf, void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames)
 {
-    return AudioMixBufAcquireReadBlockEx(pMixBuf, pMixBuf->uAudioFmt, pvBuf, cbBuf, pcAcquiredFrames);
+    return AudioMixBufAcquireReadBlockEx(pMixBuf, &pMixBuf->Props, pvBuf, cbBuf, pcAcquiredFrames);
 }
 
 /**
  * Reads audio frames in a specific audio format.
+ *
  * If the audio format of the mixing buffer and the requested audio format do
  * not match the output will be converted accordingly.
  *
- * @return  IPRT status code.
+ * @returns VBox status code.
  * @param   pMixBuf             Mixing buffer to read audio frames from.
- * @param   enmFmt              Audio format to use for output.
+ * @param   pDstProps           The target format.
  * @param   pvBuf               Pointer to buffer to write output to.
  * @param   cbBuf               Size (in bytes) of buffer to write to.
@@ -1568,5 +1542,5 @@
  *                              the block that was acquired.
  */
-int AudioMixBufAcquireReadBlockEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt,
+int AudioMixBufAcquireReadBlockEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps,
                                   void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames)
 {
@@ -1581,7 +1555,11 @@
     uint32_t cFramesToRead = RT_MIN(pMixBuf->cUsed, AUDIOMIXBUF_B2F(pMixBuf, cbBuf));
 
-    AUDMIXBUF_LOG(("%s: cbBuf=%RU32 (%RU32 frames), cFramesToRead=%RU32, fmtSrc=0x%x, fmtDst=0x%x\n",
-                   pMixBuf->pszName, cbBuf, AUDIOMIXBUF_B2F(pMixBuf, cbBuf), cFramesToRead, pMixBuf->uAudioFmt, enmFmt));
-
+#ifdef AUDMIXBUF_LOG_ENABLED
+    char szTmp1[PDMAUDIOPROPSTOSTRING_MAX], szTmp2[PDMAUDIOPROPSTOSTRING_MAX];
+#endif
+    AUDMIXBUF_LOG(("%s: cbBuf=%RU32 (%RU32 frames), cFramesToRead=%RU32, MixBuf=%s, pDstProps=%s\n",
+                   pMixBuf->pszName, cbBuf, AUDIOMIXBUF_B2F(pMixBuf, cbBuf), cFramesToRead,
+                   PDMAudioPropsToString(&pMixBuf->Props, szTmp1, sizeof(szTmp1)),
+                   PDMAudioPropsToString(pDstProps, szTmp2, sizeof(szTmp2))));
     if (!cFramesToRead)
     {
@@ -1594,8 +1572,8 @@
 
     PFNPDMAUDIOMIXBUFCONVTO pfnConvTo;
-    if (pMixBuf->uAudioFmt == enmFmt)
+    if (PDMAudioPropsAreEqual(&pMixBuf->Props, pDstProps))
         pfnConvTo = pMixBuf->pfnConvTo;
     else
-        pfnConvTo = audioMixBufConvToLookup(enmFmt);
+        pfnConvTo = audioMixBufConvToLookup(pDstProps);
     AssertReturn(pfnConvTo, VERR_NOT_SUPPORTED);
 
@@ -1799,5 +1777,5 @@
 int AudioMixBufWriteAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offFrames, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten)
 {
-    return AudioMixBufWriteAtEx(pMixBuf, pMixBuf->uAudioFmt, offFrames, pvBuf, cbBuf, pcWritten);
+    return AudioMixBufWriteAtEx(pMixBuf, &pMixBuf->Props, offFrames, pvBuf, cbBuf, pcWritten);
 }
 
@@ -1812,14 +1790,13 @@
  *
  * @return  IPRT status code.
- * @param   pMixBuf                 Pointer to mixing buffer to write to.
- * @param   enmFmt                  Audio format supplied in the buffer.
- * @param   offFrames               Offset (in frames) starting to write at.
- * @param   pvBuf                   Pointer to audio buffer to be written.
- * @param   cbBuf                   Size (in bytes) of audio buffer.
- * @param   pcWritten               Returns number of audio frames written. Optional.
- */
-int AudioMixBufWriteAtEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt,
-                         uint32_t offFrames, const void *pvBuf, uint32_t cbBuf,
-                         uint32_t *pcWritten)
+ * @param   pMixBuf     Pointer to mixing buffer to write to.
+ * @param   pSrcProps   The source format.
+ * @param   offFrames   Offset (in frames) starting to write at.
+ * @param   pvBuf       Pointer to audio buffer to be written.
+ * @param   cbBuf       Size (in bytes) of audio buffer.
+ * @param   pcWritten   Returns number of audio frames written. Optional.
+ */
+int AudioMixBufWriteAtEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps,
+                         uint32_t offFrames, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten)
 {
     AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
@@ -1860,8 +1837,9 @@
     if (!pMixBuf->Volume.fMuted)
     {
-        if (pMixBuf->uAudioFmt != enmFmt)
-            pfnConvFrom = audioMixBufConvFromLookup(enmFmt);
+        if (PDMAudioPropsAreEqual(&pMixBuf->Props, pSrcProps))
+            pfnConvFrom = pMixBuf->pfnConvFrom;
         else
-            pfnConvFrom = pMixBuf->pfnConvFrom;
+            pfnConvFrom = audioMixBufConvFromLookup(pSrcProps);
+        AssertReturn(pfnConvFrom, VERR_NOT_SUPPORTED);
     }
     else
@@ -1871,10 +1849,9 @@
 
     uint32_t cWritten;
-    if (   pfnConvFrom
-        && cToWrite)
+    if (cToWrite)
     {
         PDMAUDMIXBUFCONVOPTS convOpts;
 
-        convOpts.cFrames           = cToWrite;
+        convOpts.cFrames            = cToWrite;
         convOpts.From.Volume.fMuted = pMixBuf->Volume.fMuted;
         convOpts.From.Volume.uLeft  = pMixBuf->Volume.uLeft;
@@ -1884,12 +1861,5 @@
     }
     else
-    {
         cWritten = 0;
-        if (!pfnConvFrom)
-        {
-            AssertFailed();
-            rc = VERR_NOT_SUPPORTED;
-        }
-    }
 
     AUDMIXBUF_LOG(("%s: offFrames=%RU32, cbBuf=%RU32, cToWrite=%RU32 (%zu bytes), cWritten=%RU32 (%zu bytes), rc=%Rrc\n",
@@ -1929,9 +1899,7 @@
  * @param   pcWritten               Returns number of audio frames written. Optional.
  */
-int AudioMixBufWriteCirc(PPDMAUDIOMIXBUF pMixBuf,
-                         const void *pvBuf, uint32_t cbBuf,
-                         uint32_t *pcWritten)
-{
-    return AudioMixBufWriteCircEx(pMixBuf, pMixBuf->uAudioFmt, pvBuf, cbBuf, pcWritten);
+int AudioMixBufWriteCirc(PPDMAUDIOMIXBUF pMixBuf, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten)
+{
+    return AudioMixBufWriteCircEx(pMixBuf, &pMixBuf->Props, pvBuf, cbBuf, pcWritten);
 }
 
@@ -1941,16 +1909,17 @@
  *
  * @return  IPRT status code, or VERR_BUFFER_OVERFLOW no space is available for writing anymore.
- * @param   pMixBuf                 Pointer to mixing buffer to write to.
- * @param   enmFmt                  Audio format supplied in the buffer.
- * @param   pvBuf                   Pointer to audio buffer to be written.
- * @param   cbBuf                   Size (in bytes) of audio buffer.
- * @param   pcWritten               Returns number of audio frames written. Optional.
- */
-int AudioMixBufWriteCircEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt,
+ * @param   pMixBuf     Pointer to mixing buffer to write to.
+ * @param   pSrcProps   The source format.
+ * @param   enmFmt      Audio format supplied in the buffer.
+ * @param   pvBuf       Pointer to audio buffer to be written.
+ * @param   cbBuf       Size (in bytes) of audio buffer.
+ * @param   pcWritten   Returns number of audio frames written. Optional.
+ */
+int AudioMixBufWriteCircEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps,
                            const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten)
 {
     AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
     AssertPtrReturn(pvBuf,   VERR_INVALID_POINTER);
-    /* pcbWritten is optional. */
+    AssertPtrNullReturn(pcWritten, VERR_INVALID_POINTER);
 
     if (!cbBuf)
@@ -1970,17 +1939,12 @@
     if (!pMixBuf->Volume.fMuted)
     {
-        if (pMixBuf->uAudioFmt != enmFmt)
-            pfnConvFrom = audioMixBufConvFromLookup(enmFmt);
+        if (PDMAudioPropsAreEqual(&pMixBuf->Props, pSrcProps))
+            pfnConvFrom = pMixBuf->pfnConvFrom;
         else
-            pfnConvFrom = pMixBuf->pfnConvFrom;
+            pfnConvFrom = audioMixBufConvFromLookup(pSrcProps);
+        AssertReturn(pfnConvFrom, VERR_NOT_SUPPORTED);
     }
     else
         pfnConvFrom = &audioMixBufConvFromSilence;
-
-    if (!pfnConvFrom)
-    {
-        AssertFailed();
-        return VERR_NOT_SUPPORTED;
-    }
 
     int rc = VINF_SUCCESS;
@@ -2034,6 +1998,9 @@
         *pcWritten = cWritten;
 
-    AUDMIXBUF_LOG(("%s: enmFmt=0x%x, cbBuf=%RU32 (%RU32 frames), cWritten=%RU32, rc=%Rrc\n",
-                   pMixBuf->pszName, enmFmt, cbBuf, AUDIOMIXBUF_B2F(pMixBuf, cbBuf), cWritten, rc));
+#ifdef AUDMIXBUF_LOG_ENABLED
+    char szTmp[PDMAUDIOPROPSTOSTRING_MAX];
+#endif
+    AUDMIXBUF_LOG(("%s: pSrcProps=%s, cbBuf=%RU32 (%RU32 frames), cWritten=%RU32, rc=%Rrc\n", pMixBuf->pszName,
+                   PDMAudioPropsToString(pSrcProps, szTmp, sizeof(szTmp)), cbBuf, AUDIOMIXBUF_B2F(pMixBuf, cbBuf), cWritten, rc));
     return rc;
 }
Index: trunk/src/VBox/Devices/Audio/AudioMixBuffer.h
===================================================================
--- trunk/src/VBox/Devices/Audio/AudioMixBuffer.h	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/AudioMixBuffer.h	(revision 88269)
@@ -26,5 +26,5 @@
 
 /** Constructs 32 bit value for given frequency, number of channels, bits per sample and signed bit.
- *  Note: This currently matches 1:1 the VRDE encoding -- this might change in the future, so better don't rely on this fact! */
+ * @note This currently matches 1:1 the VRDE encoding -- this might change in the future, so better don't rely on this fact! */
 #define AUDMIXBUF_AUDIO_FMT_MAKE(freq, c, bps, s) ((((s) & 0x1) << 28) + (((bps) & 0xFF) << 20) + (((c) & 0xF) << 16) + ((freq) & 0xFFFF))
 
@@ -40,14 +40,16 @@
 #define AUDMIXBUF_FMT_BYTES_PER_SAMPLE(a) ((AUDMIXBUF_AUDIO_FMT_BITS_PER_SAMPLE(a) + 7) / 8)
 
-/** Converts frames to bytes. */
-#define AUDIOMIXBUF_F2B(pBuf, frames) ((frames) << (pBuf)->cShift)
+/** Converts (audio) frames to bytes. */
+#define AUDIOMIXBUF_F2B(a_pMixBuf, a_cFrames)   PDMAUDIOPCMPROPS_F2B(&(a_pMixBuf)->Props, a_cFrames)
+/** Converts bytes to (audio) frames.
+ * @note Does *not* take the conversion ratio into account. */
+#define AUDIOMIXBUF_B2F(a_pMixBuf, a_cb)        PDMAUDIOPCMPROPS_B2F(&(a_pMixBuf)->Props, a_cb)
+
 /** Converts frames to bytes, respecting the conversion ratio to
  *  a linked buffer. */
-#define AUDIOMIXBUF_F2B_RATIO(pBuf, frames) ((((int64_t) frames << 32) / (pBuf)->iFreqRatio) << (pBuf)->cShift)
-/** Converts bytes to frames, *not* taking the conversion ratio
- *  into account. */
-#define AUDIOMIXBUF_B2F(pBuf, cb)  (cb >> (pBuf)->cShift)
-/** Converts number of frames according to the buffer's ratio. */
-#define AUDIOMIXBUF_F2F_RATIO(pBuf, frames)  (((int64_t) frames << 32) / (pBuf)->iFreqRatio)
+#define AUDIOMIXBUF_F2B_RATIO(a_pMixBuf, a_cFrames) AUDIOMIXBUF_F2B(a_pMixBuf, AUDIOMIXBUF_F2F_RATIO(a_pMixBuf, a_cFrames))
+/** Converts number of frames according to the buffer's ratio.
+ * @todo r=bird: Why the *signed* cast?  */
+#define AUDIOMIXBUF_F2F_RATIO(a_pMixBuf, a_cFrames) (((int64_t)(a_cFrames) << 32) / (a_pMixBuf)->iFreqRatio)
 
 
@@ -58,5 +60,5 @@
 uint32_t AudioMixBufFree(PPDMAUDIOMIXBUF pMixBuf);
 uint32_t AudioMixBufFreeBytes(PPDMAUDIOMIXBUF pMixBuf);
-int AudioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PPDMAUDIOPCMPROPS pProps, uint32_t cFrames);
+int AudioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PCPDMAUDIOPCMPROPS pProps, uint32_t cFrames);
 bool AudioMixBufIsEmpty(PPDMAUDIOMIXBUF pMixBuf);
 int AudioMixBufLinkTo(PPDMAUDIOMIXBUF pMixBuf, PPDMAUDIOMIXBUF pParent);
@@ -64,12 +66,13 @@
 int AudioMixBufMixToParent(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSrcFrames, uint32_t *pcSrcMixed);
 int AudioMixBufMixToParentEx(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSrcOffset, uint32_t cSrcFrames, uint32_t *pcSrcMixed);
-int AudioMixBufPeek(PPDMAUDIOMIXBUF pMixBuf, uint32_t cFramesToRead, PPDMAUDIOFRAME paSampleBuf, uint32_t cSampleBuf, uint32_t *pcFramesRead);
 int AudioMixBufPeekMutable(PPDMAUDIOMIXBUF pMixBuf, uint32_t cFramesToRead, PPDMAUDIOFRAME *ppvSamples, uint32_t *pcFramesRead);
 uint32_t AudioMixBufUsed(PPDMAUDIOMIXBUF pMixBuf);
 uint32_t AudioMixBufUsedBytes(PPDMAUDIOMIXBUF pMixBuf);
-int AudioMixBufReadAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offSamples, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
-int AudioMixBufReadAtEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt, uint32_t offSamples, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
-int AudioMixBufAcquireReadBlock(PPDMAUDIOMIXBUF pMixBuf, void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);
-int AudioMixBufAcquireReadBlockEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt, void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);
+int         AudioMixBufReadAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offFrames, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
+int         AudioMixBufReadAtEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps, uint32_t offFrames,
+                                void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
+int         AudioMixBufAcquireReadBlock(PPDMAUDIOMIXBUF pMixBuf, void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);
+int         AudioMixBufAcquireReadBlockEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps,
+                                          void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);
 void AudioMixBufReleaseReadBlock(PPDMAUDIOMIXBUF pMixBuf, uint32_t cFrames);
 uint32_t AudioMixBufReadPos(PPDMAUDIOMIXBUF pMixBuf);
@@ -79,8 +82,10 @@
 uint32_t AudioMixBufSizeBytes(PPDMAUDIOMIXBUF pMixBuf);
 void AudioMixBufUnlink(PPDMAUDIOMIXBUF pMixBuf);
-int AudioMixBufWriteAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offSamples, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
-int AudioMixBufWriteAtEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt, uint32_t offSamples, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
-int AudioMixBufWriteCirc(PPDMAUDIOMIXBUF pMixBuf, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
-int AudioMixBufWriteCircEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
+int         AudioMixBufWriteAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offSamples, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
+int         AudioMixBufWriteAtEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps, uint32_t offFrames,
+                                 const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
+int         AudioMixBufWriteCirc(PPDMAUDIOMIXBUF pMixBuf, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
+int         AudioMixBufWriteCircEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps,
+                                   const void *pvBuf,uint32_t cbBuf, uint32_t *pcWritten);
 uint32_t AudioMixBufWritePos(PPDMAUDIOMIXBUF pMixBuf);
 
Index: trunk/src/VBox/Devices/Audio/AudioMixer.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/AudioMixer.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/AudioMixer.cpp	(revision 88269)
@@ -264,5 +264,5 @@
         }
         else
-            RTMemFree(pMixer);
+            RTMemFree(pMixer); /** @todo leaks pszName due to badly structured code */
     }
     else
@@ -611,6 +611,6 @@
         return rc;
 
-    LogFlowFunc(("[%s] fFlags=0x%x (enmDir=%ld, %u bits, %RU8 channels, %RU32Hz)\n",
-                 pSink->pszName, fFlags, pCfg->enmDir, pCfg->Props.cbSample * 8, pCfg->Props.cChannels, pCfg->Props.uHz));
+    LogFlowFunc(("[%s] fFlags=0x%x (enmDir=%ld, %u bits, %RU8 channels, %RU32Hz)\n", pSink->pszName, fFlags, pCfg->enmDir,
+                 PDMAudioPropsSampleBits(&pCfg->Props), PDMAudioPropsChannels(&pCfg->Props), pCfg->Props.uHz));
 
     /*
@@ -1488,11 +1488,11 @@
 
     if (pSink->PCMProps.uHz)
-        LogFlowFunc(("[%s] Old format: %u bit, %RU8 channels, %RU32Hz\n",
-                     pSink->pszName, pSink->PCMProps.cbSample * 8, pSink->PCMProps.cChannels, pSink->PCMProps.uHz));
+        LogFlowFunc(("[%s] Old format: %u bit, %RU8 channels, %RU32Hz\n", pSink->pszName,
+                     PDMAudioPropsSampleBits(&pSink->PCMProps), PDMAudioPropsChannels(&pSink->PCMProps), pSink->PCMProps.uHz));
 
     memcpy(&pSink->PCMProps, pPCMProps, sizeof(PDMAUDIOPCMPROPS));
 
-    LogFlowFunc(("[%s] New format %u bit, %RU8 channels, %RU32Hz\n",
-                 pSink->pszName, pSink->PCMProps.cbSample * 8, pSink->PCMProps.cChannels, pSink->PCMProps.uHz));
+    LogFlowFunc(("[%s] New format %u bit, %RU8 channels, %RU32Hz\n", pSink->pszName, PDMAudioPropsSampleBits(&pSink->PCMProps),
+                 PDMAudioPropsChannels(&pSink->PCMProps), pSink->PCMProps.uHz));
 
     /* Also update the sink's mixing buffer format. */
Index: trunk/src/VBox/Devices/Audio/DevHda.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevHda.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DevHda.cpp	(revision 88269)
@@ -1449,9 +1449,11 @@
 
 # ifdef LOG_ENABLED
-                PDMAUDIOPCMPROPS Props;
-                rc2 = hdaR3SDFMTToPCMProps(HDA_STREAM_REG(pThis, FMT, uSD), &Props);
-                AssertRC(rc2);
-                LogFunc(("[SD%RU8] %RU32Hz, %RU8bit, %RU8 channel(s)\n",
-                         uSD, Props.uHz, Props.cbSample * 8 /* Bit */, Props.cChannels));
+                if (LogIsEnabled())
+                {
+                    PDMAUDIOPCMPROPS Props = { 0 };
+                    rc2 = hdaR3SDFMTToPCMProps(HDA_STREAM_REG(pThis, FMT, uSD), &Props); AssertRC(rc2);
+                    LogFunc(("[SD%RU8] %RU32Hz, %RU8bit, %RU8 channel(s)\n",
+                             uSD, Props.uHz, PDMAudioPropsSampleBits(&Props), PDMAudioPropsChannels(&Props)));
+                }
 # endif
                 /* (Re-)initialize the stream with current values. */
@@ -1667,5 +1669,5 @@
 
     /** @todo Make the following configurable through mixer API and/or CFGM? */
-    switch (pCfg->Props.cChannels)
+    switch (PDMAudioPropsGetChannels(&pCfg->Props))
     {
         case 3:  /* 2.1: Front (Stereo) + LFE. */
@@ -1706,5 +1708,5 @@
     if (rc == VERR_NOT_SUPPORTED)
     {
-        LogRel2(("HDA: Warning: Unsupported channel count (%RU8), falling back to stereo channels (2)\n", pCfg->Props.cChannels));
+        LogRel2(("HDA: Warning: Unsupported channel count (%RU8), falling back to stereo channels (2)\n", pCfg->Props.cChannelsX));
 
         /* Fall back to 2 channels (see below in fUseFront block). */
@@ -1723,6 +1725,5 @@
             pCfg->u.enmDst          = PDMAUDIOPLAYBACKDST_FRONT;
             pCfg->enmLayout         = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
-
-            pCfg->Props.cShift      = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
+            /// @todo PDMAudioPropsSetChannels(&pCfg->Props, 2); ?
 
             rc = hdaR3CodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_FRONT, pCfg);
@@ -1737,7 +1738,5 @@
             pCfg->u.enmDst          = PDMAUDIOPLAYBACKDST_CENTER_LFE;
             pCfg->enmLayout         = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
-
-            pCfg->Props.cChannels   = (fUseCenter && fUseLFE) ? 2 : 1;
-            pCfg->Props.cShift      = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
+            PDMAudioPropsSetChannels(&pCfg->Props, fUseCenter && fUseLFE ? 2 : 1);
 
             rc = hdaR3CodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_CENTER_LFE, pCfg);
@@ -1751,7 +1750,5 @@
             pCfg->u.enmDst          = PDMAUDIOPLAYBACKDST_REAR;
             pCfg->enmLayout         = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
-
-            pCfg->Props.cChannels   = 2;
-            pCfg->Props.cShift      = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
+            PDMAudioPropsSetChannels(&pCfg->Props, 2);
 
             rc = hdaR3CodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_REAR, pCfg);
@@ -1912,6 +1909,6 @@
     int rc2 = hdaR3SDFMTToPCMProps(RT_LO_U16(u32Value), &Props);
     AssertRC(rc2);
-    LogFunc(("[SD%RU8] Set to %#x (%RU32Hz, %RU8bit, %RU8 channel(s))\n",
-             HDA_SD_NUM_FROM_REG(pThis, FMT, iReg), u32Value, Props.uHz, Props.cbSample * 8 /* Bit */, Props.cChannels));
+    LogFunc(("[SD%RU8] Set to %#x (%RU32Hz, %RU8bit, %RU8 channel(s))\n", HDA_SD_NUM_FROM_REG(pThis, FMT, iReg), u32Value,
+             PDMAudioPropsHz(&Props), PDMAudioPropsSampleBits(&Props), PDMAudioPropsChannels(&Props)));
 
     /*
@@ -2319,5 +2316,5 @@
     AssertPtrReturn(pCfg,     VERR_INVALID_POINTER);
 
-    LogFunc(("szSink=%s, szStream=%s, cChannels=%RU8\n", pMixSink->pszName, pCfg->szName, pCfg->Props.cChannels));
+    LogFunc(("szSink=%s, szStream=%s, cChannels=%RU8\n", pMixSink->pszName, pCfg->szName, PDMAudioPropsChannels(&pCfg->Props)));
 
     PPDMAUDIOSTREAMCFG pStreamCfg = PDMAudioStrmCfgDup(pCfg);
@@ -5356,5 +5353,10 @@
         PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.uHz, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES,
                                "The stream frequency.",                     "Stream%u/Cfg/Hz", idxStream);
-        PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.cChannels, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
+        PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.cbFrame, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
+                               "The number of channels.",                   "Stream%u/Cfg/FrameSize-Host", idxStream);
+        PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.Mapping.GuestProps.cbFrame, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
+                               "The number of channels.",                   "Stream%u/Cfg/FrameSize-Guest", idxStream);
+#if 0 /** @todo this would require some callback */
+        PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.cChannelsX, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
                                "The number of channels.",                   "Stream%u/Cfg/Channels-Host", idxStream);
         PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.Mapping.GuestProps.cChannels, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
@@ -5362,4 +5364,5 @@
         PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.cbSample, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
                                "The size of a sample (per channel).",       "Stream%u/Cfg/cbSample", idxStream);
+#endif
     }
 
Index: trunk/src/VBox/Devices/Audio/DevHdaCommon.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevHdaCommon.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DevHdaCommon.cpp	(revision 88269)
@@ -22,4 +22,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define LOG_GROUP LOG_GROUP_DEV_HDA
 #include <iprt/assert.h>
 #include <iprt/errcore.h>
@@ -27,6 +28,6 @@
 
 #include <VBox/AssertGuest.h>
-
-#define LOG_GROUP LOG_GROUP_DEV_HDA
+#include <VBox/vmm/pdmaudioinline.h>
+
 #include <VBox/log.h>
 
@@ -34,4 +35,5 @@
 #include "DevHdaCommon.h"
 #include "DevHdaStream.h"
+
 
 
@@ -304,15 +306,15 @@
     }
 
-    uint8_t cBytes = 0;
+    uint8_t cbSample = 0;
     switch (EXTRACT_VALUE(u16SDFMT, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT))
     {
         case 0:
-            cBytes = 1;
+            cbSample = 1;
             break;
         case 1:
-            cBytes = 2;
+            cbSample = 2;
             break;
         case 4:
-            cBytes = 4;
+            cbSample = 4;
             break;
         default:
@@ -324,13 +326,5 @@
 
     if (RT_SUCCESS(rc))
-    {
-        RT_BZERO(pProps, sizeof(PDMAUDIOPCMPROPS));
-
-        pProps->cbSample  = cBytes;
-        pProps->fSigned   = true;
-        pProps->cChannels = (u16SDFMT & 0xf) + 1;
-        pProps->uHz       = u32Hz * u32HzMult / u32HzDiv;
-        pProps->cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pProps->cbSample, pProps->cChannels);
-    }
+        PDMAudioPropsInit(pProps, cbSample, true /*fSigned*/, (u16SDFMT & 0xf) + 1 /*cChannels*/, u32Hz * u32HzMult / u32HzDiv);
 
 # undef EXTRACT_VALUE
Index: trunk/src/VBox/Devices/Audio/DevHdaStream.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevHdaStream.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DevHdaStream.cpp	(revision 88269)
@@ -739,7 +739,7 @@
 
     /* Serious paranoia: */
-    ASSERT_GUEST_LOGREL_MSG_STMT(cbCircBuf % (pCfg->Props.cbSample * pCfg->Props.cChannels) == 0,
+    ASSERT_GUEST_LOGREL_MSG_STMT(cbCircBuf % PDMAudioPropsFrameSize(&pCfg->Props) == 0,
                                  ("Ring buffer size (%RU32) for stream #%RU8 not aligned to the (host) frame size (%RU8)\n",
-                                  cbCircBuf, uSD, pCfg->Props.cbSample * pCfg->Props.cChannels),
+                                  cbCircBuf, uSD, PDMAudioPropsFrameSize(&pCfg->Props)),
                                  rc = VERR_INVALID_PARAMETER);
     ASSERT_GUEST_LOGREL_MSG_STMT(cbCircBuf, ("Ring buffer size for stream #%RU8 is invalid\n", uSD),
Index: trunk/src/VBox/Devices/Audio/DevHdaStreamMap.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevHdaStreamMap.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DevHdaStreamMap.cpp	(revision 88269)
@@ -209,8 +209,9 @@
      *        - have a simple (raw) data layout
      *        - work in a non-striped fashion, e.g. interleaved (only on one SDn, not spread over multiple SDns) */
-    if  (   pProps->cChannels == 1  /* Mono */
-         || pProps->cChannels == 2  /* Stereo */
-         || pProps->cChannels == 4  /* Quadrophonic */
-         || pProps->cChannels == 6) /* Surround (5.1) */
+    uint8_t cChannels = PDMAudioPropsChannels(pProps);
+    if  (   cChannels == 1  /* Mono */
+         || cChannels == 2  /* Stereo */
+         || cChannels == 4  /* Quadrophonic */
+         || cChannels == 6) /* Surround (5.1) */
     {
         /*
@@ -218,19 +219,18 @@
          */
         memcpy(&pMap->GuestProps, pProps, sizeof(PDMAUDIOPCMPROPS));
-        if (pProps->cChannels != cHostChannels)
+        if (cChannels != cHostChannels)
         {
-            if (pProps->cChannels == 1)
+            if (cChannels == 1)
                 LogRelMax(32, ("HDA: Warning: Guest mono, host stereo.\n"));
-            else if (cHostChannels == 1 && pProps->cChannels == 2)
+            else if (cHostChannels == 1 && cChannels == 2)
                 LogRelMax(32, ("HDA: Warning: Host mono, guest stereo.\n"));
             else
 #ifndef VBOX_WITH_AUDIO_HDA_51_SURROUND
                 LogRelMax(32, ("HDA: Warning: Guest configured %u channels, host only supports %u. Ignoring additional channels.\n",
-                               pProps->cChannels, cHostChannels));
+                               cChannels, cHostChannels));
 #else
 # error reconsider the above logic
 #endif
-            pProps->cChannels = cHostChannels;
-            pProps->cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT(pProps);
+            PDMAudioPropsSetChannels(pProps, cHostChannels);
         }
 
@@ -238,8 +238,8 @@
          * Pick conversion functions.
          */
-        Assert(pMap->GuestProps.cbSample == pProps->cbSample);
+        Assert(PDMAudioPropsSampleSize(&pMap->GuestProps) == PDMAudioPropsSampleSize(pProps));
 
         /* If the channel count matches, we can use the memcpy converters: */
-        if (pProps->cChannels == pMap->GuestProps.cChannels)
+        if (PDMAudioPropsChannels(pProps) == PDMAudioPropsChannels(&pMap->GuestProps))
         {
             pMap->pfnGuestToHost = hdaR3StreamMap_GenericCopy;
@@ -252,8 +252,8 @@
                first two channels and map this onto the host stereo ones. */
             AssertReturn(cHostChannels == 2, VERR_NOT_SUPPORTED);
-            switch (pMap->GuestProps.cbSample)
+            switch (PDMAudioPropsSampleSize(&pMap->GuestProps))
             {
                 case 2:
-                    if (pMap->GuestProps.cChannels > 1)
+                    if (PDMAudioPropsChannels(&pMap->GuestProps) > 1)
                     {
                         pMap->pfnGuestToHost = hdaR3StreamMap_G2H_GenericS16_NonMono2Stereo;
@@ -268,5 +268,5 @@
 
                 case 4:
-                    if (pMap->GuestProps.cChannels > 1)
+                    if (PDMAudioPropsChannels(&pMap->GuestProps) > 1)
                     {
                         pMap->pfnGuestToHost = hdaR3StreamMap_G2H_GenericS32_NonMono2Stereo;
@@ -281,5 +281,5 @@
 
                 default:
-                    AssertMsgFailedReturn(("cbSample=%u\n", pMap->GuestProps.cbSample), VERR_NOT_SUPPORTED);
+                    AssertMsgFailedReturn(("cbSample=%u\n", PDMAudioPropsChannels(&pMap->GuestProps)), VERR_NOT_SUPPORTED);
             }
             pMap->fMappingNeeded = true;
@@ -297,6 +297,6 @@
             pMapLR->aenmIDs[0]  = PDMAUDIOSTREAMCHANNELID_FRONT_LEFT;
             pMapLR->aenmIDs[1]  = PDMAUDIOSTREAMCHANNELID_FRONT_RIGHT;
-            pMapLR->cbFrame     = pProps->cbSample * pProps->cChannels;
-            pMapLR->cbStep      = pProps->cbSample * 2 /* Front left + Front right channels */;
+            pMapLR->cbFrame     = PDMAudioPropsFrameSize(pProps);
+            pMapLR->cbStep      = PDMAudioPropsSampleSize(pProps) * 2 /* Front left + Front right channels */;
             pMapLR->offFirst    = 0;
             pMapLR->offNext     = pMapLR->offFirst;
@@ -334,5 +334,5 @@
     hdaR3StreamMapReset(pMap);
 
-    pMap->cbGuestFrame = pProps->cChannels * pProps->cbSample;
+    pMap->cbGuestFrame = PDMAudioPropsFrameSize(pProps);
     int rc = hdaR3StreamMapSetup(pMap, pProps, cHostChannels);
     if (RT_SUCCESS(rc))
@@ -346,5 +346,5 @@
         {
             LogFunc(("cChannels=%RU8, cBytes=%RU8 -> cbGuestFrame=%RU32\n",
-                     pProps->cChannels, pProps->cbSample, pMap->cbGuestFrame));
+                     PDMAudioPropsChannels(pProps), PDMAudioPropsSampleSize(pProps), pMap->cbGuestFrame));
 
             Assert(pMap->cbGuestFrame); /* Frame size must not be 0. */
Index: trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 88269)
@@ -2137,18 +2137,14 @@
 static int ichac97R3StreamOpen(PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce)
 {
-    PDMAUDIOSTREAMCFG Cfg;
+    int                 rc = VINF_SUCCESS;
+    PAUDMIXSINK         pMixSink;
+    PDMAUDIOSTREAMCFG   Cfg;
     RT_ZERO(Cfg);
-    Cfg.Props.cChannels = 2;
-    Cfg.Props.cbSample  = 2 /* 16-bit */;
-    Cfg.Props.fSigned   = true;
-    Cfg.Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(Cfg.Props.cbSample, Cfg.Props.cChannels);
-
-    int rc = VINF_SUCCESS;
-    PAUDMIXSINK pMixSink;
     switch (pStream->u8SD)
     {
         case AC97SOUNDSOURCE_PI_INDEX:
         {
-            Cfg.Props.uHz   = ichac97MixerGet(pThis, AC97_PCM_LR_ADC_Rate);
+            PDMAudioPropsInit(&Cfg.Props, 2 /*16-bit*/, true /*signed*/, 2 /*stereo*/,
+                              ichac97MixerGet(pThis, AC97_PCM_LR_ADC_Rate));
             Cfg.enmDir      = PDMAUDIODIR_IN;
             Cfg.u.enmSrc    = PDMAUDIORECSRC_LINE;
@@ -2162,5 +2158,6 @@
         case AC97SOUNDSOURCE_MC_INDEX:
         {
-            Cfg.Props.uHz   = ichac97MixerGet(pThis, AC97_MIC_ADC_Rate);
+            PDMAudioPropsInit(&Cfg.Props, 2 /*16-bit*/, true /*signed*/, 2 /*stereo*/,
+                              ichac97MixerGet(pThis, AC97_MIC_ADC_Rate));
             Cfg.enmDir      = PDMAUDIODIR_IN;
             Cfg.u.enmSrc    = PDMAUDIORECSRC_MIC;
@@ -2174,5 +2171,6 @@
         case AC97SOUNDSOURCE_PO_INDEX:
         {
-            Cfg.Props.uHz   = ichac97MixerGet(pThis, AC97_PCM_Front_DAC_Rate);
+            PDMAudioPropsInit(&Cfg.Props, 2 /*16-bit*/, true /*signed*/, 2 /*stereo*/,
+                              ichac97MixerGet(pThis, AC97_PCM_Front_DAC_Rate));
             Cfg.enmDir      = PDMAUDIODIR_OUT;
             Cfg.u.enmDst    = PDMAUDIOPLAYBACKDST_FRONT;
@@ -2197,6 +2195,6 @@
             || fForce)
         {
-            LogRel2(("AC97: (Re-)Opening stream '%s' (%RU32Hz, %RU8 channels, %s%RU8)\n",
-                     Cfg.szName, Cfg.Props.uHz, Cfg.Props.cChannels, Cfg.Props.fSigned ? "S" : "U", Cfg.Props.cbSample * 8));
+            LogRel2(("AC97: (Re-)Opening stream '%s' (%RU32Hz, %RU8 channels, %s%RU8)\n", Cfg.szName, Cfg.Props.uHz,
+                     PDMAudioPropsChannels(&Cfg.Props), Cfg.Props.fSigned ? "S" : "U",  PDMAudioPropsSampleBits(&Cfg.Props)));
 
             LogFlowFunc(("[SD%RU8] uHz=%RU32\n", pStream->u8SD, Cfg.Props.uHz));
Index: trunk/src/VBox/Devices/Audio/DevSB16.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 88269)
@@ -910,10 +910,5 @@
     pCfg->u.enmDst        = PDMAUDIOPLAYBACKDST_FRONT;
     pCfg->enmLayout       = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
-
-    pCfg->Props.uHz       = pThis->freq;
-    pCfg->Props.cChannels = 1; /* Mono */
-    pCfg->Props.cbSample  = 1 /* 8-bit */;
-    pCfg->Props.fSigned   = false;
-    pCfg->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
+    PDMAudioPropsInit(&pCfg->Props, 1 /*8-bit*/, false /*fSigned*/, 1 /*mono*/, pThis->freq);
 
     AssertCompile(sizeof(pCfg->szName) >= sizeof("Output"));
@@ -1833,10 +1828,5 @@
         PDMAUDIOSTREAMCFG Cfg;
         RT_ZERO(Cfg);
-
-        Cfg.Props.uHz       = pThis->freq;
-        Cfg.Props.cChannels = 1 << pThis->fmt_stereo;
-        Cfg.Props.cbSample  = pThis->fmt_bits / 8;
-        Cfg.Props.fSigned   = RT_BOOL(pThis->fmt_signed);
-        Cfg.Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(Cfg.Props.cbSample, Cfg.Props.cChannels);
+        PDMAudioPropsInit(&Cfg.Props, pThis->fmt_bits / 8, pThis->fmt_signed != 0, 1 << pThis->fmt_stereo, pThis->freq);
 
         if (!PDMAudioStrmCfgMatchesProps(&Cfg, &pThis->Out.Cfg.Props))
Index: trunk/src/VBox/Devices/Audio/DrvAudio.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DrvAudio.cpp	(revision 88269)
@@ -716,12 +716,12 @@
 
     LogRel2(("Audio: Creating stream '%s'\n", pStream->szName));
-    LogRel2(("Audio: Guest %s format for '%s': %RU32Hz, %u%s, %RU8 %s\n",
+    LogRel2(("Audio: Guest %s format for '%s': %RU32Hz, %u%s, %RU8 channel%s\n",
              pCfgGuest->enmDir == PDMAUDIODIR_IN ? "recording" : "playback", pStream->szName,
-             pCfgGuest->Props.uHz, pCfgGuest->Props.cbSample * 8, pCfgGuest->Props.fSigned ? "S" : "U",
-             pCfgGuest->Props.cChannels, pCfgGuest->Props.cChannels == 1 ? "Channel" : "Channels"));
-    LogRel2(("Audio: Requested host %s format for '%s': %RU32Hz, %u%s, %RU8 %s\n",
+             pCfgGuest->Props.uHz, PDMAudioPropsSampleBits(&pCfgGuest->Props), pCfgGuest->Props.fSigned ? "S" : "U",
+             PDMAudioPropsChannels(&pCfgGuest->Props), PDMAudioPropsChannels(&pCfgGuest->Props) == 1 ? "" : "s"));
+    LogRel2(("Audio: Requested host %s format for '%s': %RU32Hz, %u%s, %RU8 channel%s\n",
              pCfgHost->enmDir == PDMAUDIODIR_IN ? "recording" : "playback", pStream->szName,
-             pCfgHost->Props.uHz, pCfgHost->Props.cbSample * 8, pCfgHost->Props.fSigned ? "S" : "U",
-             pCfgHost->Props.cChannels, pCfgHost->Props.cChannels == 1 ? "Channel" : "Channels"));
+             pCfgHost->Props.uHz, PDMAudioPropsSampleBits(&pCfgHost->Props), pCfgHost->Props.fSigned ? "S" : "U",
+             PDMAudioPropsChannels(&pCfgHost->Props), PDMAudioPropsChannels(&pCfgHost->Props) == 1 ? "" : "s"));
 
     PDMAUDIOSTREAMCFG CfgHostAcq;
@@ -730,13 +730,11 @@
         return rc;
 
-#ifdef LOG_ENABLED
     LogFunc(("[%s] Acquired host format:\n",  pStream->szName));
     PDMAudioStrmCfgLog(&CfgHostAcq);
-#endif
-
-    LogRel2(("Audio: Acquired host %s format for '%s': %RU32Hz, %u%s, %RU8 %s\n",
+    LogRel2(("Audio: Acquired host %s format for '%s': %RU32Hz, %u%s, %RU8 channel%s\n",
              CfgHostAcq.enmDir == PDMAUDIODIR_IN ? "recording" : "playback",  pStream->szName,
-             CfgHostAcq.Props.uHz, CfgHostAcq.Props.cbSample * 8, CfgHostAcq.Props.fSigned ? "S" : "U",
-             CfgHostAcq.Props.cChannels, CfgHostAcq.Props.cChannels == 1 ? "Channel" : "Channels"));
+             CfgHostAcq.Props.uHz, PDMAudioPropsSampleBits(&CfgHostAcq.Props), CfgHostAcq.Props.fSigned ? "S" : "U",
+             PDMAudioPropsChannels(&CfgHostAcq.Props), PDMAudioPropsChannels(&CfgHostAcq.Props) == 1 ? "" : "s"));
+    Assert(PDMAudioPropsAreValid(&CfgHostAcq.Props));
 
     /* Let the user know if the backend changed some of the tweakable values. */
@@ -755,4 +753,5 @@
                  PDMAudioPropsFramesToMilli(&pCfgHost->Props, pCfgHost->Backend.cFramesPreBuffering), pCfgHost->Backend.cFramesPreBuffering,
                  PDMAudioPropsFramesToMilli(&CfgHostAcq.Props, CfgHostAcq.Backend.cFramesPreBuffering), CfgHostAcq.Backend.cFramesPreBuffering));
+
     /*
      * Configure host buffers.
@@ -801,7 +800,4 @@
     AudioMixBufDestroy(&pStream->Host.MixBuf);
 
-    /* Make sure to (re-)set the host buffer's shift size. */
-    CfgHostAcq.Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(CfgHostAcq.Props.cbSample, CfgHostAcq.Props.cChannels);
-
     rc = AudioMixBufInit(&pStream->Host.MixBuf, pStream->szName, &CfgHostAcq.Props, CfgHostAcq.Backend.cFramesBufferSize);
     AssertRC(rc);
@@ -825,7 +821,4 @@
     /* Set the guests's default audio data layout. */
     pCfgGuest->enmLayout = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
-
-    /* Make sure to (re-)set the guest buffer's shift size. */
-    pCfgGuest->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgGuest->Props.cbSample, pCfgGuest->Props.cChannels);
 
     rc = AudioMixBufInit(&pStream->Guest.MixBuf, pStream->szName, &pCfgGuest->Props, CfgHostAcq.Backend.cFramesBufferSize);
@@ -1448,17 +1441,16 @@
 
 /**
- * Worker for drvAudioStreamPlay that plays non-interleaved data.
+ * Worker for drvAudioStreamPlay that does the actual playing.
  *
  * @returns VBox status code.
  * @param   pThis           The audio driver instance data.
  * @param   pStream         The stream to play.
- * @param   cFramesToPlay   Number of audio frames to play.
+ * @param   cFramesToPlay   Number of audio frames to play.  The backend is
+ *                          supposed to have buffer space for this.
  * @param   pcFramesPlayed  Where to return the number of audio frames played.
  */
-static int drvAudioStreamPlayNonInterleaved(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream,
-                                            uint32_t cFramesToPlay, uint32_t *pcFramesPlayed)
+static int drvAudioStreamPlayDoIt(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, uint32_t cFramesToPlay, uint32_t *pcFramesPlayed)
 {
     Assert(pStream->enmDir == PDMAUDIODIR_OUT);
-    Assert(pStream->Host.Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED);
 
     /*
@@ -1490,22 +1482,14 @@
         if (RT_SUCCESS(rc))
         {
-            if (cbPlayed)
-            {
-                if (pThis->Out.Cfg.Dbg.fEnabled)
-                    AudioHlpFileWrite(pStream->Out.Dbg.pFilePlayNonInterleaved, abChunk, cbPlayed, 0 /* fFlags */);
-
-                if (cbRead != cbPlayed)
-                    LogRel2(("Audio: Host stream '%s' played wrong amount (%RU32 bytes read but played %RU32)\n",
-                             pStream->szName, cbRead, cbPlayed));
-
-                cFramesPlayed  = AUDIOMIXBUF_B2F(&pStream->Host.MixBuf, cbPlayed);
-                AssertStmt(cFramesLeft >= cFramesPlayed, cFramesPlayed = cFramesLeft);
-                cFramesLeft   -= cFramesPlayed;
-            }
-            else
-            {
-                /** @todo r=bird: If the backend is doing non-blocking writes, we'll probably
-                 *        be spinning like crazy here...  The ALSA backend is non-blocking.   */
-            }
+            if (pThis->Out.Cfg.Dbg.fEnabled)
+                AudioHlpFileWrite(pStream->Out.Dbg.pFilePlayNonInterleaved, abChunk, cbPlayed, 0 /* fFlags */);
+
+            if (cbRead != cbPlayed)
+                LogRel2(("Audio: Host stream '%s' played wrong amount (%RU32 bytes read but played %RU32)\n",
+                         pStream->szName, cbRead, cbPlayed));
+
+            cFramesPlayed  = AUDIOMIXBUF_B2F(&pStream->Host.MixBuf, cbPlayed);
+            AssertStmt(cFramesLeft >= cFramesPlayed, cFramesPlayed = cFramesLeft);
+            cFramesLeft   -= cFramesPlayed;
         }
 
@@ -1513,71 +1497,9 @@
 
         AssertRCBreak(rc); /* (this is here for Acquire/Release symmetry - which isn't at all necessary) */
+        AssertBreak(cbPlayed > 0); /* (ditto) */
     }
 
     Log3Func(("[%s] Played %RU32/%RU32 frames, rc=%Rrc\n", pStream->szName, cFramesToPlay - cFramesLeft, cFramesToPlay, rc));
     *pcFramesPlayed = cFramesToPlay - cFramesLeft;
-    return rc;
-}
-
-/**
- * Plays an audio host output stream which has been configured for raw audio (layout) data.
- *
- * @returns VBox status code.
- * @param   pThis               Pointer to driver instance.
- * @param   pStream             Stream to play.
- * @param   cFramesToPlay       Number of audio frames to play.
- * @param   pcFramesPlayed      Where to return number of audio frames played.
- */
-static int drvAudioStreamPlayRaw(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, uint32_t cFramesToPlay, uint32_t *pcFramesPlayed)
-{
-    Assert(pStream->enmDir == PDMAUDIODIR_OUT);
-    Assert(pStream->Host.Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_RAW);
-
-    /*
-     * ...
-     */
-    int      rc          = VINF_SUCCESS;
-    uint32_t cFramesLeft = cFramesToPlay;
-    while (cFramesLeft > 0)
-    {
-        PDMAUDIOFRAME   aFrames[_2K];
-        uint32_t        cFramesRead = 0;
-        /** @todo r=bird: Peek functions do _not_ generally drop stuff from what they're
-         *        peeking into.  We normally name such functions Read.  (Oh man, am I
-         *        getting tired of this kind of crap.) */
-        rc = AudioMixBufPeek(&pStream->Host.MixBuf, cFramesLeft, aFrames,
-                             RT_MIN(cFramesLeft, RT_ELEMENTS(aFrames)), &cFramesRead);
-        if (RT_SUCCESS(rc))
-        {
-            Assert(cFramesRead <= RT_ELEMENTS(aFrames));
-            if (cFramesRead)
-            {
-                uint32_t cbPlayed = 0;
-                rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pStream->pvBackend,
-                                                         aFrames, cFramesRead * sizeof(aFrames[0]), &cbPlayed);
-                AssertRCBreak(rc);
-                /** @todo r=bird: This is a natural follow up to the non-peeking peek crap
-                 *        above.  It works because VRDE is the only consumer and it always
-                 *        processes all that it gets. */
-                AssertBreakStmt(cbPlayed == cFramesRead * sizeof(aFrames[0]), rc = VERR_INTERNAL_ERROR_2);
-
-                Assert(cFramesRead <= cFramesLeft);
-                cFramesLeft -= cFramesRead;
-            }
-            else
-            {
-/** @todo r=bird: This looks totally loopy.  Why should another call return data
- *        when the first one didn't? */
-                if (rc == VINF_AUDIO_MORE_DATA_AVAILABLE) /* Do another peeking round if there is more data available. */
-                    continue;
-                break;
-            }
-        }
-        else
-            break;
-    }
-
-    *pcFramesPlayed = cFramesToPlay - cFramesLeft;
-    Log3Func(("[%s] Played %RU32/%RU32 frames, rc=%Rrc\n", pStream->szName, cFramesToPlay - cFramesLeft, cFramesToPlay, rc));
     return rc;
 }
@@ -1675,6 +1597,5 @@
         if (cFramesLive >= pStream->Host.Cfg.Backend.cFramesPreBuffering)
         {
-            LogRel2(("Audio: Stream '%s' buffering complete\n", pStream->szName));
-            Log3Func(("[%s] Dbg: Buffering complete!\n", pStream->szName));
+            LogRel2(("Audio: Stream '%s' buffering complete!\n", pStream->szName));
             pStream->fThresholdReached = fJustStarted = true;
         }
@@ -1690,6 +1611,5 @@
                  && (pStream->fStatus & PDMAUDIOSTREAMSTS_FLAGS_PENDING_DISABLE))
         {
-            LogRel2(("Audio: Stream '%s' buffering complete (short sound)\n", pStream->szName));
-            Log3Func(("[%s] Dbg: Buffering complete (short)!\n", pStream->szName));
+            LogRel2(("Audio: Stream '%s' buffering complete (short sound)!\n", pStream->szName));
             pStream->fThresholdReached = fJustStarted = true;
         }
@@ -1756,10 +1676,5 @@
          *        https://stackoverflow.com/questions/17879933/whats-the-interleaved-audio
          */
-        if (RT_LIKELY(pStream->Host.Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED))
-            rc = drvAudioStreamPlayNonInterleaved(pThis, pStream, cFramesToPlay, pcFramesPlayed);
-        else if (pStream->Host.Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_RAW)
-            rc = drvAudioStreamPlayRaw(pThis, pStream, cFramesToPlay, pcFramesPlayed);
-        else
-            AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
+        rc = drvAudioStreamPlayDoIt(pThis, pStream, cFramesToPlay, pcFramesPlayed);
 
         if (pThis->pHostDrvAudio->pfnStreamPlayEnd)
@@ -3085,8 +3000,9 @@
      * PCM
      */
-    if (pDrvCfg->Props.cbSample) /* Anything set via custom extra-data? */
-    {
-        pCfgReq->Props.cbSample = pDrvCfg->Props.cbSample;
-        LogRel2(("Audio: Using custom sample size of %RU8 bytes for stream '%s'\n", pCfgReq->Props.cbSample, pStream->szName));
+    if (PDMAudioPropsSampleSize(&pDrvCfg->Props) != 0) /* Anything set via custom extra-data? */
+    {
+        PDMAudioPropsSetSampleSize(&pCfgReq->Props, PDMAudioPropsSampleSize(&pDrvCfg->Props));
+        LogRel2(("Audio: Using custom sample size of %RU8 bytes for stream '%s'\n",
+                 PDMAudioPropsSampleSize(&pCfgReq->Props), pStream->szName));
     }
 
@@ -3111,12 +3027,9 @@
     }
 
-    if (pDrvCfg->Props.cChannels) /* Anything set via custom extra-data? */
-    {
-        pCfgReq->Props.cChannels = pDrvCfg->Props.cChannels;
-        LogRel2(("Audio: Using custom %RU8 channel(s) for stream '%s'\n", pCfgReq->Props.cChannels, pStream->szName));
-    }
-
-    /* Make sure to (re-)set the host buffer's shift size. */
-    pCfgReq->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgReq->Props.cbSample, pCfgReq->Props.cChannels);
+    if (PDMAudioPropsChannels(&pDrvCfg->Props) != 0) /* Anything set via custom extra-data? */
+    {
+        PDMAudioPropsSetChannels(&pCfgReq->Props, PDMAudioPropsChannels(&pDrvCfg->Props));
+        LogRel2(("Audio: Using custom %RU8 channel(s) for stream '%s'\n", PDMAudioPropsChannels(&pDrvCfg->Props), pStream->szName));
+    }
 
     /* Validate PCM properties. */
@@ -3237,9 +3150,9 @@
 
     /* Validate acquired configuration. */
-    if (!AudioHlpStreamCfgIsValid(pCfgAcq))
-    {
-        LogRel(("Audio: Creating stream '%s' returned an invalid backend configuration, skipping\n", pStream->szName));
-        return VERR_INVALID_PARAMETER;
-    }
+    char szTmp[PDMAUDIOPROPSTOSTRING_MAX];
+    AssertLogRelMsgReturn(AudioHlpStreamCfgIsValid(pCfgAcq),
+                          ("Audio: Creating stream '%s' returned an invalid backend configuration (%s), skipping\n",
+                           pStream->szName, PDMAudioPropsToString(&pCfgAcq->Props, szTmp, sizeof(szTmp))),
+                          VERR_INVALID_PARAMETER);
 
     /* Let the user know that the backend changed one of the values requested above. */
@@ -3637,4 +3550,5 @@
     }
 
+    PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->Out.StatsReBuffering);
 #ifdef VBOX_WITH_STATISTICS
     PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->Stats.TotalStreamsActive);
@@ -3787,15 +3701,19 @@
         AssertRCReturn(rc, rc);
 
-        QUERY_VAL_RET(8,  "PCMSampleBit",        &pAudioCfg->Props.cbSample,    0,
-                         pAudioCfg->Props.cbSample == 0
-                      || pAudioCfg->Props.cbSample == 8
-                      || pAudioCfg->Props.cbSample == 16
-                      || pAudioCfg->Props.cbSample == 32
-                      || pAudioCfg->Props.cbSample == 64,
+        uint8_t cSampleBits = 0;
+        QUERY_VAL_RET(8,  "PCMSampleBit",        &cSampleBits,                  0,
+                         cSampleBits == 0
+                      || cSampleBits == 8
+                      || cSampleBits == 16
+                      || cSampleBits == 32
+                      || cSampleBits == 64,
                       "Must be either 0, 8, 16, 32 or 64");
-        pAudioCfg->Props.cbSample /= 8;
-
-        QUERY_VAL_RET(8,  "PCMSampleChannels",   &pAudioCfg->Props.cChannels,   0,
-                      pAudioCfg->Props.cChannels <= 16, "Max 16");
+        if (cSampleBits)
+            PDMAudioPropsSetSampleSize(&pAudioCfg->Props, cSampleBits / 8);
+
+        uint8_t cChannels;
+        QUERY_VAL_RET(8,  "PCMSampleChannels",   &cChannels,                    0, cChannels <= 16, "Max 16");
+        if (cChannels)
+            PDMAudioPropsSetChannels(&pAudioCfg->Props, cChannels);
 
         QUERY_VAL_RET(32, "PCMSampleHz",         &pAudioCfg->Props.uHz,         0,
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp	(revision 88269)
@@ -149,5 +149,5 @@
 static snd_pcm_format_t alsaAudioPropsToALSA(PPDMAUDIOPCMPROPS pProps)
 {
-    switch (pProps->cbSample)
+    switch (PDMAudioPropsSampleSize(pProps))
     {
         case 1:
@@ -155,15 +155,17 @@
 
         case 2:
-            return pProps->fSigned ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_U16_LE;
+            if (PDMAudioPropsIsLittleEndian(pProps))
+                return pProps->fSigned ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_U16_LE;
+            return pProps->fSigned ? SND_PCM_FORMAT_S16_BE : SND_PCM_FORMAT_U16_BE;
 
         case 4:
-            return pProps->fSigned ? SND_PCM_FORMAT_S32_LE : SND_PCM_FORMAT_U32_LE;
+            if (PDMAudioPropsIsLittleEndian(pProps))
+                return pProps->fSigned ? SND_PCM_FORMAT_S32_LE : SND_PCM_FORMAT_U32_LE;
+            return pProps->fSigned ? SND_PCM_FORMAT_S32_BE : SND_PCM_FORMAT_U32_BE;
 
         default:
-            break;
-    }
-
-    AssertMsgFailed(("%RU8 bytes not supported\n", pProps->cbSample));
-    return SND_PCM_FORMAT_U8;
+            AssertMsgFailed(("%RU8 bytes not supported\n", PDMAudioPropsSampleSize(pProps)));
+            return SND_PCM_FORMAT_U8;
+    }
 }
 
@@ -173,77 +175,53 @@
  *
  * @returns VBox status code.
- * @param   fmt                 ALSA PCM format to convert.
- * @param   pProps              Where to store the converted PCM properties on success.
- */
-static int alsaALSAToAudioProps(snd_pcm_format_t fmt, PPDMAUDIOPCMPROPS pProps)
-{
+ * @param   pProps      Where to store the converted PCM properties on success.
+ * @param   fmt         ALSA PCM format to convert.
+ * @param   cChannels   Number of channels.
+ * @param   uHz         Frequency.
+ */
+static int alsaALSAToAudioProps(PPDMAUDIOPCMPROPS pProps, snd_pcm_format_t fmt, int cChannels, unsigned uHz)
+{
+    AssertReturn(cChannels > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cChannels < 16, VERR_INVALID_PARAMETER);
     switch (fmt)
     {
         case SND_PCM_FORMAT_S8:
-            pProps->cbSample    = 1;
-            pProps->fSigned     = true;
-            pProps->fSwapEndian = false;
+            PDMAudioPropsInit(pProps, 1 /*8-bit*/,  true /*signed*/, cChannels, uHz);
             break;
 
         case SND_PCM_FORMAT_U8:
-            pProps->cbSample    = 1;
-            pProps->fSigned     = false;
-            pProps->fSwapEndian = false;
+            PDMAudioPropsInit(pProps, 1 /*8-bit*/, false /*signed*/, cChannels, uHz);
             break;
 
         case SND_PCM_FORMAT_S16_LE:
-            pProps->cbSample    = 2;
-            pProps->fSigned     = true;
-            pProps->fSwapEndian = false;
+            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/,  true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
             break;
 
         case SND_PCM_FORMAT_U16_LE:
-            pProps->cbSample    = 2;
-            pProps->fSigned     = false;
-            pProps->fSwapEndian = false;
+            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, false /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
             break;
 
         case SND_PCM_FORMAT_S16_BE:
-            pProps->cbSample    = 2;
-            pProps->fSigned     = true;
-#ifdef RT_LITTLE_ENDIAN
-            pProps->fSwapEndian = true;
-#endif
+            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/,  true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
             break;
 
         case SND_PCM_FORMAT_U16_BE:
-            pProps->cbSample    = 2;
-            pProps->fSigned     = false;
-#ifdef RT_LITTLE_ENDIAN
-            pProps->fSwapEndian = true;
-#endif
+            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, false /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
             break;
 
         case SND_PCM_FORMAT_S32_LE:
-            pProps->cbSample    = 4;
-            pProps->fSigned     = true;
-            pProps->fSwapEndian = false;
+            PDMAudioPropsInitEx(pProps, 4 /*32-bit*/,  true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
             break;
 
         case SND_PCM_FORMAT_U32_LE:
-            pProps->cbSample    = 4;
-            pProps->fSigned     = false;
-            pProps->fSwapEndian = false;
+            PDMAudioPropsInitEx(pProps, 4 /*32-bit*/, false /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
             break;
 
         case SND_PCM_FORMAT_S32_BE:
-            pProps->cbSample    = 4;
-            pProps->fSigned     = true;
-#ifdef RT_LITTLE_ENDIAN
-            pProps->fSwapEndian = true;
-#endif
+            PDMAudioPropsInitEx(pProps, 4 /*32-bit*/,  true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
             break;
 
         case SND_PCM_FORMAT_U32_BE:
-            pProps->cbSample    = 4;
-            pProps->fSigned     = false;
-#ifdef RT_LITTLE_ENDIAN
-            pProps->fSwapEndian = true;
-#endif
+            PDMAudioPropsInitEx(pProps, 4 /*32-bit*/, false /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
             break;
 
@@ -251,10 +229,4 @@
             AssertMsgFailedReturn(("Format %d not supported\n", fmt), VERR_NOT_SUPPORTED);
     }
-
-    AssertReturn(pProps->cbSample > 0,  VERR_NOT_SUPPORTED);
-    AssertReturn(pProps->cChannels > 0, VERR_INVALID_PARAMETER);
-
-    pProps->cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pProps->cbSample, pProps->cChannels);
-
     return VINF_SUCCESS;
 }
@@ -937,6 +909,6 @@
         ALSAAUDIOSTREAMCFG req;
         req.fmt         = alsaAudioPropsToALSA(&pCfgReq->Props);
-        req.freq        = pCfgReq->Props.uHz;
-        req.nchannels   = pCfgReq->Props.cChannels;
+        req.freq        = PDMAudioPropsHz(&pCfgReq->Props);
+        req.nchannels   = PDMAudioPropsChannels(&pCfgReq->Props);
         req.period_size = pCfgReq->Backend.cFramesPeriod;
         req.buffer_size = pCfgReq->Backend.cFramesBufferSize;
@@ -948,8 +920,5 @@
             break;
 
-        pCfgAcq->Props.uHz       = obt.freq;
-        pCfgAcq->Props.cChannels = obt.nchannels;
-
-        rc = alsaALSAToAudioProps(obt.fmt, &pCfgAcq->Props);
+        rc = alsaALSAToAudioProps(&pCfgAcq->Props, obt.fmt, obt.nchannels, obt.freq);
         if (RT_FAILURE(rc))
             break;
@@ -1000,6 +969,6 @@
         ALSAAUDIOSTREAMCFG req;
         req.fmt         = alsaAudioPropsToALSA(&pCfgReq->Props);
-        req.freq        = pCfgReq->Props.uHz;
-        req.nchannels   = pCfgReq->Props.cChannels;
+        req.freq        = PDMAudioPropsHz(&pCfgReq->Props);
+        req.nchannels   = PDMAudioPropsChannels(&pCfgReq->Props);
         req.period_size = PDMAudioPropsMilliToFrames(&pCfgReq->Props, 50 /*ms*/); /** @todo Make this configurable. */
         req.buffer_size = req.period_size * 2; /** @todo Make this configurable. */
@@ -1011,8 +980,5 @@
             break;
 
-        pCfgAcq->Props.uHz       = obt.freq;
-        pCfgAcq->Props.cChannels = obt.nchannels;
-
-        rc = alsaALSAToAudioProps(obt.fmt, &pCfgAcq->Props);
+        rc = alsaALSAToAudioProps(&pCfgAcq->Props, obt.fmt, obt.nchannels, obt.freq);
         if (RT_FAILURE(rc))
             break;
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioCoreAudio.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioCoreAudio.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioCoreAudio.cpp	(revision 88269)
@@ -150,8 +150,8 @@
     char pszSampleRate[32];
     LogRel2(("CoreAudio: %s description:\n", pszDesc));
-    LogRel2(("CoreAudio:\tFormat ID: %RU32 (%c%c%c%c)\n", pASBD->mFormatID,
+    LogRel2(("CoreAudio:  Format ID: %RU32 (%c%c%c%c)\n", pASBD->mFormatID,
              RT_BYTE4(pASBD->mFormatID), RT_BYTE3(pASBD->mFormatID),
              RT_BYTE2(pASBD->mFormatID), RT_BYTE1(pASBD->mFormatID)));
-    LogRel2(("CoreAudio:\tFlags: %RU32", pASBD->mFormatFlags));
+    LogRel2(("CoreAudio:  Flags: %RU32", pASBD->mFormatFlags));
     if (pASBD->mFormatFlags & kAudioFormatFlagIsFloat)
         LogRel2((" Float"));
@@ -171,16 +171,16 @@
         LogRel2((" AllClear"));
     LogRel2(("\n"));
-    snprintf(pszSampleRate, 32, "%.2f", (float)pASBD->mSampleRate); /** @todo r=andy Use RTStrPrint*. */
-    LogRel2(("CoreAudio:\tSampleRate      : %s\n", pszSampleRate));
-    LogRel2(("CoreAudio:\tChannelsPerFrame: %RU32\n", pASBD->mChannelsPerFrame));
-    LogRel2(("CoreAudio:\tFramesPerPacket : %RU32\n", pASBD->mFramesPerPacket));
-    LogRel2(("CoreAudio:\tBitsPerChannel  : %RU32\n", pASBD->mBitsPerChannel));
-    LogRel2(("CoreAudio:\tBytesPerFrame   : %RU32\n", pASBD->mBytesPerFrame));
-    LogRel2(("CoreAudio:\tBytesPerPacket  : %RU32\n", pASBD->mBytesPerPacket));
-}
-
-static void coreAudioPCMPropsToASBD(PDMAUDIOPCMPROPS *pPCMProps, AudioStreamBasicDescription *pASBD)
-{
-    AssertPtrReturnVoid(pPCMProps);
+    LogRel2(("CoreAudio:  SampleRate      : %RU64.%02u Hz\n",
+             (uint64_t)pASBD->mSampleRate, (unsigned)(pASBD->mSampleRate * 100) % 100));
+    LogRel2(("CoreAudio:  ChannelsPerFrame: %RU32\n", pASBD->mChannelsPerFrame));
+    LogRel2(("CoreAudio:  FramesPerPacket : %RU32\n", pASBD->mFramesPerPacket));
+    LogRel2(("CoreAudio:  BitsPerChannel  : %RU32\n", pASBD->mBitsPerChannel));
+    LogRel2(("CoreAudio:  BytesPerFrame   : %RU32\n", pASBD->mBytesPerFrame));
+    LogRel2(("CoreAudio:  BytesPerPacket  : %RU32\n", pASBD->mBytesPerPacket));
+}
+
+static void coreAudioPCMPropsToASBD(PCPDMAUDIOPCMPROPS pProps, AudioStreamBasicDescription *pASBD)
+{
+    AssertPtrReturnVoid(pProps);
     AssertPtrReturnVoid(pASBD);
 
@@ -189,12 +189,14 @@
     pASBD->mFormatID         = kAudioFormatLinearPCM;
     pASBD->mFormatFlags      = kAudioFormatFlagIsPacked;
+    if (pProps->fSigned)
+        pASBD->mFormatFlags |= kAudioFormatFlagIsSignedInteger;
+    if (PDMAudioPropsIsBigEndian(pProps))
+        pASBD->mFormatFlags |= kAudioFormatFlagIsBigEndian;
+    pASBD->mSampleRate       = PDMAudioPropsHz(pProps);
+    pASBD->mChannelsPerFrame = PDMAudioPropsChannels(pProps);
+    pASBD->mBitsPerChannel   = PDMAudioPropsSampleBits(pProps);
+    pASBD->mBytesPerFrame    = PDMAudioPropsFrameSize(pProps);
     pASBD->mFramesPerPacket  = 1; /* For uncompressed audio, set this to 1. */
-    pASBD->mSampleRate       = (Float64)pPCMProps->uHz;
-    pASBD->mChannelsPerFrame = pPCMProps->cChannels;
-    pASBD->mBitsPerChannel   = pPCMProps->cbSample * 8;
-    if (pPCMProps->fSigned)
-        pASBD->mFormatFlags |= kAudioFormatFlagIsSignedInteger;
-    pASBD->mBytesPerFrame    = pASBD->mChannelsPerFrame * (pASBD->mBitsPerChannel / 8);
-    pASBD->mBytesPerPacket   = pASBD->mFramesPerPacket * pASBD->mBytesPerFrame;
+    pASBD->mBytesPerPacket   = PDMAudioPropsFrameSize(pProps) * pASBD->mFramesPerPacket;
 }
 
@@ -205,12 +207,20 @@
     AssertPtrReturn(pCfg,  VERR_INVALID_PARAMETER);
 
-    pCfg->Props.cChannels = pASBD->mChannelsPerFrame;
-    pCfg->Props.uHz       = (uint32_t)pASBD->mSampleRate;
-    AssertMsg(!(pASBD->mBitsPerChannel & 7), ("%u\n", pASBD->mBitsPerChannel));
-    pCfg->Props.cbSample  = pASBD->mBitsPerChannel / 8;
-    pCfg->Props.fSigned   = RT_BOOL(pASBD->mFormatFlags & kAudioFormatFlagIsSignedInteger);
-    pCfg->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
-    /** @todo r=bird: pCfg->Props.fSwapEndian is not initialized here!  */
-
+    AssertLogRelMsgReturn(pASBD->mChannelsPerFrame > 0, VERR_NOT_SUPPORTED);
+    AssertLogRelMsgReturn(pASBD->mChannelsPerFrame < 16, VERR_NOT_SUPPORTED);
+    AssertLogRelMsgReturn(   pASBD->mBitsPerChannel == 8
+                          || pASBD->mBitsPerChannel == 16
+                          || pASBD->mBitsPerChannel == 32,
+                          ("%u\n", pASBD->mBitsPerChannel), VERR_NOT_SUPPORTED);
+    AssertLogRelMsgReturn(!(pASBD->mFormatFlags & (kAudioFormatFlagIsFloat /** @todo more we don't like?*/)),
+                          ("%#x\n", pASBD->mFormatFlags), VERR_NOT_SUPPORTED);
+
+    PDMAudioPropsInitEx(&pCfg->Props,
+                        pASBD->mBitsPerChannel / 8,
+                        RT_BOOL(pASBD->mFormatFlags & kAudioFormatFlagIsSignedInteger),
+                        pASBD->mChannelsPerFrame,
+                        (uint32_t)pASBD->mSampleRate,
+                        RT_BOOL(pASBD->mFormatFlags & kAudioFormatFlagIsBigEndian),
+                        false /*fRaw*/);
     return VINF_SUCCESS;
 }
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp	(revision 88269)
@@ -269,9 +269,9 @@
 
     pFmt->wFormatTag      = WAVE_FORMAT_PCM;
-    pFmt->nChannels       = pCfg->Props.cChannels;
-    pFmt->wBitsPerSample  = pCfg->Props.cbSample * 8;
-    pFmt->nSamplesPerSec  = pCfg->Props.uHz;
-    pFmt->nBlockAlign     = pFmt->nChannels * pFmt->wBitsPerSample / 8;
-    pFmt->nAvgBytesPerSec = pFmt->nSamplesPerSec * pFmt->nBlockAlign;
+    pFmt->nChannels       = PDMAudioPropsChannels(&pCfg->Props);
+    pFmt->wBitsPerSample  = PDMAudioPropsSampleBits(&pCfg->Props);
+    pFmt->nSamplesPerSec  = PDMAudioPropsHz(&pCfg->Props);
+    pFmt->nBlockAlign     = PDMAudioPropsFrameSize(&pCfg->Props);
+    pFmt->nAvgBytesPerSec = PDMAudioPropsFramesToBytes(&pCfg->Props, PDMAudioPropsHz(&pCfg->Props));
     pFmt->cbSize          = 0; /* No extra data specified. */
 
@@ -614,10 +614,12 @@
     AssertPtrReturn(pCfgAcq,   E_POINTER);
 
+/** @todo r=bird: I cannot see any code populating pCfgAcq... */
+
     LogFlowFuncEnter();
 
     Assert(pStreamDS->Out.pDSB == NULL);
 
-    DSLOG(("DSound: Opening playback stream (uHz=%RU32, cChannels=%RU8, cBits=%u, fSigned=%RTbool)\n",
-           pCfgReq->Props.uHz, pCfgReq->Props.cChannels, pCfgReq->Props.cbSample * 8, pCfgReq->Props.fSigned));
+    DSLOG(("DSound: Opening playback stream (uHz=%RU32, cChannels=%RU8, cBits=%u, fSigned=%RTbool)\n", pCfgReq->Props.uHz,
+           PDMAudioPropsChannels(&pCfgReq->Props), PDMAudioPropsSampleBits(&pCfgReq->Props), pCfgReq->Props.fSigned));
 
     WAVEFORMATEX wfx;
@@ -1369,10 +1371,12 @@
     AssertPtrReturn(pCfgAcq,   E_POINTER);
 
+    /** @todo r=bird: I cannot see any code populating pCfgAcq... */
+
     LogFlowFuncEnter();
 
     Assert(pStreamDS->In.pDSCB == NULL);
 
-    DSLOG(("DSound: Opening capturing stream (uHz=%RU32, cChannels=%RU8, cBits=%u, fSigned=%RTbool)\n",
-           pCfgReq->Props.uHz, pCfgReq->Props.cChannels, pCfgReq->Props.cbSample * 8, pCfgReq->Props.fSigned));
+    DSLOG(("DSound: Opening capturing stream (uHz=%RU32, cChannels=%RU8, cBits=%u, fSigned=%RTbool)\n", pCfgReq->Props.uHz,
+           PDMAudioPropsChannels(&pCfgReq->Props), PDMAudioPropsSampleBits(&pCfgReq->Props), pCfgReq->Props.fSigned));
 
     WAVEFORMATEX wfx;
@@ -2067,7 +2071,7 @@
              pStreamDS, pCfgReq, PDMAudioRecSrcGetName(pCfgReq->u.enmSrc)));
 
-    int rc = VINF_SUCCESS;
 
     /* Try to open capture in case the device is already there. */
+    int rc;
     HRESULT hr = directSoundCaptureOpen(pThis, pStreamDS, pCfgReq, pCfgAcq);
     if (SUCCEEDED(hr))
@@ -2363,4 +2367,5 @@
     if (RT_SUCCESS(rc))
     {
+        /** @todo already copied   */
         rc = PDMAudioStrmCfgCopy(&pStreamDS->Cfg, pCfgAcq);
         if (RT_SUCCESS(rc))
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioDebug.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioDebug.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioDebug.cpp	(revision 88269)
@@ -16,5 +16,5 @@
  */
 
-#include <iprt/alloc.h>
+#include <iprt/mem.h>
 #include <iprt/rand.h>
 #include <iprt/uuid.h> /* For PDMIBASE_2_PDMDRV. */
@@ -211,10 +211,10 @@
  */
 static DECLCALLBACK(int) drvHostDebugAudioHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
-                                                        const void *pvBuf, uint32_t uBufSize, uint32_t *puWritten)
-{
-    RT_NOREF(pInterface);
-    PDEBUGAUDIOSTREAM  pStreamDbg = (PDEBUGAUDIOSTREAM)pStream;
-
-    int rc = AudioHlpFileWrite(pStreamDbg->pFile, pvBuf, uBufSize, 0 /* fFlags */);
+                                                        const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
+{
+    PDEBUGAUDIOSTREAM pStreamDbg = (PDEBUGAUDIOSTREAM)pStream;
+    RT_NOREF(pInterface);
+
+    int rc = AudioHlpFileWrite(pStreamDbg->pFile, pvBuf, cbBuf, 0 /* fFlags */);
     if (RT_FAILURE(rc))
     {
@@ -223,7 +223,5 @@
     }
 
-    if (puWritten)
-        *puWritten = uBufSize;
-
+    *pcbWritten = cbBuf;
     return VINF_SUCCESS;
 }
@@ -243,10 +241,11 @@
     AssertPtr(pCfg);
 
-    Assert(uBufSize % pCfg->Props.cbSample == 0);
+    Assert(uBufSize % PDMAudioPropsSampleSize(&pCfg->Props) == 0);
+    size_t const cSamples = uBufSize / PDMAudioPropsSampleSize(&pCfg->Props);
 
     uint16_t *paBuf = (uint16_t *)pvBuf;
 
     /* Generate a simple mono sine wave. */
-    for (size_t i = 0; i < uBufSize / pCfg->Props.cbSample; i++)
+    for (size_t i = 0; i < cSamples; i++)
     {
         paBuf[i] = 32760 * sin((2.f * float(3.1415) * pStreamDbg->In.uFreqHz) / pCfg->Props.uHz * pStreamDbg->In.uSample);
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioOss.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioOss.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioOss.cpp	(revision 88269)
@@ -151,47 +151,30 @@
 
 
-static int ossOSSToAudioProps(int fmt, PPDMAUDIOPCMPROPS pProps)
-{
-    RT_BZERO(pProps, sizeof(PDMAUDIOPCMPROPS));
-
-    /** @todo r=bird: What's the assumption about the incoming pProps?  Code is
-     *        clearly ASSUMING something about how it's initialized, but even so,
-     *        the fSwapEndian isn't correct in a portable way. */
+static int ossOSSToAudioProps(PPDMAUDIOPCMPROPS pProps, int fmt, int cChannels, int uHz)
+{
     switch (fmt)
     {
         case AFMT_S8:
-            pProps->cbSample    = 1;
-            pProps->fSigned     = true;
+            PDMAudioPropsInit(pProps, 1 /*8-bit*/, true /*signed*/, cChannels, uHz);
             break;
 
         case AFMT_U8:
-            pProps->cbSample    = 1;
-            pProps->fSigned     = false;
+            PDMAudioPropsInit(pProps, 1 /*8-bit*/, false /*signed*/, cChannels, uHz);
             break;
 
         case AFMT_S16_LE:
-            pProps->cbSample    = 2;
-            pProps->fSigned     = true;
+            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
             break;
 
         case AFMT_U16_LE:
-            pProps->cbSample    = 2;
-            pProps->fSigned     = false;
-            break;
-
-       case AFMT_S16_BE:
-            pProps->cbSample    = 2;
-            pProps->fSigned     = true;
-#ifdef RT_LITTLE_ENDIAN
-            pProps->fSwapEndian = true;
-#endif
+            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, false /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
+            break;
+
+        case AFMT_S16_BE:
+            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
             break;
 
         case AFMT_U16_BE:
-            pProps->cbSample    = 2;
-            pProps->fSigned     = false;
-#ifdef RT_LITTLE_ENDIAN
-            pProps->fSwapEndian = true;
-#endif
+            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, false /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
             break;
 
@@ -240,5 +223,5 @@
 
         int iFormat;
-        switch (pOSSReq->Props.cbSample)
+        switch (PDMAudioPropsSampleSize(&pOSSReq->Props))
         {
             case 1:
@@ -266,9 +249,9 @@
         }
 
-        int cChannels = pOSSReq->Props.cChannels;
+        int cChannels = PDMAudioPropsChannels(&pOSSReq->Props);
         if (ioctl(fdFile, SNDCTL_DSP_CHANNELS, &cChannels))
         {
             LogRel(("OSS: Failed to set number of audio channels (%RU8): %s (%d)\n",
-                    pOSSReq->Props.cChannels, strerror(errno), errno));
+                    PDMAudioPropsChannels(&pOSSReq->Props), strerror(errno), errno));
             break;
         }
@@ -311,11 +294,7 @@
         }
 
-        rc = ossOSSToAudioProps(iFormat, &pOSSAcq->Props);
+        rc = ossOSSToAudioProps(&pOSSAcq->Props, iFormat, cChannels, freq);
         if (RT_SUCCESS(rc))
         {
-            pOSSAcq->Props.cChannels = cChannels;
-            pOSSAcq->Props.uHz       = freq;
-            pOSSAcq->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pOSSAcq->Props.cbSample, pOSSAcq->Props.cChannels);
-
             pOSSAcq->cFragments      = abinfo.fragstotal;
             pOSSAcq->cbFragmentSize  = abinfo.fragsize;
Index: trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp	(revision 88269)
@@ -217,5 +217,5 @@
 static pa_sample_format_t paAudioPropsToPulse(PPDMAUDIOPCMPROPS pProps)
 {
-    switch (pProps->cbSample)
+    switch (PDMAudioPropsSampleSize(pProps))
     {
         case 1:
@@ -226,5 +226,5 @@
         case 2:
             if (pProps->fSigned)
-                return PA_SAMPLE_S16LE;
+                return PDMAudioPropsIsLittleEndian(pProps) ? PA_SAMPLE_S16LE : PA_SAMPLE_S16BE;
             break;
 
@@ -232,43 +232,36 @@
         case 4:
             if (pProps->fSigned)
-                return PA_SAMPLE_S32LE;
+                return PDMAudioPropsIsLittleEndian(pProps) ? PA_SAMPLE_S32LE : PA_SAMPLE_S32BE;
             break;
 #endif
-
-        default:
-            break;
-    }
-
-    AssertMsgFailed(("%RU8%s not supported\n", pProps->cbSample, pProps->fSigned ? "S" : "U"));
+    }
+
+    AssertMsgFailed(("%RU8%s not supported\n", PDMAudioPropsSampleSize(pProps), pProps->fSigned ? "S" : "U"));
     return PA_SAMPLE_INVALID;
 }
 
 
-static int paPulseToAudioProps(pa_sample_format_t pulsefmt, PPDMAUDIOPCMPROPS pProps)
-{
-    /** @todo r=bird: You are assuming undocumented stuff about
-     *        pProps->fSwapEndian. */
+static int paPulseToAudioProps(PPDMAUDIOPCMPROPS pProps, pa_sample_format_t pulsefmt, uint8_t cChannels, uint32_t uHz)
+{
+    AssertReturn(cChannels > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(cChannels < 16, VERR_INVALID_PARAMETER);
+
     switch (pulsefmt)
     {
         case PA_SAMPLE_U8:
-            pProps->cbSample    = 1;
-            pProps->fSigned     = false;
+            PDMAudioPropsInit(pProps, 1 /*8-bit*/, false /*signed*/, cChannels, uHz);
             break;
 
         case PA_SAMPLE_S16LE:
-            pProps->cbSample    = 2;
-            pProps->fSigned     = true;
+            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
             break;
 
         case PA_SAMPLE_S16BE:
-            pProps->cbSample    = 2;
-            pProps->fSigned     = true;
-            /** @todo Handle Endianess. */
+            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
             break;
 
 #ifdef PA_SAMPLE_S32LE
         case PA_SAMPLE_S32LE:
-            pProps->cbSample    = 4;
-            pProps->fSigned     = true;
+            PDMAudioPropsInitEx(pProps, 4 /*32-bit*/, true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
             break;
 #endif
@@ -276,12 +269,10 @@
 #ifdef PA_SAMPLE_S32BE
         case PA_SAMPLE_S32BE:
-            pProps->cbSample    = 4;
-            pProps->fSigned     = true;
-            /** @todo Handle Endianess. */
+            PDMAudioPropsInitEx(pProps, 4 /*32-bit*/, true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
             break;
 #endif
 
         default:
-            AssertLogRelMsgFailed(("PulseAudio: Format (%ld) not supported\n", pulsefmt));
+            AssertLogRelMsgFailed(("PulseAudio: Format (%d) not supported\n", pulsefmt));
             return VERR_NOT_SUPPORTED;
     }
@@ -789,6 +780,6 @@
 
     pStreamPA->SampleSpec.format   = paAudioPropsToPulse(&pCfgReq->Props);
-    pStreamPA->SampleSpec.rate     = pCfgReq->Props.uHz;
-    pStreamPA->SampleSpec.channels = pCfgReq->Props.cChannels;
+    pStreamPA->SampleSpec.rate     = PDMAudioPropsHz(&pCfgReq->Props);
+    pStreamPA->SampleSpec.channels = PDMAudioPropsChannels(&pCfgReq->Props);
 
     pStreamPA->curLatencyUs        = PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize) * RT_US_1MS;
@@ -816,5 +807,6 @@
         return rc;
 
-    rc = paPulseToAudioProps(pStreamPA->SampleSpec.format, &pCfgAcq->Props);
+    rc = paPulseToAudioProps(&pCfgAcq->Props, pStreamPA->SampleSpec.format,
+                             pStreamPA->SampleSpec.channels, pStreamPA->SampleSpec.rate);
     if (RT_FAILURE(rc))
     {
@@ -822,8 +814,4 @@
         return rc;
     }
-
-    pCfgAcq->Props.uHz       = pStreamPA->SampleSpec.rate;
-    pCfgAcq->Props.cChannels = pStreamPA->SampleSpec.channels;
-    pCfgAcq->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgAcq->Props.cbSample, pCfgAcq->Props.cChannels);
 
     LogFunc(("Acquired: BufAttr tlength=%RU32, maxLength=%RU32, minReq=%RU32\n",
@@ -844,6 +832,6 @@
 {
     pStreamPA->SampleSpec.format   = paAudioPropsToPulse(&pCfgReq->Props);
-    pStreamPA->SampleSpec.rate     = pCfgReq->Props.uHz;
-    pStreamPA->SampleSpec.channels = pCfgReq->Props.cChannels;
+    pStreamPA->SampleSpec.rate     = PDMAudioPropsHz(&pCfgReq->Props);
+    pStreamPA->SampleSpec.channels = PDMAudioPropsChannels(&pCfgReq->Props);
 
     pStreamPA->BufAttr.fragsize    = PDMAudioPropsFramesToBytes(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod);
@@ -860,5 +848,6 @@
         return rc;
 
-    rc = paPulseToAudioProps(pStreamPA->SampleSpec.format, &pCfgAcq->Props);
+    rc = paPulseToAudioProps(&pCfgAcq->Props, pStreamPA->SampleSpec.format,
+                             pStreamPA->SampleSpec.channels, pStreamPA->SampleSpec.rate);
     if (RT_FAILURE(rc))
     {
@@ -869,7 +858,4 @@
     pStreamPA->pDrv       = pThis;
     pStreamPA->pu8PeekBuf = NULL;
-
-    pCfgAcq->Props.uHz         = pStreamPA->SampleSpec.rate;
-    pCfgAcq->Props.cChannels   = pStreamPA->SampleSpec.channels;
 
     pCfgAcq->Backend.cFramesPeriod       = PDMAUDIOSTREAMCFG_B2F(pCfgAcq, pStreamPA->BufAttr.fragsize);
Index: trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp	(revision 88259)
+++ trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp	(revision 88269)
@@ -38,26 +38,23 @@
     RTTestSub(hTest, "Basics");
 
-    const PDMAUDIOPCMPROPS Cfg441StereoS16 = PDMAUDIOPCMPROPS_INITIALIZOR(
+    const PDMAUDIOPCMPROPS Cfg441StereoS16 = PDMAUDIOPCMPROPS_INITIALIZER(
         /* a_cb: */             2,
         /* a_fSigned: */        true,
         /* a_cChannels: */      2,
         /* a_uHz: */            44100,
-        /* a_cShift: */         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* cb */, 2 /* cChannels */),
         /* a_fSwapEndian: */    false
     );
-    const PDMAUDIOPCMPROPS Cfg441StereoU16 = PDMAUDIOPCMPROPS_INITIALIZOR(
+    const PDMAUDIOPCMPROPS Cfg441StereoU16 = PDMAUDIOPCMPROPS_INITIALIZER(
         /* a_cb: */             2,
         /* a_fSigned: */        false,
         /* a_cChannels: */      2,
         /* a_uHz: */            44100,
-        /* a_cShift: */         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* cb */, 2 /* cChannels */),
         /* a_fSwapEndian: */    false
     );
-    const PDMAUDIOPCMPROPS Cfg441StereoU32 = PDMAUDIOPCMPROPS_INITIALIZOR(
+    const PDMAUDIOPCMPROPS Cfg441StereoU32 = PDMAUDIOPCMPROPS_INITIALIZER(
         /* a_cb: */             4,
         /* a_fSigned: */        false,
         /* a_cChannels: */      2,
         /* a_uHz: */            44100,
-        /* a_cShift: */         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(4 /* cb */, 2 /* cChannels */),
         /* a_fSwapEndian: */    false
     );
@@ -191,10 +188,9 @@
 
     /* 44100Hz, 2 Channels, S16 */
-    PDMAUDIOPCMPROPS config = PDMAUDIOPCMPROPS_INITIALIZOR(
+    PDMAUDIOPCMPROPS config = PDMAUDIOPCMPROPS_INITIALIZER(
         2,                                                                  /* Bytes */
         true,                                                               /* Signed */
         2,                                                                  /* Channels */
         44100,                                                              /* Hz */
-        PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 2 /* Channels */), /* Shift */
         false                                                               /* Swap Endian */
     );
@@ -312,10 +308,9 @@
 
     /* 44100Hz, 2 Channels, S16 */
-    PDMAUDIOPCMPROPS cfg_p = PDMAUDIOPCMPROPS_INITIALIZOR(
+    PDMAUDIOPCMPROPS cfg_p = PDMAUDIOPCMPROPS_INITIALIZER(
         2,                                                                  /* Bytes */
         true,                                                               /* Signed */
         2,                                                                  /* Channels */
         44100,                                                              /* Hz */
-        PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 2 /* Channels */), /* Shift */
         false                                                               /* Swap Endian */
     );
@@ -327,10 +322,9 @@
 
     /* 22050Hz, 2 Channels, S16 */
-    PDMAUDIOPCMPROPS cfg_c1 = PDMAUDIOPCMPROPS_INITIALIZOR(/* Upmixing to parent */
+    PDMAUDIOPCMPROPS cfg_c1 = PDMAUDIOPCMPROPS_INITIALIZER(/* Upmixing to parent */
         2,                                                                  /* Bytes */
         true,                                                               /* Signed */
         2,                                                                  /* Channels */
         22050,                                                              /* Hz */
-        PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 2 /* Channels */), /* Shift */
         false                                                               /* Swap Endian */
     );
@@ -346,10 +340,9 @@
 
     /* 48000Hz, 2 Channels, S16 */
-    PDMAUDIOPCMPROPS cfg_c2 = PDMAUDIOPCMPROPS_INITIALIZOR(/* Downmixing to parent */
+    PDMAUDIOPCMPROPS cfg_c2 = PDMAUDIOPCMPROPS_INITIALIZER(/* Downmixing to parent */
         2,                                                                  /* Bytes */
         true,                                                               /* Signed */
         2,                                                                  /* Channels */
         48000,                                                              /* Hz */
-        PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 2 /* Channels */), /* Shift */
         false                                                               /* Swap Endian */
     );
@@ -460,10 +453,9 @@
 
     /* 44100Hz, 1 Channel, U8 */
-    PDMAUDIOPCMPROPS cfg_p = PDMAUDIOPCMPROPS_INITIALIZOR(
+    PDMAUDIOPCMPROPS cfg_p = PDMAUDIOPCMPROPS_INITIALIZER(
         1,                                                                  /* Bytes */
         false,                                                              /* Signed */
         1,                                                                  /* Channels */
         44100,                                                              /* Hz */
-        PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(1 /* Bytes */, 1 /* Channels */), /* Shift */
         false                                                               /* Swap Endian */
     );
@@ -483,10 +475,9 @@
 
     /* 22050Hz, 1 Channel, U8 */
-    PDMAUDIOPCMPROPS cfg_c = PDMAUDIOPCMPROPS_INITIALIZOR( /* Upmixing to parent */
+    PDMAUDIOPCMPROPS cfg_c = PDMAUDIOPCMPROPS_INITIALIZER( /* Upmixing to parent */
         1,                                                                  /* Bytes */
         false,                                                              /* Signed */
         1,                                                                  /* Channels */
         22050,                                                              /* Hz */
-        PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(1 /* Bytes */, 1 /* Channels */), /* Shift */
         false                                                               /* Swap Endian */
     );
@@ -514,5 +505,5 @@
 
     /**** 8-bit unsigned samples ****/
-    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 8-bit\n", cfg_c.uHz, cfg_c.cChannels);
+    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 8-bit\n", cfg_c.uHz, PDMAudioPropsChannels(&cfg_c));
     RTTESTI_CHECK_RC_OK(AudioMixBufWriteCirc(&child, &aFrames8U, sizeof(aFrames8U), &cFramesWritten));
     RTTESTI_CHECK_MSG(cFramesWritten == cFramesChild, ("Child: Expected %RU32 written frames, got %RU32\n", cFramesChild, cFramesWritten));
@@ -565,10 +556,9 @@
 
     /* 44100Hz, 1 Channel, S16 */
-    PDMAUDIOPCMPROPS cfg_p = PDMAUDIOPCMPROPS_INITIALIZOR(
+    PDMAUDIOPCMPROPS cfg_p = PDMAUDIOPCMPROPS_INITIALIZER(
         2,                                                                  /* Bytes */
         true,                                                               /* Signed */
         1,                                                                  /* Channels */
         44100,                                                              /* Hz */
-        PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 1 /* Channels */), /* Shift */
         false                                                               /* Swap Endian */
     );
@@ -580,10 +570,9 @@
 
     /* 22050Hz, 1 Channel, S16 */
-    PDMAUDIOPCMPROPS cfg_c = PDMAUDIOPCMPROPS_INITIALIZOR( /* Upmixing to parent */
+    PDMAUDIOPCMPROPS cfg_c = PDMAUDIOPCMPROPS_INITIALIZER( /* Upmixing to parent */
         2,                                                                  /* Bytes */
         true,                                                               /* Signed */
         1,                                                                  /* Channels */
         22050,                                                              /* Hz */
-        PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 1 /* Channels */), /* Shift */
         false                                                               /* Swap Endian */
     );
@@ -611,5 +600,5 @@
 
     /**** 16-bit signed samples ****/
-    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 16-bit\n", cfg_c.uHz, cfg_c.cChannels);
+    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 16-bit\n", cfg_c.uHz, PDMAudioPropsChannels(&cfg_c));
     RTTESTI_CHECK_RC_OK(AudioMixBufWriteCirc(&child, &aFrames16S, sizeof(aFrames16S), &cFramesWritten));
     RTTESTI_CHECK_MSG(cFramesWritten == cFramesChild, ("Child: Expected %RU32 written frames, got %RU32\n", cFramesChild, cFramesWritten));
@@ -662,10 +651,9 @@
     /* Same for parent/child. */
     /* 44100Hz, 2 Channels, S16 */
-    PDMAUDIOPCMPROPS cfg = PDMAUDIOPCMPROPS_INITIALIZOR(
+    PDMAUDIOPCMPROPS cfg = PDMAUDIOPCMPROPS_INITIALIZER(
         2,                                                                  /* Bytes */
         true,                                                               /* Signed */
         2,                                                                  /* Channels */
         44100,                                                              /* Hz */
-        PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 2 /* Channels */), /* Shift */
         false                                                               /* Swap Endian */
     );
@@ -699,5 +687,5 @@
 
     /**** Volume control test ****/
-    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Volume control test %uHz %uch \n", cfg.uHz, cfg.cChannels);
+    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Volume control test %uHz %uch \n", cfg.uHz, PDMAudioPropsChannels(&cfg));
 
     /* 1) Full volume/0dB attenuation (255). */
