VirtualBox

Changeset 89378 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 30, 2021 2:14:34 AM (4 years ago)
Author:
vboxsync
Message:

AudioMixBuffer: Changed the internal sample type from int64_t to int32_t and made the internal buffer handling capable of an arbitrary channel number (well 1 thru 12 (PDMAUDIO_MAX_CHANNELS)). That said, we don't have decoders, encoders or resamplers for channel counts other than 1 and 2 yet. bugref:9890

Location:
trunk/src/VBox/Devices/Audio
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp

    r89377 r89378  
    221221
    222222/**
    223  * Merges @a i64Src into the value stored at @a pi64Dst.
    224  *
    225  * @param   pi64Dst     The value to merge @a i64Src into.
    226  * @param   i64Src      The new value to add.
    227  */
    228 DECL_FORCE_INLINE(void) audioMixBufBlendSample(int64_t *pi64Dst, int64_t i64Src)
    229 {
    230     if (i64Src)
    231     {
    232         int64_t const i64Dst = *pi64Dst;
    233         if (!i64Dst)
    234             *pi64Dst = i64Src;
     223 * Merges @a i32Src into the value stored at @a pi32Dst.
     224 *
     225 * @param   pi32Dst     The value to merge @a i32Src into.
     226 * @param   i32Src      The new value to add.
     227 */
     228DECL_FORCE_INLINE(void) audioMixBufBlendSample(int32_t *pi32Dst, int32_t i32Src)
     229{
     230    if (i32Src)
     231    {
     232        int64_t const i32Dst = *pi32Dst;
     233        if (!i32Dst)
     234            *pi32Dst = i32Src;
    235235        else
    236             *pi64Dst = (i64Dst + i64Src) / 2;
     236            *pi32Dst = (int32_t)(((int64_t)i32Dst + i32Src) / 2);
    237237    }
    238238}
     
    244244 * This is used for stereo -> mono.
    245245 */
    246 DECL_FORCE_INLINE(int64_t) audioMixBufBlendSampleRet(int64_t i64Sample1, int64_t i64Sample2)
    247 {
    248     if (!i64Sample1)
    249         return i64Sample2;
    250     if (!i64Sample2)
    251         return i64Sample1;
    252     return (i64Sample1 + i64Sample2) / 2;
     246DECL_FORCE_INLINE(int32_t) audioMixBufBlendSampleRet(int32_t i32Sample1, int32_t i32Sample2)
     247{
     248    if (!i32Sample1)
     249        return i32Sample2;
     250    if (!i32Sample2)
     251        return i32Sample1;
     252    return (int32_t)(((int64_t)i32Sample1 + i32Sample2) / 2);
    253253}
    254254
     
    261261 *  - otherwise sum and divide by two.
    262262 *
    263  * @param   pi64Dst     The destination stream buffer (input and output).
    264  * @param   pi64Src     The source stream buffer.
     263 * @param   pi32Dst     The destination stream buffer (input and output).
     264 * @param   pi32Src     The source stream buffer.
    265265 * @param   cFrames     Number of frames to process.
    266266 * @param   cChannels   Number of channels.
    267267 */
    268 static void audioMixBufBlendBuffer(int64_t *pi64Dst, int64_t const *pi64Src, uint32_t cFrames, uint8_t cChannels)
     268static void audioMixBufBlendBuffer(int32_t *pi32Dst, int32_t const *pi32Src, uint32_t cFrames, uint8_t cChannels)
    269269{
    270270    switch (cChannels)
     
    273273            while (cFrames-- > 0)
    274274            {
    275                 audioMixBufBlendSample(&pi64Dst[0], pi64Src[0]);
    276                 audioMixBufBlendSample(&pi64Dst[1], pi64Src[1]);
    277                 pi64Dst += 2;
    278                 pi64Src += 2;
     275                audioMixBufBlendSample(&pi32Dst[0], pi32Src[0]);
     276                audioMixBufBlendSample(&pi32Dst[1], pi32Src[1]);
     277                pi32Dst += 2;
     278                pi32Src += 2;
    279279            }
    280280            break;
     
    286286            while (cFrames-- > 0)
    287287            {
    288                 audioMixBufBlendSample(pi64Dst, pi64Src[0]);
    289                 pi64Dst++;
    290                 pi64Src++;
     288                audioMixBufBlendSample(pi32Dst, pi32Src[0]);
     289                pi32Dst++;
     290                pi32Src++;
    291291            }
    292292            break;
     
    312312#define AUDMIXBUF_CONVERT(a_Name, a_Type, _aMin, _aMax, _aSigned, _aShift) \
    313313    /* Clips a specific output value to a single sample value. */ \
    314     DECLINLINE(int64_t) audioMixBufClipFrom##a_Name(a_Type aVal) \
     314    DECLINLINE(int32_t) audioMixBufSampleFrom##a_Name(a_Type aVal) \
    315315    { \
    316316        /* left shifting of signed values is not defined, therefore the intermediate uint64_t cast */ \
    317317        if (_aSigned) \
    318             return (int64_t) (((uint64_t) ((int64_t) aVal                     )) << (32 - _aShift)); \
    319         return     (int64_t) (((uint64_t) ((int64_t) aVal - ((_aMax >> 1) + 1))) << (32 - _aShift)); \
     318            return (int32_t) (((uint32_t) ((int32_t) aVal                     )) << (32 - _aShift)); \
     319        return     (int32_t) (((uint32_t) ((int32_t) aVal - ((_aMax >> 1) + 1))) << (32 - _aShift)); \
    320320    } \
    321321    \
    322322    /* Clips a single sample value to a specific output value. */ \
    323     DECLINLINE(a_Type) audioMixBufClipTo##a_Name(int64_t iVal) \
     323    DECLINLINE(a_Type) audioMixBufSampleTo##a_Name(int32_t iVal) \
    324324    { \
    325         /*if (iVal >= 0x7fffffff) return _aMax; if (iVal < -INT64_C(0x80000000)) return _aMin;*/ \
    326         if (!(((uint64_t)iVal + UINT64_C(0x80000000)) & UINT64_C(0xffffffff00000000))) \
    327         { \
    328             if (_aSigned) \
    329                 return (a_Type)  (iVal >> (32 - _aShift)); \
    330             return     (a_Type) ((iVal >> (32 - _aShift)) + ((_aMax >> 1) + 1)); \
    331         } \
    332         AssertMsgFailed(("%RI64 (%#RX64)\n", iVal, iVal)); /* shouldn't be possible with current buffer operations */ \
    333         return iVal >= 0 ? _aMax : _aMin; \
     325        if (_aSigned) \
     326            return (a_Type)  (iVal >> (32 - _aShift)); \
     327        return     (a_Type) ((iVal >> (32 - _aShift)) + ((_aMax >> 1) + 1)); \
    334328    } \
    335329    \
     
    337331    \
    338332    /* 2ch -> 2ch */ \
    339     static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo2Ch,a_Name)(void *pvDst, int64_t const *pi64Src, uint32_t cFrames, \
     333    static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo2Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \
    340334                                                                          PAUDIOMIXBUFPEEKSTATE pState) \
    341335    { \
     
    344338        while (cFrames-- > 0) \
    345339        { \
    346             pDst[0] = audioMixBufClipTo##a_Name(pi64Src[0]); \
    347             pDst[1] = audioMixBufClipTo##a_Name(pi64Src[1]); \
    348             AUDMIXBUF_MACRO_LOG(("%p: %RI64 / %RI64 => %RI64 / %RI64\n", \
    349                                  &pi64Src[0], pi64Src[0], pi64Src[1], (int64_t)pDst[0], (int64_t)pDst[1])); \
     340            pDst[0] = audioMixBufSampleTo##a_Name(pi32Src[0]); \
     341            pDst[1] = audioMixBufSampleTo##a_Name(pi32Src[1]); \
     342            AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n", \
     343                                 &pi32Src[0], pi32Src[0], pi32Src[1], (int32_t)pDst[0], (int32_t)pDst[1])); \
    350344            pDst    += 2; \
    351             pi64Src += 2; \
     345            pi32Src += 2; \
    352346        } \
    353347    } \
    354348    \
    355349    /* 2ch -> 1ch */ \
    356     static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo1Ch,a_Name)(void *pvDst, int64_t const *pi64Src, uint32_t cFrames, \
     350    static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo1Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \
    357351                                                                          PAUDIOMIXBUFPEEKSTATE pState) \
    358352    { \
     
    361355        while (cFrames-- > 0) \
    362356        { \
    363              pDst[0] = audioMixBufClipTo##a_Name(audioMixBufBlendSampleRet(pi64Src[0], pi64Src[1])); \
     357             pDst[0] = audioMixBufSampleTo##a_Name(audioMixBufBlendSampleRet(pi32Src[0], pi32Src[1])); \
    364358             pDst    += 1; \
    365              pi64Src += 2; \
     359             pi32Src += 2; \
    366360        } \
    367361    } \
    368362    \
    369363    /* 1ch -> 2ch */ \
    370     static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo2Ch,a_Name)(void *pvDst, int64_t const *pi64Src, uint32_t cFrames, \
     364    static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo2Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \
    371365                                                                          PAUDIOMIXBUFPEEKSTATE pState) \
    372366    { \
     
    375369        while (cFrames-- > 0) \
    376370        { \
    377             pDst[0] = pDst[1] = audioMixBufClipTo##a_Name(pi64Src[0]); \
     371            pDst[0] = pDst[1] = audioMixBufSampleTo##a_Name(pi32Src[0]); \
    378372            pDst    += 2; \
    379             pi64Src += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */ \
     373            pi32Src += 1; \
    380374        } \
    381375    } \
    382376    /* 1ch -> 1ch */ \
    383     static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo1Ch,a_Name)(void *pvDst, int64_t const *pi64Src, uint32_t cFrames, \
     377    static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo1Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \
    384378                                                                          PAUDIOMIXBUFPEEKSTATE pState) \
    385379    { \
     
    388382        while (cFrames-- > 0) \
    389383        { \
    390              pDst[0] = audioMixBufClipTo##a_Name(pi64Src[0]); \
     384             pDst[0] = audioMixBufSampleTo##a_Name(pi32Src[0]); \
    391385             pDst    += 1; \
    392              pi64Src += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */ \
     386             pi32Src += 1; \
    393387        } \
    394388    } \
     
    397391    \
    398392    /* 2ch -> 2ch */ \
    399     static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo2Ch,a_Name)(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, \
     393    static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo2Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \
    400394                                                                          PAUDIOMIXBUFWRITESTATE pState) \
    401395    { \
     
    404398        while (cFrames-- > 0) \
    405399        { \
    406             pi64Dst[0] = audioMixBufClipFrom##a_Name(pSrc[0]); \
    407             pi64Dst[1] = audioMixBufClipFrom##a_Name(pSrc[1]); \
    408             AUDMIXBUF_MACRO_LOG(("%p: %RI64 / %RI64 => %RI64 / %RI64\n", \
    409                                  &pSrc[0], (int64_t)pSrc[0], (int64_t)pSrc[1], pi64Dst[0], pi64Dst[1])); \
    410             pi64Dst  += 2; \
     400            pi32Dst[0] = audioMixBufSampleFrom##a_Name(pSrc[0]); \
     401            pi32Dst[1] = audioMixBufSampleFrom##a_Name(pSrc[1]); \
     402            AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n", \
     403                                 &pSrc[0], (int32_t)pSrc[0], (int32_t)pSrc[1], pi32Dst[0], pi32Dst[1])); \
     404            pi32Dst  += 2; \
    411405            pSrc     += 2; \
    412406        } \
     
    414408    \
    415409    /* 2ch -> 1ch */ \
    416     static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo1Ch,a_Name)(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, \
     410    static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo1Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \
    417411                                                                          PAUDIOMIXBUFWRITESTATE pState) \
    418412    { \
     
    421415        while (cFrames-- > 0) \
    422416        { \
    423             pi64Dst[0] = audioMixBufBlendSampleRet(audioMixBufClipFrom##a_Name(pSrc[0]), audioMixBufClipFrom##a_Name(pSrc[1])); \
    424             pi64Dst  += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */ \
     417            pi32Dst[0] = audioMixBufBlendSampleRet(audioMixBufSampleFrom##a_Name(pSrc[0]), audioMixBufSampleFrom##a_Name(pSrc[1])); \
     418            pi32Dst  += 1; \
    425419            pSrc     += 2; \
    426420        } \
     
    428422    \
    429423    /* 1ch -> 2ch */ \
    430     static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo2Ch,a_Name)(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, \
     424    static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo2Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \
    431425                                                                          PAUDIOMIXBUFWRITESTATE pState) \
    432426    { \
     
    435429        while (cFrames-- > 0) \
    436430        { \
    437             pi64Dst[1] = pi64Dst[0] = audioMixBufClipFrom##a_Name(pSrc[0]); \
    438             pi64Dst  += 2; \
     431            pi32Dst[1] = pi32Dst[0] = audioMixBufSampleFrom##a_Name(pSrc[0]); \
     432            pi32Dst  += 2; \
    439433            pSrc     += 1; \
    440434        } \
     
    442436    \
    443437    /* 1ch -> 1ch */ \
    444     static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo1Ch,a_Name)(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, \
     438    static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo1Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \
    445439                                                                          PAUDIOMIXBUFWRITESTATE pState) \
    446440    { \
     
    449443        while (cFrames-- > 0) \
    450444        { \
    451             pi64Dst[0] = audioMixBufClipFrom##a_Name(pSrc[0]); \
    452             pi64Dst  += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */ \
     445            pi32Dst[0] = audioMixBufSampleFrom##a_Name(pSrc[0]); \
     446            pi32Dst  += 1; \
    453447            pSrc     += 1; \
    454448        } \
     
    458452    \
    459453    /* 2ch -> 2ch */ \
    460     static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo2Ch,a_Name,Blend)(int64_t *pi64Dst, void const *pvSrc, \
     454    static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo2Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \
    461455                                                                                 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
    462456    { \
     
    465459        while (cFrames-- > 0) \
    466460        { \
    467             audioMixBufBlendSample(&pi64Dst[0], audioMixBufClipFrom##a_Name(pSrc[0])); \
    468             audioMixBufBlendSample(&pi64Dst[1], audioMixBufClipFrom##a_Name(pSrc[1])); \
    469             AUDMIXBUF_MACRO_LOG(("%p: %RI64 / %RI64 => %RI64 / %RI64\n", \
    470                                  &pSrc[0], (int64_t)pSrc[0], (int64_t)pSrc[1], pi64Dst[0], pi64Dst[1])); \
    471             pi64Dst  += 2; \
     461            audioMixBufBlendSample(&pi32Dst[0], audioMixBufSampleFrom##a_Name(pSrc[0])); \
     462            audioMixBufBlendSample(&pi32Dst[1], audioMixBufSampleFrom##a_Name(pSrc[1])); \
     463            AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n", \
     464                                 &pSrc[0], (int32_t)pSrc[0], (int32_t)pSrc[1], pi32Dst[0], pi32Dst[1])); \
     465            pi32Dst  += 2; \
    472466            pSrc     += 2; \
    473467        } \
     
    475469    \
    476470    /* 2ch -> 1ch */ \
    477     static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo1Ch,a_Name,Blend)(int64_t *pi64Dst, void const *pvSrc, \
     471    static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo1Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \
    478472                                                                                 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
    479473    { \
     
    482476        while (cFrames-- > 0) \
    483477        { \
    484             audioMixBufBlendSample(&pi64Dst[0], audioMixBufBlendSampleRet(audioMixBufClipFrom##a_Name(pSrc[0]), \
    485                                                                           audioMixBufClipFrom##a_Name(pSrc[1]))); \
    486             pi64Dst  += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */ \
     478            audioMixBufBlendSample(&pi32Dst[0], audioMixBufBlendSampleRet(audioMixBufSampleFrom##a_Name(pSrc[0]), \
     479                                                                          audioMixBufSampleFrom##a_Name(pSrc[1]))); \
     480            pi32Dst  += 1; \
    487481            pSrc     += 2; \
    488482        } \
     
    490484    \
    491485    /* 1ch -> 2ch */ \
    492     static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo2Ch,a_Name,Blend)(int64_t *pi64Dst, void const *pvSrc, \
     486    static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo2Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \
    493487                                                                                 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
    494488    { \
     
    497491        while (cFrames-- > 0) \
    498492        { \
    499             int64_t const i64Src = audioMixBufClipFrom##a_Name(pSrc[0]); \
    500             audioMixBufBlendSample(&pi64Dst[0], i64Src); \
    501             audioMixBufBlendSample(&pi64Dst[1], i64Src); \
    502             pi64Dst  += 2; \
     493            int32_t const i32Src = audioMixBufSampleFrom##a_Name(pSrc[0]); \
     494            audioMixBufBlendSample(&pi32Dst[0], i32Src); \
     495            audioMixBufBlendSample(&pi32Dst[1], i32Src); \
     496            pi32Dst  += 2; \
    503497            pSrc     += 1; \
    504498        } \
     
    506500    \
    507501    /* 1ch -> 1ch */ \
    508     static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo1Ch,a_Name,Blend)(int64_t *pi64Dst, void const *pvSrc, \
     502    static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo1Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \
    509503                                                                                 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
    510504    { \
     
    513507        while (cFrames-- > 0) \
    514508        { \
    515             audioMixBufBlendSample(&pi64Dst[0], audioMixBufClipFrom##a_Name(pSrc[0])); \
    516             pi64Dst  += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */ \
     509            audioMixBufBlendSample(&pi32Dst[0], audioMixBufSampleFrom##a_Name(pSrc[0])); \
     510            pi32Dst  += 1; \
    517511            pSrc     += 1; \
    518512        } \
     
    520514
    521515
    522 /* audioMixBufConvXXXS8: 8 bit, signed. */
     516/* audioMixBufConvXXXS8: 8-bit, signed. */
    523517AUDMIXBUF_CONVERT(S8 /* Name */,  int8_t,   INT8_MIN  /* Min */, INT8_MAX   /* Max */, true  /* fSigned */, 8  /* cShift */)
    524 /* audioMixBufConvXXXU8: 8 bit, unsigned. */
     518/* audioMixBufConvXXXU8: 8-bit, unsigned. */
    525519AUDMIXBUF_CONVERT(U8 /* Name */,  uint8_t,  0         /* Min */, UINT8_MAX  /* Max */, false /* fSigned */, 8  /* cShift */)
    526 /* audioMixBufConvXXXS16: 16 bit, signed. */
     520/* audioMixBufConvXXXS16: 16-bit, signed. */
    527521AUDMIXBUF_CONVERT(S16 /* Name */, int16_t,  INT16_MIN /* Min */, INT16_MAX  /* Max */, true  /* fSigned */, 16 /* cShift */)
    528 /* audioMixBufConvXXXU16: 16 bit, unsigned. */
     522/* audioMixBufConvXXXU16: 16-bit, unsigned. */
    529523AUDMIXBUF_CONVERT(U16 /* Name */, uint16_t, 0         /* Min */, UINT16_MAX /* Max */, false /* fSigned */, 16 /* cShift */)
    530 /* audioMixBufConvXXXS32: 32 bit, signed. */
     524/* audioMixBufConvXXXS32: 32-bit, signed. */
    531525AUDMIXBUF_CONVERT(S32 /* Name */, int32_t,  INT32_MIN /* Min */, INT32_MAX  /* Max */, true  /* fSigned */, 32 /* cShift */)
    532 /* audioMixBufConvXXXU32: 32 bit, unsigned. */
     526/* audioMixBufConvXXXU32: 32-bit, unsigned. */
    533527AUDMIXBUF_CONVERT(U32 /* Name */, uint32_t, 0         /* Min */, UINT32_MAX /* Max */, false /* fSigned */, 32 /* cShift */)
     528/* audioMixBufConvXXXRaw: 32-bit stored as 64-bit, signed. */
     529AUDMIXBUF_CONVERT(Raw /* Name */, int64_t,  INT32_MIN /* Min */, INT32_MAX  /* Max */, true  /* fSigned */, 32 /* cShift */)
    534530
    535531#undef AUDMIXBUF_CONVERT
    536 
    537 /*
    538  * Manually coded signed 64-bit conversion.
    539  */
    540 
    541 /* Encoders for peek: */
    542 
    543 static DECLCALLBACK(void)
    544 audioMixBufEncode2ChTo2ChRaw(void *pvDst, int64_t const *pi64Src, uint32_t cFrames, PAUDIOMIXBUFPEEKSTATE pState)
    545 {
    546     RT_NOREF_PV(pState);
    547     memcpy(pvDst, pi64Src, sizeof(int64_t) * 2 * cFrames);
    548 }
    549 
    550 static DECLCALLBACK(void)
    551 audioMixBufEncode2ChTo1ChRaw(void *pvDst, int64_t const *pi64Src, uint32_t cFrames, PAUDIOMIXBUFPEEKSTATE pState)
    552 {
    553     RT_NOREF_PV(pState);
    554     int64_t *pi64Dst = (int64_t *)pvDst;
    555     while (cFrames-- > 0)
    556     {
    557         *pi64Dst = (pi64Src[0] + pi64Src[1]) / 2;
    558         pi64Dst += 1;
    559         pi64Src += 2;
    560     }
    561 }
    562 
    563 static DECLCALLBACK(void)
    564 audioMixBufEncode1ChTo2ChRaw(void *pvDst, int64_t const *pi64Src, uint32_t cFrames, PAUDIOMIXBUFPEEKSTATE pState)
    565 {
    566     RT_NOREF_PV(pState);
    567     int64_t *pi64Dst = (int64_t *)pvDst;
    568     while (cFrames-- > 0)
    569     {
    570         pi64Dst[0] = pi64Dst[1] = *pi64Src;
    571         pi64Dst += 2;
    572         pi64Src += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */
    573     }
    574 }
    575 
    576 static DECLCALLBACK(void)
    577 audioMixBufEncode1ChTo1ChRaw(void *pvDst, int64_t const *pi64Src, uint32_t cFrames, PAUDIOMIXBUFPEEKSTATE pState)
    578 {
    579     RT_NOREF_PV(pState);
    580     /** @todo memcpy(pvDst, pi64Src, sizeof(int64_t) * 1 * cFrames); when we do
    581      *        multi channel mixbuf support. */
    582     int64_t *pi64Dst = (int64_t *)pvDst;
    583     while (cFrames-- > 0)
    584     {
    585         *pi64Dst = *pi64Src;
    586         pi64Dst += 1;
    587         pi64Src += 2;
    588     }
    589 }
    590 
    591 
    592 /* Decoders for write: */
    593 
    594 static DECLCALLBACK(void)
    595 audioMixBufDecode2ChTo2ChRaw(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
    596 {
    597     RT_NOREF_PV(pState);
    598     memcpy(pi64Dst, pvSrc, sizeof(int64_t) * 2 * cFrames);
    599 }
    600 
    601 static DECLCALLBACK(void)
    602 audioMixBufDecode2ChTo1ChRaw(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
    603 {
    604     RT_NOREF_PV(pState);
    605     int64_t const *pi64Src = (int64_t const *)pvSrc;
    606     while (cFrames-- > 0)
    607     {
    608         *pi64Dst = (pi64Src[0] + pi64Src[1]) / 2;
    609         pi64Dst += 2;  /** @todo when we do multi channel mixbuf support, this can change to 1 */
    610         pi64Src += 2;
    611     }
    612 }
    613 
    614 static DECLCALLBACK(void)
    615 audioMixBufDecode1ChTo2ChRaw(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
    616 {
    617     RT_NOREF_PV(pState);
    618     int64_t const *pi64Src = (int64_t const *)pvSrc;
    619     while (cFrames-- > 0)
    620     {
    621         pi64Dst[0] = pi64Dst[1] = *pi64Src;
    622         pi64Dst += 2;
    623         pi64Src += 1;
    624     }
    625 }
    626 
    627 static DECLCALLBACK(void)
    628 audioMixBufDecode1ChTo1ChRaw(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
    629 {
    630     RT_NOREF_PV(pState);
    631     /** @todo memcpy(pi64Dst, pvSrc, sizeof(int64_t) * 1 * cFrames); when we do
    632      *        multi channel mixbuf support. */
    633     int64_t const *pi64Src = (int64_t const *)pvSrc;
    634     while (cFrames-- > 0)
    635     {
    636         *pi64Dst = *pi64Src;
    637         pi64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */
    638         pi64Src += 1;
    639     }
    640 }
    641 
    642 
    643 /* Decoders for blending: */
    644 
    645 static DECLCALLBACK(void)
    646 audioMixBufDecode2ChTo2ChRawBlend(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
    647 {
    648     RT_NOREF_PV(pState);
    649     audioMixBufBlendBuffer(pi64Dst, (int64_t const *)pvSrc, cFrames, 2);
    650 }
    651 
    652 static DECLCALLBACK(void)
    653 audioMixBufDecode2ChTo1ChRawBlend(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
    654 {
    655     RT_NOREF_PV(pState);
    656     int64_t const *pi64Src = (int64_t const *)pvSrc;
    657     while (cFrames-- > 0)
    658     {
    659         audioMixBufBlendSample(pi64Dst, audioMixBufBlendSampleRet(pi64Src[0], pi64Src[1]));
    660         pi64Dst += 2;  /** @todo when we do multi channel mixbuf support, this can change to 1 */
    661         pi64Src += 2;
    662     }
    663 }
    664 
    665 static DECLCALLBACK(void)
    666 audioMixBufDecode1ChTo2ChRawBlend(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
    667 {
    668     RT_NOREF_PV(pState);
    669     int64_t const *pi64Src = (int64_t const *)pvSrc;
    670     while (cFrames-- > 0)
    671     {
    672         int64_t const i64Src = *pi64Src;
    673         audioMixBufBlendSample(&pi64Dst[0], i64Src);
    674         audioMixBufBlendSample(&pi64Dst[1], i64Src);
    675         pi64Dst += 2;
    676         pi64Src += 1;
    677     }
    678 }
    679 
    680 static DECLCALLBACK(void)
    681 audioMixBufDecode1ChTo1ChRawBlend(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
    682 {
    683     RT_NOREF_PV(pState);
    684     /** @todo memcpy(pi64Dst, pvSrc, sizeof(int64_t) * 1 * cFrames); when we do
    685      *        multi channel mixbuf support. */
    686     int64_t const *pi64Src = (int64_t const *)pvSrc;
    687     while (cFrames-- > 0)
    688     {
    689         audioMixBufBlendSample(&pi64Dst[0], *pi64Src);
    690         pi64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */
    691         pi64Src += 1;
    692     }
    693 }
    694 
    695532#undef AUDMIXBUF_MACRO_LOG
     533
    696534
    697535/*
     
    699537 */
    700538/** @todo Separate down- and up-sampling, borrow filter code from RDP. */
    701 #define COPY_LAST_FRAME_1CH(a_pi64Dst, a_pi64Src, a_cChannels) do { \
    702         (a_pi64Dst)[0] = (a_pi64Src)[0]; \
     539#define COPY_LAST_FRAME_1CH(a_pi32Dst, a_pi32Src, a_cChannels) do { \
     540        (a_pi32Dst)[0] = (a_pi32Src)[0]; \
    703541    } while (0)
    704 #define COPY_LAST_FRAME_2CH(a_pi64Dst, a_pi64Src, a_cChannels) do { \
    705         (a_pi64Dst)[0] = (a_pi64Src)[0]; \
    706         (a_pi64Dst)[1] = (a_pi64Src)[1]; \
     542#define COPY_LAST_FRAME_2CH(a_pi32Dst, a_pi32Src, a_cChannels) do { \
     543        (a_pi32Dst)[0] = (a_pi32Src)[0]; \
     544        (a_pi32Dst)[1] = (a_pi32Src)[1]; \
    707545    } while (0)
    708546
    709 #define INTERPOLATE_ONE(a_pi64Dst, a_pi64Src, a_pi64Last, a_i64FactorCur, a_i64FactorLast, a_iCh) \
    710         (a_pi64Dst)[a_iCh] = ((a_pi64Last)[a_iCh] * a_i64FactorLast + (a_pi64Src)[a_iCh] * a_i64FactorCur) >> 32
    711 #define INTERPOLATE_1CH(a_pi64Dst, a_pi64Src, a_pi64Last, a_i64FactorCur, a_i64FactorLast, a_cChannels) do { \
    712         INTERPOLATE_ONE(a_pi64Dst, a_pi64Src, a_pi64Last, a_i64FactorCur, a_i64FactorLast, 0); \
     547#define INTERPOLATE_ONE(a_pi32Dst, a_pi32Src, a_pi32Last, a_i64FactorCur, a_i64FactorLast, a_iCh) \
     548        (a_pi32Dst)[a_iCh] = ((a_pi32Last)[a_iCh] * a_i64FactorLast + (a_pi32Src)[a_iCh] * a_i64FactorCur) >> 32
     549#define INTERPOLATE_1CH(a_pi32Dst, a_pi32Src, a_pi32Last, a_i64FactorCur, a_i64FactorLast, a_cChannels) do { \
     550        INTERPOLATE_ONE(a_pi32Dst, a_pi32Src, a_pi32Last, a_i64FactorCur, a_i64FactorLast, 0); \
    713551    } while (0)
    714 #define INTERPOLATE_2CH(a_pi64Dst, a_pi64Src, a_pi64Last, a_i64FactorCur, a_i64FactorLast, a_cChannels) do { \
    715         INTERPOLATE_ONE(a_pi64Dst, a_pi64Src, a_pi64Last, a_i64FactorCur, a_i64FactorLast, 0); \
    716         INTERPOLATE_ONE(a_pi64Dst, a_pi64Src, a_pi64Last, a_i64FactorCur, a_i64FactorLast, 1); \
     552#define INTERPOLATE_2CH(a_pi32Dst, a_pi32Src, a_pi32Last, a_i64FactorCur, a_i64FactorLast, a_cChannels) do { \
     553        INTERPOLATE_ONE(a_pi32Dst, a_pi32Src, a_pi32Last, a_i64FactorCur, a_i64FactorLast, 0); \
     554        INTERPOLATE_ONE(a_pi32Dst, a_pi32Src, a_pi32Last, a_i64FactorCur, a_i64FactorLast, 1); \
    717555    } while (0)
    718556
     
    720558    /** @returns Number of destination frames written. */ \
    721559    static DECLCALLBACK(uint32_t) \
    722     audioMixBufResample##a_cChannels##Ch##a_Suffix(int64_t *pi64Dst, uint32_t cDstFrames, \
    723                                                    int64_t const *pi64Src, uint32_t cSrcFrames, uint32_t *pcSrcFramesRead, \
     560    audioMixBufResample##a_cChannels##Ch##a_Suffix(int32_t *pi32Dst, uint32_t cDstFrames, \
     561                                                   int32_t const *pi32Src, uint32_t cSrcFrames, uint32_t *pcSrcFramesRead, \
    724562                                                   PAUDIOSTREAMRATE pRate) \
    725563    { \
    726564        Log5(("Src: %RU32 L %RU32;  Dst: %RU32 L%RU32; uDstInc=%#RX64\n", \
    727565              pRate->offSrc, cSrcFrames, RT_HI_U32(pRate->offDst), cDstFrames, pRate->uDstInc)); \
    728         int64_t * const       pi64DstStart = pi64Dst; \
    729         int64_t const * const pi64SrcStart = pi64Src; \
     566        int32_t * const       pi32DstStart = pi32Dst; \
     567        int32_t const * const pi32SrcStart = pi32Src; \
    730568        \
    731         int64_t ai64LastFrame[a_cChannels]; \
    732         COPY_LAST_FRAME_##a_cChannels##CH(ai64LastFrame, pRate->SrcLast.ai64Samples, a_cChannels); \
     569        int32_t ai32LastFrame[a_cChannels]; \
     570        COPY_LAST_FRAME_##a_cChannels##CH(ai32LastFrame, pRate->SrcLast.ai32Samples, a_cChannels); \
    733571        \
    734572        while (cDstFrames > 0 && cSrcFrames > 0) \
     
    741579                    pRate->offSrc += (uint32_t)cSrcNeeded; \
    742580                    cSrcFrames    -= (uint32_t)cSrcNeeded; \
    743                     pi64Src       += (uint32_t)cSrcNeeded * a_cChannels; \
    744                     COPY_LAST_FRAME_##a_cChannels##CH(ai64LastFrame, &pi64Src[-a_cChannels], a_cChannels); \
     581                    pi32Src       += (uint32_t)cSrcNeeded * a_cChannels; \
     582                    COPY_LAST_FRAME_##a_cChannels##CH(ai32LastFrame, &pi32Src[-a_cChannels], a_cChannels); \
    745583                } \
    746584                else \
    747585                { \
    748                     pi64Src       += cSrcFrames * a_cChannels; \
     586                    pi32Src       += cSrcFrames * a_cChannels; \
    749587                    pRate->offSrc += cSrcFrames; \
    750                     COPY_LAST_FRAME_##a_cChannels##CH(pRate->SrcLast.ai64Samples, &pi64Src[-a_cChannels], a_cChannels); \
    751                     *pcSrcFramesRead = (pi64Src - pi64SrcStart) / a_cChannels; \
    752                     return (pi64Dst - pi64DstStart) / a_cChannels; \
     588                    COPY_LAST_FRAME_##a_cChannels##CH(pRate->SrcLast.ai32Samples, &pi32Src[-a_cChannels], a_cChannels); \
     589                    *pcSrcFramesRead = (pi32Src - pi32SrcStart) / a_cChannels; \
     590                    return (pi32Dst - pi32DstStart) / a_cChannels; \
    753591                } \
    754592            } \
     
    757595            int64_t const offFactorCur  = pRate->offDst & UINT32_MAX; \
    758596            int64_t const offFactorLast = (int64_t)_4G - offFactorCur; \
    759             INTERPOLATE_##a_cChannels##CH(pi64Dst, pi64Src, ai64LastFrame, offFactorCur, offFactorLast, a_cChannels); \
     597            INTERPOLATE_##a_cChannels##CH(pi32Dst, pi32Src, ai32LastFrame, offFactorCur, offFactorLast, a_cChannels); \
    760598            \
    761599            /* Advance. */ \
    762600            pRate->offDst += pRate->uDstInc; \
    763             pi64Dst       += a_cChannels; \
     601            pi32Dst       += a_cChannels; \
    764602            cDstFrames    -= 1; \
    765603        } \
    766604        \
    767         COPY_LAST_FRAME_##a_cChannels##CH(pRate->SrcLast.ai64Samples, ai64LastFrame, a_cChannels); \
    768         *pcSrcFramesRead = (pi64Src - pi64SrcStart) / a_cChannels; \
    769         return (pi64Dst - pi64DstStart) / a_cChannels; \
     605        COPY_LAST_FRAME_##a_cChannels##CH(pRate->SrcLast.ai32Samples, ai32LastFrame, a_cChannels); \
     606        *pcSrcFramesRead = (pi32Src - pi32SrcStart) / a_cChannels; \
     607        return (pi32Dst - pi32DstStart) / a_cChannels; \
    770608    }
    771609
     
    783621    pRate->offDst = 0;
    784622    pRate->offSrc = 0;
    785     for (uintptr_t i = 0; i < RT_ELEMENTS(pRate->SrcLast.ai64Samples); i++)
    786         pRate->SrcLast.ai64Samples[0] = 0;
     623    for (uintptr_t i = 0; i < RT_ELEMENTS(pRate->SrcLast.ai32Samples); i++)
     624        pRate->SrcLast.ai32Samples[0] = 0;
    787625}
    788626
     
    866704    Assert(PDMAudioPropsAreValid(pProps));
    867705
    868     pMixBuf->uMagic  = AUDIOMIXBUF_MAGIC;
    869 
    870     pMixBuf->pFrames = NULL;
    871     pMixBuf->cFrames = 0;
    872 
    873     pMixBuf->offRead  = 0;
    874     pMixBuf->offWrite = 0;
    875     pMixBuf->cUsed    = 0;
    876 
    877     /* Set initial volume to max. */
    878     pMixBuf->Volume.fMuted = false;
    879     pMixBuf->Volume.uLeft  = AUDIOMIXBUF_VOL_0DB;
    880     pMixBuf->Volume.uRight = AUDIOMIXBUF_VOL_0DB;
    881 
    882     pMixBuf->Props       = *pProps;
    883 
    884     pMixBuf->pszName = RTStrDup(pszName);
    885     if (pMixBuf->pszName)
    886     {
    887         pMixBuf->pFrames = (PPDMAUDIOFRAME)RTMemAllocZ(cFrames * sizeof(PDMAUDIOFRAME));
    888         if (pMixBuf->pFrames)
     706    /*
     707     * Initialize all members, setting the volume to max (0dB).
     708     */
     709    pMixBuf->cFrames        = 0;
     710    pMixBuf->pi32Samples    = NULL;
     711    pMixBuf->cChannels      = 0;
     712    pMixBuf->cbFrame        = 0;
     713    pMixBuf->offRead        = 0;
     714    pMixBuf->offWrite       = 0;
     715    pMixBuf->cUsed          = 0;
     716    pMixBuf->Props          = *pProps;
     717    pMixBuf->Volume.fMuted  = false;
     718    pMixBuf->Volume.fAllMax = true;
     719    for (uintptr_t i = 0; i < RT_ELEMENTS(pMixBuf->Volume.auChannels); i++)
     720        pMixBuf->Volume.auChannels[i] = AUDIOMIXBUF_VOL_0DB;
     721
     722    int rc;
     723    uint8_t const cChannels = PDMAudioPropsChannels(pProps);
     724    if (cChannels >= 1 && cChannels <= PDMAUDIO_MAX_CHANNELS)
     725    {
     726        pMixBuf->pszName = RTStrDup(pszName);
     727        if (pMixBuf->pszName)
    889728        {
    890             pMixBuf->cFrames = cFrames;
     729            pMixBuf->pi32Samples = (int32_t *)RTMemAllocZ(cFrames * cChannels * sizeof(pMixBuf->pi32Samples[0]));
     730            if (pMixBuf->pi32Samples)
     731            {
     732                pMixBuf->cFrames    = cFrames;
     733                pMixBuf->cChannels  = cChannels;
     734                pMixBuf->cbFrame    = cChannels * sizeof(pMixBuf->pi32Samples[0]);
     735                pMixBuf->uMagic     = AUDIOMIXBUF_MAGIC;
    891736#ifdef AUDMIXBUF_LOG_ENABLED
    892             char szTmp[PDMAUDIOPROPSTOSTRING_MAX];
    893             AUDMIXBUF_LOG(("%s: %s - cFrames=%#x (%d)\n",
    894                            pMixBuf->pszName, PDMAudioPropsToString(pProps, szTmp, sizeof(szTmp)), cFrames, cFrames));
     737                char szTmp[PDMAUDIOPROPSTOSTRING_MAX];
     738                AUDMIXBUF_LOG(("%s: %s - cFrames=%#x (%d)\n",
     739                               pMixBuf->pszName, PDMAudioPropsToString(pProps, szTmp, sizeof(szTmp)), cFrames, cFrames));
    895740#endif
    896             return VINF_SUCCESS;
     741                return VINF_SUCCESS;
     742            }
     743            RTStrFree(pMixBuf->pszName);
     744            pMixBuf->pszName = NULL;
     745            rc = VERR_NO_MEMORY;
    897746        }
    898         RTStrFree(pMixBuf->pszName);
    899         pMixBuf->pszName = NULL;
     747        else
     748            rc = VERR_NO_STR_MEMORY;
     749    }
     750    else
     751    {
     752        LogRelMaxFunc(64, ("cChannels=%d pszName=%s\n", cChannels, pszName));
     753        rc = VERR_OUT_OF_RANGE;
    900754    }
    901755    pMixBuf->uMagic = AUDIOMIXBUF_MAGIC_DEAD;
    902     return VERR_NO_MEMORY;
     756    return rc;
    903757}
    904758
     
    919773    {
    920774        Assert(!pMixBuf->pszName);
    921         Assert(!pMixBuf->pFrames);
     775        Assert(!pMixBuf->pi32Samples);
    922776        Assert(!pMixBuf->cFrames);
    923777        return;
     
    935789    }
    936790
    937     if (pMixBuf->pFrames)
     791    if (pMixBuf->pi32Samples)
    938792    {
    939793        Assert(pMixBuf->cFrames);
    940 
    941         RTMemFree(pMixBuf->pFrames);
    942         pMixBuf->pFrames = NULL;
    943     }
    944 
    945     pMixBuf->cFrames = 0;
     794        RTMemFree(pMixBuf->pi32Samples);
     795        pMixBuf->pi32Samples = NULL;
     796    }
     797
     798    pMixBuf->cFrames   = 0;
     799    pMixBuf->cChannels = 0;
    946800}
    947801
     
    14091263    {
    14101264        /* Rate conversion into temporary buffer. */
    1411         int64_t  ai64DstRate[1024];
     1265        int32_t  ai32DstRate[1024];
    14121266        uint32_t cSrcFrames    = RT_MIN(pMixBuf->cFrames - offSrcFrame, cMaxSrcFrames);
    1413         uint32_t cMaxDstFrames = RT_MIN(RT_ELEMENTS(ai64DstRate) / pState->cDstChannels, cbDst / pState->cbDstFrame);
    1414         uint32_t const cDstFrames = pState->Rate.pfnResample(ai64DstRate, cMaxDstFrames,
    1415                                                              &pMixBuf->pFrames[offSrcFrame].i64LSample, cSrcFrames, &cSrcFrames,
    1416                                                              &pState->Rate);
     1267        uint32_t cMaxDstFrames = RT_MIN(RT_ELEMENTS(ai32DstRate) / pState->cDstChannels, cbDst / pState->cbDstFrame);
     1268        uint32_t const cDstFrames = pState->Rate.pfnResample(ai32DstRate, cMaxDstFrames,
     1269                                                             &pMixBuf->pi32Samples[offSrcFrame * pMixBuf->cChannels],
     1270                                                             cSrcFrames, &cSrcFrames, &pState->Rate);
    14171271        *pcSrcFramesPeeked += cSrcFrames;
    14181272        cMaxSrcFrames      -= cSrcFrames;
     
    14211275        /* Encode the converted frames. */
    14221276        uint32_t const cbDstEncoded = cDstFrames * pState->cbDstFrame;
    1423         pState->pfnEncode(pvDst, ai64DstRate, cDstFrames, pState);
     1277        pState->pfnEncode(pvDst, ai32DstRate, cDstFrames, pState);
    14241278        *pcbDstPeeked      += cbDstEncoded;
    14251279        cbDst              -= cbDstEncoded;
     
    14841338        /* First chunk. */
    14851339        uint32_t const cSrcFrames1 = RT_MIN(pMixBuf->cFrames - offSrcFrame, cMaxSrcFrames);
    1486         pState->pfnEncode(pvDst, &pMixBuf->pFrames[offSrcFrame].i64LSample, cSrcFrames1, pState);
     1340        pState->pfnEncode(pvDst, &pMixBuf->pi32Samples[offSrcFrame * pMixBuf->cChannels], cSrcFrames1, pState);
    14871341
    14881342        /* Another chunk from the start of the mixing buffer? */
    14891343        if (cMaxSrcFrames > cSrcFrames1)
    14901344            pState->pfnEncode((uint8_t *)pvDst + cSrcFrames1 * pState->cbDstFrame,
    1491                               &pMixBuf->pFrames[0].i64LSample, cMaxSrcFrames - cSrcFrames1, pState);
     1345                              &pMixBuf->pi32Samples[0], cMaxSrcFrames - cSrcFrames1, pState);
    14921346    }
    14931347    else
     
    15071361    {
    15081362        /* Decode into temporary buffer. */
    1509         int64_t  ai64SrcDecoded[1024];
    1510         uint32_t cFramesDecoded = RT_MIN(RT_ELEMENTS(ai64SrcDecoded) / pState->cSrcChannels, cbSrcBuf / pState->cbSrcFrame);
    1511         pState->pfnDecode(ai64SrcDecoded, pvSrcBuf, cFramesDecoded, pState);
     1363        int32_t  ai32SrcDecoded[1024];
     1364        uint32_t cFramesDecoded = RT_MIN(RT_ELEMENTS(ai32SrcDecoded) / pState->cSrcChannels, cbSrcBuf / pState->cbSrcFrame);
     1365        pState->pfnDecode(ai32SrcDecoded, pvSrcBuf, cFramesDecoded, pState);
    15121366        cbSrcBuf -= cFramesDecoded * pState->cbSrcFrame;
    15131367        pvSrcBuf  = (uint8_t const *)pvSrcBuf + cFramesDecoded * pState->cbSrcFrame;
     
    15191373            uint32_t cDstMaxFrames    = RT_MIN(pMixBuf->cFrames - offDstFrame, cMaxDstFrames);
    15201374            uint32_t cSrcFrames       = cFramesDecoded - iFrameDecoded;
    1521             uint32_t const cDstFrames = pState->Rate.pfnResample(&pMixBuf->pFrames[offDstFrame].i64LSample, cDstMaxFrames,
    1522                                                                  &ai64SrcDecoded[iFrameDecoded * pState->cSrcChannels],
     1375            uint32_t const cDstFrames = pState->Rate.pfnResample(&pMixBuf->pi32Samples[offDstFrame * pMixBuf->cChannels],
     1376                                                                 cDstMaxFrames,
     1377                                                                 &ai32SrcDecoded[iFrameDecoded * pState->cSrcChannels],
    15231378                                                                 cSrcFrames, &cSrcFrames, &pState->Rate);
    15241379
     
    15871442        /* First chunk. */
    15881443        uint32_t const cDstFrames1 = RT_MIN(pMixBuf->cFrames - offDstFrame, cMaxDstFrames);
    1589         pState->pfnDecode(&pMixBuf->pFrames[offDstFrame].i64LSample, pvSrcBuf, cDstFrames1, pState);
     1444        pState->pfnDecode(&pMixBuf->pi32Samples[offDstFrame * pMixBuf->cChannels], pvSrcBuf, cDstFrames1, pState);
    15901445
    15911446        /* Another chunk from the start of the mixing buffer? */
    15921447        if (cMaxDstFrames > cDstFrames1)
    1593             pState->pfnDecode(&pMixBuf->pFrames[0].i64LSample, (uint8_t *)pvSrcBuf + cDstFrames1 * pState->cbSrcFrame,
     1448            pState->pfnDecode(&pMixBuf->pi32Samples[0], (uint8_t *)pvSrcBuf + cDstFrames1 * pState->cbSrcFrame,
    15941449                              cMaxDstFrames - cDstFrames1, pState);
    15951450    }
     
    16101465    {
    16111466        /* Decode into temporary buffer. */
    1612         int64_t  ai64SrcDecoded[1024];
    1613         uint32_t cFramesDecoded = RT_MIN(RT_ELEMENTS(ai64SrcDecoded) / pState->cSrcChannels, cbSrcBuf / pState->cbSrcFrame);
    1614         pState->pfnDecode(ai64SrcDecoded, pvSrcBuf, cFramesDecoded, pState);
     1467        int32_t  ai32SrcDecoded[1024];
     1468        uint32_t cFramesDecoded = RT_MIN(RT_ELEMENTS(ai32SrcDecoded) / pState->cSrcChannels, cbSrcBuf / pState->cbSrcFrame);
     1469        pState->pfnDecode(ai32SrcDecoded, pvSrcBuf, cFramesDecoded, pState);
    16151470        cbSrcBuf -= cFramesDecoded * pState->cbSrcFrame;
    16161471        pvSrcBuf  = (uint8_t const *)pvSrcBuf + cFramesDecoded * pState->cbSrcFrame;
     
    16201475        while (iFrameDecoded < cFramesDecoded)
    16211476        {
    1622             int64_t  ai64SrcRate[1024];
    1623             uint32_t cDstMaxFrames    = RT_MIN(RT_ELEMENTS(ai64SrcRate), cMaxDstFrames);
     1477            int32_t  ai32SrcRate[1024];
     1478            uint32_t cDstMaxFrames    = RT_MIN(RT_ELEMENTS(ai32SrcRate), cMaxDstFrames);
    16241479            uint32_t cSrcFrames       = cFramesDecoded - iFrameDecoded;
    1625             uint32_t const cDstFrames = pState->Rate.pfnResample(&ai64SrcRate[0], cDstMaxFrames,
    1626                                                                  &ai64SrcDecoded[iFrameDecoded * pState->cSrcChannels],
     1480            uint32_t const cDstFrames = pState->Rate.pfnResample(&ai32SrcRate[0], cDstMaxFrames,
     1481                                                                 &ai32SrcDecoded[iFrameDecoded * pState->cSrcChannels],
    16271482                                                                 cSrcFrames, &cSrcFrames, &pState->Rate);
    16281483
    16291484            /* First chunk.*/
    16301485            uint32_t const cDstFrames1 = RT_MIN(pMixBuf->cFrames - offDstFrame, cDstFrames);
    1631             audioMixBufBlendBuffer(&pMixBuf->pFrames[offDstFrame].i64LSample, ai64SrcRate, cDstFrames1, pState->cSrcChannels);
     1486            audioMixBufBlendBuffer(&pMixBuf->pi32Samples[offDstFrame * pMixBuf->cChannels],
     1487                                   ai32SrcRate, cDstFrames1, pState->cSrcChannels);
    16321488
    16331489            /* Another chunk from the start of the mixing buffer? */
    16341490            if (cDstFrames > cDstFrames1)
    1635                 audioMixBufBlendBuffer(&pMixBuf->pFrames[0].i64LSample, &ai64SrcRate[cDstFrames1 * pState->cSrcChannels],
     1491                audioMixBufBlendBuffer(&pMixBuf->pi32Samples[0], &ai32SrcRate[cDstFrames1 * pState->cSrcChannels],
    16361492                                       cDstFrames - cDstFrames1, pState->cSrcChannels);
    16371493
     
    16871543        /* First chunk. */
    16881544        uint32_t const cDstFrames1 = RT_MIN(pMixBuf->cFrames - offDstFrame, cMaxDstFrames);
    1689         pState->pfnDecodeBlend(&pMixBuf->pFrames[offDstFrame].i64LSample, pvSrcBuf, cDstFrames1, pState);
     1545        pState->pfnDecodeBlend(&pMixBuf->pi32Samples[offDstFrame * pMixBuf->cChannels], pvSrcBuf, cDstFrames1, pState);
    16901546
    16911547        /* Another chunk from the start of the mixing buffer? */
    16921548        if (cMaxDstFrames > cDstFrames1)
    1693             pState->pfnDecodeBlend(&pMixBuf->pFrames[0].i64LSample, (uint8_t *)pvSrcBuf + cDstFrames1 * pState->cbSrcFrame,
     1549            pState->pfnDecodeBlend(&pMixBuf->pi32Samples[0], (uint8_t *)pvSrcBuf + cDstFrames1 * pState->cbSrcFrame,
    16941550                                   cMaxDstFrames - cDstFrames1, pState);
    16951551    }
     
    17421598     */
    17431599    uint32_t const cFramesChunk1 = RT_MIN(pMixBuf->cFrames - offFrame, cFrames);
    1744     RT_BZERO(&pMixBuf->pFrames[offFrame], cFramesChunk1 * sizeof(pMixBuf->pFrames[0]));
     1600    RT_BZERO(&pMixBuf->pi32Samples[offFrame * pMixBuf->cChannels], cFramesChunk1 * pMixBuf->cbFrame);
    17451601
    17461602    /*
     
    17511607        cFrames -= cFramesChunk1;
    17521608        AssertStmt(cFrames <= pMixBuf->cFrames, cFrames = pMixBuf->cFrames);
    1753         RT_BZERO(&pMixBuf->pFrames[0], cFrames * sizeof(pMixBuf->pFrames[0]));
     1609        RT_BZERO(&pMixBuf->pi32Samples[0], cFrames * pMixBuf->cbFrame);
    17541610    }
    17551611
     
    18091665static void audioMixAdjustVolumeWorker(PAUDIOMIXBUF pMixBuf, uint32_t off, uint32_t cFrames)
    18101666{
    1811     PPDMAUDIOFRAME const    paFrames = pMixBuf->pFrames;
    1812     uint32_t const          uLeft    = pMixBuf->Volume.uLeft;
    1813     uint32_t const          uRight   = pMixBuf->Volume.uRight;
    1814     while (cFrames-- > 0)
    1815     {
    1816         paFrames[off].i64LSample = ASMMult2xS32RetS64(paFrames[off].i64LSample, uLeft)  >> AUDIOMIXBUF_VOL_SHIFT;
    1817         paFrames[off].i64RSample = ASMMult2xS32RetS64(paFrames[off].i64RSample, uRight) >> AUDIOMIXBUF_VOL_SHIFT;
    1818         off++;
     1667    int32_t       *pi32Samples = &pMixBuf->pi32Samples[off * pMixBuf->cChannels];
     1668    switch (pMixBuf->cChannels)
     1669    {
     1670        case 1:
     1671        {
     1672            uint32_t const uFactorCh0 = pMixBuf->Volume.auChannels[0];
     1673            while (cFrames-- > 0)
     1674            {
     1675                *pi32Samples = (int32_t)(ASMMult2xS32RetS64(*pi32Samples, uFactorCh0) >> AUDIOMIXBUF_VOL_SHIFT);
     1676                pi32Samples++;
     1677            }
     1678            break;
     1679        }
     1680
     1681        case 2:
     1682        {
     1683            uint32_t const uFactorCh0 = pMixBuf->Volume.auChannels[0];
     1684            uint32_t const uFactorCh1 = pMixBuf->Volume.auChannels[1];
     1685            while (cFrames-- > 0)
     1686            {
     1687                pi32Samples[0] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[0], uFactorCh0) >> AUDIOMIXBUF_VOL_SHIFT);
     1688                pi32Samples[1] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[1], uFactorCh1) >> AUDIOMIXBUF_VOL_SHIFT);
     1689                pi32Samples += 2;
     1690            }
     1691            break;
     1692        }
     1693
     1694        case 3:
     1695        {
     1696            uint32_t const uFactorCh0 = pMixBuf->Volume.auChannels[0];
     1697            uint32_t const uFactorCh1 = pMixBuf->Volume.auChannels[1];
     1698            uint32_t const uFactorCh2 = pMixBuf->Volume.auChannels[2];
     1699            while (cFrames-- > 0)
     1700            {
     1701                pi32Samples[0] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[0], uFactorCh0) >> AUDIOMIXBUF_VOL_SHIFT);
     1702                pi32Samples[1] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[1], uFactorCh1) >> AUDIOMIXBUF_VOL_SHIFT);
     1703                pi32Samples[2] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[2], uFactorCh2) >> AUDIOMIXBUF_VOL_SHIFT);
     1704                pi32Samples += 3;
     1705            }
     1706            break;
     1707        }
     1708
     1709        case 4:
     1710        {
     1711            uint32_t const uFactorCh0 = pMixBuf->Volume.auChannels[0];
     1712            uint32_t const uFactorCh1 = pMixBuf->Volume.auChannels[1];
     1713            uint32_t const uFactorCh2 = pMixBuf->Volume.auChannels[2];
     1714            uint32_t const uFactorCh3 = pMixBuf->Volume.auChannels[3];
     1715            while (cFrames-- > 0)
     1716            {
     1717                pi32Samples[0] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[0], uFactorCh0) >> AUDIOMIXBUF_VOL_SHIFT);
     1718                pi32Samples[1] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[1], uFactorCh1) >> AUDIOMIXBUF_VOL_SHIFT);
     1719                pi32Samples[2] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[2], uFactorCh2) >> AUDIOMIXBUF_VOL_SHIFT);
     1720                pi32Samples[3] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[3], uFactorCh3) >> AUDIOMIXBUF_VOL_SHIFT);
     1721                pi32Samples += 4;
     1722            }
     1723            break;
     1724        }
     1725
     1726        case 5:
     1727        {
     1728            uint32_t const uFactorCh0 = pMixBuf->Volume.auChannels[0];
     1729            uint32_t const uFactorCh1 = pMixBuf->Volume.auChannels[1];
     1730            uint32_t const uFactorCh2 = pMixBuf->Volume.auChannels[2];
     1731            uint32_t const uFactorCh3 = pMixBuf->Volume.auChannels[3];
     1732            uint32_t const uFactorCh4 = pMixBuf->Volume.auChannels[4];
     1733            while (cFrames-- > 0)
     1734            {
     1735                pi32Samples[0] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[0], uFactorCh0) >> AUDIOMIXBUF_VOL_SHIFT);
     1736                pi32Samples[1] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[1], uFactorCh1) >> AUDIOMIXBUF_VOL_SHIFT);
     1737                pi32Samples[2] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[2], uFactorCh2) >> AUDIOMIXBUF_VOL_SHIFT);
     1738                pi32Samples[3] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[3], uFactorCh3) >> AUDIOMIXBUF_VOL_SHIFT);
     1739                pi32Samples[4] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[4], uFactorCh4) >> AUDIOMIXBUF_VOL_SHIFT);
     1740                pi32Samples += 5;
     1741            }
     1742            break;
     1743        }
     1744
     1745        case 6:
     1746        {
     1747            uint32_t const uFactorCh0 = pMixBuf->Volume.auChannels[0];
     1748            uint32_t const uFactorCh1 = pMixBuf->Volume.auChannels[1];
     1749            uint32_t const uFactorCh2 = pMixBuf->Volume.auChannels[2];
     1750            uint32_t const uFactorCh3 = pMixBuf->Volume.auChannels[3];
     1751            uint32_t const uFactorCh4 = pMixBuf->Volume.auChannels[4];
     1752            uint32_t const uFactorCh5 = pMixBuf->Volume.auChannels[5];
     1753            while (cFrames-- > 0)
     1754            {
     1755                pi32Samples[0] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[0], uFactorCh0) >> AUDIOMIXBUF_VOL_SHIFT);
     1756                pi32Samples[1] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[1], uFactorCh1) >> AUDIOMIXBUF_VOL_SHIFT);
     1757                pi32Samples[2] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[2], uFactorCh2) >> AUDIOMIXBUF_VOL_SHIFT);
     1758                pi32Samples[3] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[3], uFactorCh3) >> AUDIOMIXBUF_VOL_SHIFT);
     1759                pi32Samples[4] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[4], uFactorCh4) >> AUDIOMIXBUF_VOL_SHIFT);
     1760                pi32Samples[5] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[5], uFactorCh5) >> AUDIOMIXBUF_VOL_SHIFT);
     1761                pi32Samples += 6;
     1762            }
     1763            break;
     1764        }
     1765
     1766        default:
     1767            while (cFrames-- > 0)
     1768                for (uint32_t iCh = 0; iCh < pMixBuf->cChannels; iCh++, pi32Samples++)
     1769                    *pi32Samples = ASMMult2xS32RetS64(*pi32Samples, pMixBuf->Volume.auChannels[iCh]) >> AUDIOMIXBUF_VOL_SHIFT;
     1770            break;
    18191771    }
    18201772}
     
    18411793        /* first chunk */
    18421794        uint32_t const cFramesChunk1 = RT_MIN(pMixBuf->cFrames - offFirst, cFrames);
    1843         RT_BZERO(&pMixBuf->pFrames[offFirst], sizeof(pMixBuf->pFrames[0]) * cFramesChunk1);
     1795        RT_BZERO(&pMixBuf->pi32Samples[offFirst * pMixBuf->cChannels], pMixBuf->cbFrame * cFramesChunk1);
    18441796
    18451797        /* second chunk */
    18461798        if (cFramesChunk1 < cFrames)
    1847             RT_BZERO(&pMixBuf->pFrames[0], sizeof(pMixBuf->pFrames[0]) * (cFrames - cFramesChunk1));
     1799            RT_BZERO(&pMixBuf->pi32Samples[0], pMixBuf->cbFrame * (cFrames - cFramesChunk1));
    18481800    }
    18491801    /*
    18501802     * Less than max volume?
    18511803     */
    1852     else if (   pMixBuf->Volume.uLeft  != AUDIOMIXBUF_VOL_0DB
    1853              || pMixBuf->Volume.uRight != AUDIOMIXBUF_VOL_0DB)
     1804    else if (!pMixBuf->Volume.fAllMax)
    18541805    {
    18551806        /* first chunk */
     
    19091860    if (!pVol->fMuted)
    19101861    {
    1911         pMixBuf->Volume.fMuted = false;
     1862        pMixBuf->Volume.fMuted  = false;
     1863
    19121864        AssertCompileSize(pVol->uLeft, sizeof(uint8_t));
    1913         pMixBuf->Volume.uLeft  = s_aVolumeConv[pVol->uLeft ] * (AUDIOMIXBUF_VOL_0DB >> 16);
    1914         pMixBuf->Volume.uRight = s_aVolumeConv[pVol->uRight] * (AUDIOMIXBUF_VOL_0DB >> 16);
     1865        pMixBuf->Volume.auChannels[0] = s_aVolumeConv[pVol->uLeft ] * (AUDIOMIXBUF_VOL_0DB >> 16);
     1866        pMixBuf->Volume.auChannels[1] = s_aVolumeConv[pVol->uRight] * (AUDIOMIXBUF_VOL_0DB >> 16);
     1867        for (uintptr_t i = 2; i < pMixBuf->cChannels; i++)
     1868            pMixBuf->Volume.auChannels[i] = pMixBuf->Volume.auChannels[1];
     1869
     1870        pMixBuf->Volume.fAllMax = true;
     1871        for (uintptr_t i = 0; i < pMixBuf->cChannels; i++)
     1872            if (pMixBuf->Volume.auChannels[i] != AUDIOMIXBUF_VOL_0DB)
     1873            {
     1874                pMixBuf->Volume.fAllMax = false;
     1875                break;
     1876            }
    19151877    }
    19161878    else
    19171879    {
    1918         pMixBuf->Volume.fMuted = true;
    1919         pMixBuf->Volume.uLeft  = 0;
    1920         pMixBuf->Volume.uRight = 0;
    1921     }
    1922 }
    1923 
     1880        pMixBuf->Volume.fMuted  = true;
     1881        pMixBuf->Volume.fAllMax = false;
     1882        for (uintptr_t i = 0; i < RT_ELEMENTS(pMixBuf->Volume.auChannels); i++)
     1883            pMixBuf->Volume.auChannels[i] = 0;
     1884    }
     1885}
     1886
  • trunk/src/VBox/Devices/Audio/AudioMixBuffer.h

    r89373 r89378  
    5050    union
    5151    {
    52         int64_t         ai64Samples[2];
    53         PDMAUDIOFRAME   Frame;
     52        int32_t     ai32Samples[PDMAUDIO_MAX_CHANNELS];
    5453    } SrcLast;
    5554
     
    5857     * @returns Number of destination frames written.
    5958     */
    60     DECLR3CALLBACKMEMBER(uint32_t, pfnResample, (int64_t *pi64Dst, uint32_t cDstFrames,
    61                                                  int64_t const *pi64Src, uint32_t cSrcFrames, uint32_t *pcSrcFramesRead,
     59    DECLR3CALLBACKMEMBER(uint32_t, pfnResample, (int32_t *pi32Dst, uint32_t cDstFrames,
     60                                                 int32_t const *pi32Src, uint32_t cSrcFrames, uint32_t *pcSrcFramesRead,
    6261                                                 struct AUDIOSTREAMRATE *pRate));
    6362
     
    7675    /** Set to @c true if this stream is muted, @c false if not. */
    7776    bool            fMuted;
    78     /** Left volume to apply during conversion.
    79      * Pass 0 to convert the original values. May not apply to all conversion functions. */
    80     uint32_t        uLeft;
    81     /** Right volume to apply during conversion.
    82      * Pass 0 to convert the original values. May not apply to all conversion functions. */
    83     uint32_t        uRight;
     77    /** Set if all (relevant) channels are at max. */
     78    bool            fAllMax;
     79    /** The per-channels values. */
     80    uint32_t        auChannels[PDMAUDIO_MAX_CHANNELS];
    8481} AUDMIXBUFVOL;
    8582/** Pointer to mixing buffer volument parameters. */
     
    9996{
    10097    /** Encodes @a cFrames from @a paSrc to @a pvDst. */
    101     DECLR3CALLBACKMEMBER(void,  pfnEncode,(void *pvDst, int64_t const *paSrc, uint32_t cFrames, struct AUDIOMIXBUFPEEKSTATE *pState));
     98    DECLR3CALLBACKMEMBER(void,  pfnEncode,(void *pvDst, int32_t const *paSrc, uint32_t cFrames, struct AUDIOMIXBUFPEEKSTATE *pState));
    10299    /** Sample rate conversion state (only used when needed). */
    103100    AUDIOSTREAMRATE             Rate;
     
    120117{
    121118    /** Encodes @a cFrames from @a pvSrc to @a paDst. */
    122     DECLR3CALLBACKMEMBER(void,  pfnDecode,(int64_t *paDst, const void *pvSrc, uint32_t cFrames, struct AUDIOMIXBUFWRITESTATE *pState));
     119    DECLR3CALLBACKMEMBER(void,  pfnDecode,(int32_t *paDst, const void *pvSrc, uint32_t cFrames, struct AUDIOMIXBUFWRITESTATE *pState));
    123120    /** Encodes @a cFrames from @a pvSrc blending into @a paDst. */
    124     DECLR3CALLBACKMEMBER(void,  pfnDecodeBlend,(int64_t *paDst, const void *pvSrc, uint32_t cFrames, struct AUDIOMIXBUFWRITESTATE *pState));
     121    DECLR3CALLBACKMEMBER(void,  pfnDecodeBlend,(int32_t *paDst, const void *pvSrc, uint32_t cFrames, struct AUDIOMIXBUFWRITESTATE *pState));
    125122    /** Sample rate conversion state (only used when needed). */
    126123    AUDIOSTREAMRATE             Rate;
     
    145142    /** Size of the frame buffer (in audio frames). */
    146143    uint32_t                    cFrames;
    147     /** Frame buffer. */
    148     PPDMAUDIOFRAME              pFrames;
     144    /** The frame buffer.
     145     * This is a two dimensional array consisting of cFrames rows and
     146     * cChannels columns. */
     147    int32_t                    *pi32Samples;
     148    /** The number of channels. */
     149    uint8_t                     cChannels;
     150    /** The frame size (row size if you like). */
     151    uint8_t                     cbFrame;
     152    uint8_t                     abPadding[2];
    149153    /** The current read position (in frames). */
    150154    uint32_t                    offRead;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette