VirtualBox

Changeset 89398 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 31, 2021 12:36:23 PM (4 years ago)
Author:
vboxsync
Message:

AudioMixBuffer: Converting AUDMIXBUF_CONVERT into a template file to simplify debugging (can't step macro template code in windbg). bugref:9890

File:
1 edited

Legend:

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

    r89382 r89398  
    303303#endif
    304304
    305 /**
    306  * Macro for generating the conversion routines from/to different formats.
    307  * Be careful what to pass in/out, as most of the macros are optimized for speed and
    308  * thus don't do any bounds checking!
    309  *
    310  * @note Currently does not handle any endianness conversion yet!
    311  */
    312 #define AUDMIXBUF_CONVERT(a_Name, a_Type, _aMin, _aMax, _aSigned, _aShift) \
    313     /* Clips a specific output value to a single sample value. */ \
    314     DECLINLINE(int32_t) audioMixBufSampleFrom##a_Name(a_Type aVal) \
    315     { \
    316         /* left shifting of signed values is not defined, therefore the intermediate uint64_t cast */ \
    317         if (_aSigned) \
    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)); \
    320     } \
    321     \
    322     /* Clips a single sample value to a specific output value. */ \
    323     DECLINLINE(a_Type) audioMixBufSampleTo##a_Name(int32_t iVal) \
    324     { \
    325         if (_aSigned) \
    326             return (a_Type)  (iVal >> (32 - _aShift)); \
    327         return     (a_Type) ((iVal >> (32 - _aShift)) + ((_aMax >> 1) + 1)); \
    328     } \
    329     \
    330     /* Encoders for peek: */ \
    331     \
    332     /* Generic */ \
    333     static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncodeGeneric,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \
    334                                                                          PAUDIOMIXBUFPEEKSTATE pState) \
    335     { \
    336         RT_NOREF_PV(pState); \
    337         uintptr_t const cSrcChannels = pState->cSrcChannels; \
    338         uintptr_t const cDstChannels = pState->cDstChannels; \
    339         a_Type         *pDst = (a_Type *)pvDst; \
    340         while (cFrames-- > 0) \
    341         { \
    342             uintptr_t idxDst = cDstChannels; \
    343             while (idxDst-- > 0) \
    344             { \
    345                 int8_t idxSrc = pState->aidxChannelMap[idxDst]; \
    346                 if (idxSrc >= 0) \
    347                     pDst[idxDst] = audioMixBufSampleTo##a_Name(pi32Src[idxSrc]); \
    348                 else if (idxSrc != -2) \
    349                     pDst[idxDst] = (_aSigned) ? 0 : (_aMax >> 1); \
    350                 else \
    351                     pDst[idxDst] = 0; \
    352             } \
    353             pDst    += cDstChannels; \
    354             pi32Src += cSrcChannels; \
    355         } \
    356     } \
    357     \
    358     /* 2ch -> 2ch */ \
    359     static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo2Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \
    360                                                                           PAUDIOMIXBUFPEEKSTATE pState) \
    361     { \
    362         RT_NOREF_PV(pState); \
    363         a_Type *pDst = (a_Type *)pvDst; \
    364         while (cFrames-- > 0) \
    365         { \
    366             pDst[0] = audioMixBufSampleTo##a_Name(pi32Src[0]); \
    367             pDst[1] = audioMixBufSampleTo##a_Name(pi32Src[1]); \
    368             AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n", \
    369                                  &pi32Src[0], pi32Src[0], pi32Src[1], (int32_t)pDst[0], (int32_t)pDst[1])); \
    370             pDst    += 2; \
    371             pi32Src += 2; \
    372         } \
    373     } \
    374     \
    375     /* 2ch -> 1ch */ \
    376     static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo1Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \
    377                                                                           PAUDIOMIXBUFPEEKSTATE pState) \
    378     { \
    379         RT_NOREF_PV(pState); \
    380         a_Type *pDst = (a_Type *)pvDst; \
    381         while (cFrames-- > 0) \
    382         { \
    383              pDst[0] = audioMixBufSampleTo##a_Name(audioMixBufBlendSampleRet(pi32Src[0], pi32Src[1])); \
    384              pDst    += 1; \
    385              pi32Src += 2; \
    386         } \
    387     } \
    388     \
    389     /* 1ch -> 2ch */ \
    390     static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo2Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \
    391                                                                           PAUDIOMIXBUFPEEKSTATE pState) \
    392     { \
    393         RT_NOREF_PV(pState); \
    394         a_Type *pDst = (a_Type *)pvDst; \
    395         while (cFrames-- > 0) \
    396         { \
    397             pDst[0] = pDst[1] = audioMixBufSampleTo##a_Name(pi32Src[0]); \
    398             pDst    += 2; \
    399             pi32Src += 1; \
    400         } \
    401     } \
    402     /* 1ch -> 1ch */ \
    403     static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo1Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \
    404                                                                           PAUDIOMIXBUFPEEKSTATE pState) \
    405     { \
    406         RT_NOREF_PV(pState); \
    407         a_Type *pDst = (a_Type *)pvDst; \
    408         while (cFrames-- > 0) \
    409         { \
    410              pDst[0] = audioMixBufSampleTo##a_Name(pi32Src[0]); \
    411              pDst    += 1; \
    412              pi32Src += 1; \
    413         } \
    414     } \
    415     \
    416     /* Decoders for write: */ \
    417     \
    418     /* Generic */ \
    419     static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecodeGeneric,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \
    420                                                                          PAUDIOMIXBUFWRITESTATE pState) \
    421     { \
    422         RT_NOREF_PV(pState); \
    423         uintptr_t const cSrcChannels = pState->cSrcChannels; \
    424         uintptr_t const cDstChannels = pState->cDstChannels; \
    425         a_Type const   *pSrc         = (a_Type const *)pvSrc; \
    426         while (cFrames-- > 0) \
    427         { \
    428             uintptr_t idxDst = cDstChannels; \
    429             while (idxDst-- > 0) \
    430             { \
    431                 int8_t idxSrc = pState->aidxChannelMap[idxDst]; \
    432                 if (idxSrc >= 0) \
    433                     pi32Dst[idxDst] = audioMixBufSampleTo##a_Name(pSrc[idxSrc]); \
    434                 else if (idxSrc != -2) \
    435                     pi32Dst[idxDst] = (_aSigned) ? 0 : (_aMax >> 1); \
    436                 else \
    437                     pi32Dst[idxDst] = 0; \
    438             } \
    439             pi32Dst += cDstChannels; \
    440             pSrc    += cSrcChannels; \
    441         } \
    442     } \
    443     \
    444     /* 2ch -> 2ch */ \
    445     static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo2Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \
    446                                                                           PAUDIOMIXBUFWRITESTATE pState) \
    447     { \
    448         RT_NOREF_PV(pState); \
    449         a_Type const *pSrc = (a_Type const *)pvSrc; \
    450         while (cFrames-- > 0) \
    451         { \
    452             pi32Dst[0] = audioMixBufSampleFrom##a_Name(pSrc[0]); \
    453             pi32Dst[1] = audioMixBufSampleFrom##a_Name(pSrc[1]); \
    454             AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n", \
    455                                  &pSrc[0], (int32_t)pSrc[0], (int32_t)pSrc[1], pi32Dst[0], pi32Dst[1])); \
    456             pi32Dst  += 2; \
    457             pSrc     += 2; \
    458         } \
    459     } \
    460     \
    461     /* 2ch -> 1ch */ \
    462     static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo1Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \
    463                                                                           PAUDIOMIXBUFWRITESTATE pState) \
    464     { \
    465         RT_NOREF_PV(pState); \
    466         a_Type const *pSrc = (a_Type const *)pvSrc; \
    467         while (cFrames-- > 0) \
    468         { \
    469             pi32Dst[0] = audioMixBufBlendSampleRet(audioMixBufSampleFrom##a_Name(pSrc[0]), audioMixBufSampleFrom##a_Name(pSrc[1])); \
    470             pi32Dst  += 1; \
    471             pSrc     += 2; \
    472         } \
    473     } \
    474     \
    475     /* 1ch -> 2ch */ \
    476     static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo2Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \
    477                                                                           PAUDIOMIXBUFWRITESTATE pState) \
    478     { \
    479         RT_NOREF_PV(pState); \
    480         a_Type const *pSrc = (a_Type const *)pvSrc; \
    481         while (cFrames-- > 0) \
    482         { \
    483             pi32Dst[1] = pi32Dst[0] = audioMixBufSampleFrom##a_Name(pSrc[0]); \
    484             pi32Dst  += 2; \
    485             pSrc     += 1; \
    486         } \
    487     } \
    488     \
    489     /* 1ch -> 1ch */ \
    490     static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo1Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \
    491                                                                           PAUDIOMIXBUFWRITESTATE pState) \
    492     { \
    493         RT_NOREF_PV(pState); \
    494         a_Type const *pSrc = (a_Type const *)pvSrc; \
    495         while (cFrames-- > 0) \
    496         { \
    497             pi32Dst[0] = audioMixBufSampleFrom##a_Name(pSrc[0]); \
    498             pi32Dst  += 1; \
    499             pSrc     += 1; \
    500         } \
    501     } \
    502     \
    503     /* Decoders for blending: */ \
    504     \
    505     /* Generic */ \
    506     static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecodeGeneric,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \
    507                                                                                 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
    508     { \
    509         RT_NOREF_PV(pState); \
    510         uintptr_t const cSrcChannels = pState->cSrcChannels; \
    511         uintptr_t const cDstChannels = pState->cDstChannels; \
    512         a_Type const   *pSrc         = (a_Type const *)pvSrc; \
    513         while (cFrames-- > 0) \
    514         { \
    515             uintptr_t idxDst = cDstChannels; \
    516             while (idxDst-- > 0) \
    517             { \
    518                 int8_t idxSrc = pState->aidxChannelMap[idxDst]; \
    519                 if (idxSrc >= 0) \
    520                     audioMixBufBlendSample(&pi32Dst[idxDst], audioMixBufSampleTo##a_Name(pSrc[idxSrc])); \
    521             } \
    522             pi32Dst += cDstChannels; \
    523             pSrc    += cSrcChannels; \
    524         } \
    525     } \
    526     \
    527     /* 2ch -> 2ch */ \
    528     static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo2Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \
    529                                                                                  uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
    530     { \
    531         RT_NOREF_PV(pState); \
    532         a_Type const *pSrc = (a_Type const *)pvSrc; \
    533         while (cFrames-- > 0) \
    534         { \
    535             audioMixBufBlendSample(&pi32Dst[0], audioMixBufSampleFrom##a_Name(pSrc[0])); \
    536             audioMixBufBlendSample(&pi32Dst[1], audioMixBufSampleFrom##a_Name(pSrc[1])); \
    537             AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n", \
    538                                  &pSrc[0], (int32_t)pSrc[0], (int32_t)pSrc[1], pi32Dst[0], pi32Dst[1])); \
    539             pi32Dst  += 2; \
    540             pSrc     += 2; \
    541         } \
    542     } \
    543     \
    544     /* 2ch -> 1ch */ \
    545     static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo1Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \
    546                                                                                  uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
    547     { \
    548         RT_NOREF_PV(pState); \
    549         a_Type const *pSrc = (a_Type const *)pvSrc; \
    550         while (cFrames-- > 0) \
    551         { \
    552             audioMixBufBlendSample(&pi32Dst[0], audioMixBufBlendSampleRet(audioMixBufSampleFrom##a_Name(pSrc[0]), \
    553                                                                           audioMixBufSampleFrom##a_Name(pSrc[1]))); \
    554             pi32Dst  += 1; \
    555             pSrc     += 2; \
    556         } \
    557     } \
    558     \
    559     /* 1ch -> 2ch */ \
    560     static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo2Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \
    561                                                                                  uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
    562     { \
    563         RT_NOREF_PV(pState); \
    564         a_Type const *pSrc = (a_Type const *)pvSrc; \
    565         while (cFrames-- > 0) \
    566         { \
    567             int32_t const i32Src = audioMixBufSampleFrom##a_Name(pSrc[0]); \
    568             audioMixBufBlendSample(&pi32Dst[0], i32Src); \
    569             audioMixBufBlendSample(&pi32Dst[1], i32Src); \
    570             pi32Dst  += 2; \
    571             pSrc     += 1; \
    572         } \
    573     } \
    574     \
    575     /* 1ch -> 1ch */ \
    576     static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo1Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \
    577                                                                                  uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
    578     { \
    579         RT_NOREF_PV(pState); \
    580         a_Type const *pSrc = (a_Type const *)pvSrc; \
    581         while (cFrames-- > 0) \
    582         { \
    583             audioMixBufBlendSample(&pi32Dst[0], audioMixBufSampleFrom##a_Name(pSrc[0])); \
    584             pi32Dst  += 1; \
    585             pSrc     += 1; \
    586         } \
    587     }
    588 
     305/*
     306 * Instantiate format conversion (in and out of the mixer buffer.)
     307 */
     308/** @todo Currently does not handle any endianness conversion yet! */
     309
     310#include "AudioMixBuffer-Convert.cpp.h"
    589311
    590312/* audioMixBufConvXXXS8: 8-bit, signed. */
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