VirtualBox

Changeset 54980 in vbox


Ignore:
Timestamp:
Mar 27, 2015 7:00:47 AM (10 years ago)
Author:
vboxsync
Message:

PDM/Audio/AudioMixBuffer.cpp: Fixes.

File:
1 edited

Legend:

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

    r54861 r54980  
    1717 */
    1818
     19/*
     20 * DEBUG_DUMP_PCM_DATA enables dumping the raw PCM data
     21 * to a file on the host. Be sure to adjust the dumping path
     22 * to your needs before using this!
     23 */
     24#ifdef DEBUG
     25//# define DEBUG_DUMP_PCM_DATA
     26#endif
     27
    1928#include <iprt/asm-math.h>
    2029#include <iprt/assert.h>
     
    6473#endif
    6574
    66 static int audioMixBufInitCommon(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PPDMPCMPROPS pProps);
    6775static void audioMixBufFreeBuf(PPDMAUDIOMIXBUF pMixBuf);
    6876static inline void audioMixBufPrint(PPDMAUDIOMIXBUF pMixBuf);
     
    232240
    233241#ifdef DEBUG_MACROS
    234 # define AUDMIXBUF_MACRO_LOG(x) AUDMIXBUF_LOG((x))
     242# define AUDMIXBUF_MACRO_LOG(x) AUDMIXBUF_LOG(x)
    235243#elif defined(TESTCASE)
    236244# define AUDMIXBUF_MACRO_LOG(x) RTPrintf x
     
    349357                                                  uint32_t *pcDstWritten, uint32_t *pcSrcRead) \
    350358    { \
    351         AUDMIXBUF_MACRO_LOG(("pRate=%p: srcOffset=%RU32, dstOffset=%RU64, dstInc=%RU64\n", \
    352                              pRate, pRate->srcOffset, pRate->dstOffset, pRate->dstInc)); \
     359        AUDMIXBUF_MACRO_LOG(("cSrcSamples=%RU32, cDstSamples=%RU32\n", cSrcSamples, cDstSamples)); \
     360        AUDMIXBUF_MACRO_LOG(("pRate=%p: srcOffset=0x%x (%RU32), dstOffset=0x%x (%RU32), dstInc=0x%x (%RU64)\n", \
     361                             pRate, pRate->srcOffset, pRate->srcOffset, pRate->dstOffset >> 32, pRate->dstOffset >> 32, \
     362                             pRate->dstInc, pRate->dstInc)); \
    353363        \
    354         if (pRate->dstInc == (1ULL + UINT32_MAX)) \
     364        if (pRate->dstInc == (UINT64_C(1) + UINT32_MAX)) /* No conversion needed? */ \
    355365        { \
    356             uint32_t cSamples = cSrcSamples > cDstSamples ? cDstSamples : cSrcSamples; \
     366            uint32_t cSamples = RT_MIN(cSrcSamples, cDstSamples); \
    357367            AUDMIXBUF_MACRO_LOG(("cSamples=%RU32\n", cSamples)); \
    358368            for (uint32_t i = 0; i < cSamples; i++) \
     
    373383        PPDMAUDIOSAMPLE paDstStart = paDst; \
    374384        PPDMAUDIOSAMPLE paDstEnd   = paDst + cDstSamples; \
    375         PDMAUDIOSAMPLE  samCur, samOut; \
     385        PDMAUDIOSAMPLE  samCur = { 0 }; \
     386        PDMAUDIOSAMPLE  samOut; \
    376387        PDMAUDIOSAMPLE  samLast    = pRate->srcSampleLast; \
    377         uint64_t        l          = 0; \
     388        uint64_t        lDelta; \
    378389        \
    379390        AUDMIXBUF_MACRO_LOG(("Start: paDstEnd=%p - paDstStart=%p -> %zu\n", paDstEnd, paDst, paDstEnd - paDstStart)); \
     
    382393        while (paDst < paDstEnd) \
    383394        { \
     395            Assert(paSrc <= paSrcEnd); \
     396            Assert(paDst <= paDstEnd); \
     397            if (paSrc == paSrcEnd) \
     398                break; \
     399            \
     400            lDelta = 0; \
    384401            while (pRate->srcOffset <= (pRate->dstOffset >> 32)) \
    385402            { \
     403                Assert(paSrc <= paSrcEnd); \
    386404                samLast = *paSrc++; \
    387405                pRate->srcOffset++; \
    388                 l++; \
    389                 if (paSrc >= paSrcEnd) \
     406                lDelta++; \
     407                if (paSrc == paSrcEnd) \
    390408                    break; \
    391409            } \
     410            \
     411            Assert(paSrc <= paSrcEnd); \
     412            if (paSrc == paSrcEnd) \
     413                break; \
    392414            \
    393415            samCur = *paSrc; \
    394416            \
    395417            /* Interpolate. */ \
    396             int64_t t = pRate->dstOffset & 0xffffffff; \
     418            int64_t iDstOffInt = pRate->dstOffset & UINT32_MAX; \
    397419            \
    398             samOut.u64LSample = (samLast.u64LSample * ((int64_t) UINT32_MAX - t) + samCur.u64LSample * t) >> 32; \
    399             samOut.u64RSample = (samLast.u64RSample * ((int64_t) UINT32_MAX - t) + samCur.u64RSample * t) >> 32; \
     420            samOut.u64LSample = (samLast.u64LSample * ((int64_t) UINT32_MAX - iDstOffInt) + samCur.u64LSample * iDstOffInt) >> 32; \
     421            samOut.u64RSample = (samLast.u64RSample * ((int64_t) UINT32_MAX - iDstOffInt) + samCur.u64RSample * iDstOffInt) >> 32; \
    400422            \
    401423            paDst->u64LSample _aOp samOut.u64LSample; \
     
    403425            paDst++; \
    404426            \
    405             AUDMIXBUF_MACRO_LOG(("\tt=%RI64, l=%RI64, r=%RI64 (cur l=%RI64, r=%RI64)\n", t, \
     427            AUDMIXBUF_MACRO_LOG(("\tlDelta=0x%x (%RU64), iDstOffInt=0x%x (%RI64), l=%RI64, r=%RI64 (cur l=%RI64, r=%RI64)\n", \
     428                                 lDelta, lDelta, iDstOffInt, iDstOffInt, \
    406429                                 paDst->u64LSample, paDst->u64RSample, \
    407430                                 samCur.u64LSample, samCur.u64RSample)); \
     
    409432            pRate->dstOffset += pRate->dstInc; \
    410433            \
    411             AUDMIXBUF_MACRO_LOG(("\t\tpRate->dstOffset=%RU64\n", pRate->dstOffset)); \
    412             \
    413             if (paSrc >= paSrcEnd) \
    414                 break; \
     434            AUDMIXBUF_MACRO_LOG(("\t\tpRate->dstOffset=0x%x (%RU32)\n", pRate->dstOffset, pRate->dstOffset >> 32)); \
    415435            \
    416436        } \
     
    421441        pRate->srcSampleLast = samLast; \
    422442        \
    423         AUDMIXBUF_MACRO_LOG(("l=%RU64, pRate->srcSampleLast l=%RI64, r=%RI64\n", \
    424                               l, pRate->srcSampleLast.u64LSample, pRate->srcSampleLast.u64RSample)); \
     443        AUDMIXBUF_MACRO_LOG(("pRate->srcSampleLast l=%RI64, r=%RI64, lDelta=0x%x (%RU64)\n", \
     444                              pRate->srcSampleLast.u64LSample, pRate->srcSampleLast.u64RSample, lDelta, lDelta)); \
    425445        \
    426446        if (pcDstWritten) \
     
    689709    pMixBuf->pParent = pParent;
    690710
    691     /** @todo Only handles ADC (and not DAC) conversion for now. If you
    692      *        want DAC conversion, link the buffers the other way around. */
    693 
    694711    /* Calculate the frequency ratio. */
    695     pMixBuf->iFreqRatio =
    696           (  (int64_t)AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt) << 32)
    697         /             AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt);
     712    pMixBuf->iFreqRatio = ((int64_t)AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt) << 32)
     713                        /           AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt);
    698714
    699715    if (pMixBuf->iFreqRatio == 0) /* Catch division by zero. */
     
    712728                       pMixBuf->pszName, pMixBuf->cSamples, cSamples));
    713729
    714         pMixBuf->pSamples = (PPDMAUDIOSAMPLE)RTMemRealloc(pMixBuf->pSamples,
    715                                                           cSamples * sizeof(PDMAUDIOSAMPLE));
     730        uint32_t cbSamples = cSamples * sizeof(PDMAUDIOSAMPLE);
     731        Assert(cbSamples);
     732        pMixBuf->pSamples = (PPDMAUDIOSAMPLE)RTMemRealloc(pMixBuf->pSamples, cbSamples);
    716733        if (!pMixBuf->pSamples)
    717734            rc = VERR_NO_MEMORY;
    718735
    719736        if (RT_SUCCESS(rc))
     737        {
    720738            pMixBuf->cSamples = cSamples;
     739
     740            /* Make sure to zero the reallocated buffer so that it can be
     741             * used properly when blending with another buffer later. */
     742            RT_BZERO(pMixBuf->pSamples, cbSamples);
     743        }
    721744    }
    722745
     
    733756            RT_BZERO(pMixBuf->pRate, sizeof(PDMAUDIOSTRMRATE));
    734757
    735         pMixBuf->pRate->dstInc =
    736             (  (uint64_t)AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt) << 32)
    737              /           AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt);
    738 
    739         AUDMIXBUF_LOG(("uThisHz=%RU32, uParentHz=%RU32, iFreqRatio=%RI64, uRateInc=%RU64, cSamples=%RU32 (%RU32 parent)\n",
     758        pMixBuf->pRate->dstInc = ((uint64_t)AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt) << 32)
     759                               /            AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt);
     760
     761        AUDMIXBUF_LOG(("uThisHz=%RU32, uParentHz=%RU32, iFreqRatio=0x%x (%RI64), uRateInc=0x%x (%RU64), cSamples=%RU32 (%RU32 parent)\n",
    740762                       AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt),
    741763                       AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt),
    742                        pMixBuf->iFreqRatio,
    743                        pMixBuf->pRate->dstInc,
     764                       pMixBuf->iFreqRatio, pMixBuf->iFreqRatio,
     765                       pMixBuf->pRate->dstInc, pMixBuf->pRate->dstInc,
    744766                       pMixBuf->cSamples,
    745767                       pParent->cSamples));
     768        AUDMIXBUF_LOG(("%s (%RU32Hz) -> %s (%RU32Hz)\n",
     769                       pMixBuf->pszName, AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt),
     770                       pMixBuf->pParent->pszName, AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt)));
    746771    }
    747772
     
    800825        if (!cToWrite)
    801826        {
    802             AUDMIXBUF_LOG(("Destination buffer \"%s\" full\n", pDst->pszName));
     827            AUDMIXBUF_LOG(("Warning: Destination buffer \"%s\" full\n", pDst->pszName));
    803828            break;
    804829        }
     
    807832        Assert(offRead + cToRead <= pSrc->cSamples);
    808833
     834        AUDMIXBUF_LOG(("\t%RU32Hz -> %RU32Hz\n", AUDMIXBUF_FMT_SAMPLE_FREQ(pSrc->AudioFmt), AUDMIXBUF_FMT_SAMPLE_FREQ(pDst->AudioFmt)));
    809835        AUDMIXBUF_LOG(("\tcDead=%RU32, offWrite=%RU32, cToWrite=%RU32, offRead=%RU32, cToRead=%RU32\n",
    810836                       cDead, offWrite, cToWrite, offRead, cToRead));
     
    10431069    if (RT_SUCCESS(rc))
    10441070    {
     1071#ifdef DEBUG_DUMP_PCM_DATA
     1072        RTFILE fh;
     1073        rc = RTFileOpen(&fh, "c:\\temp\\mixbuf_readcirc.pcm",
     1074                        RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
     1075        if (RT_SUCCESS(rc))
     1076        {
     1077            RTFileWrite(fh, pvBuf, AUDIOMIXBUF_S2B(pMixBuf, cLenSrc1 + cLenSrc2), NULL);
     1078            RTFileClose(fh);
     1079        }
     1080#endif
    10451081        pMixBuf->offReadWrite = offRead % pMixBuf->cSamples;
    10461082        pMixBuf->cProcessed -= RT_MIN(cLenSrc1 + cLenSrc2, pMixBuf->cProcessed);
     
    10681104    pMixBuf->cProcessed   = 0;
    10691105
    1070     RT_BZERO(pMixBuf->pSamples, AUDIOMIXBUF_S2B(pMixBuf, pMixBuf->cSamples));
     1106    if (pMixBuf->cSamples)
     1107        RT_BZERO(pMixBuf->pSamples, pMixBuf->cSamples * sizeof(PDMAUDIOSAMPLE));
    10711108}
    10721109
     
    11201157    }
    11211158
    1122     pMixBuf->iFreqRatio = 0;
    1123 
    11241159    if (pMixBuf->pRate)
    11251160    {
    1126         RTMemFree(pMixBuf->pRate);
    1127         pMixBuf->pRate = NULL;
    1128     }
     1161        pMixBuf->pRate->dstOffset = pMixBuf->pRate->srcOffset = 0;
     1162        pMixBuf->pRate->dstInc = 0;
     1163    }
     1164
     1165    pMixBuf->iFreqRatio = 1; /* Prevent division by zero. */
    11291166}
    11301167
     
    11781215#ifdef DEBUG_DUMP_PCM_DATA
    11791216    RTFILE fh;
    1180     rc = RTFileOpen(&fh, "c:\\temp\\test_writeat.pcm",
     1217    rc = RTFileOpen(&fh, "c:\\temp\\mixbuf_writeat.pcm",
    11811218                    RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    11821219    if (RT_SUCCESS(rc))
     
    12961333#ifdef DEBUG_DUMP_PCM_DATA
    12971334        RTFILE fh;
    1298         RTFileOpen(&fh, "c:\\temp\\test_writeex.pcm",
     1335        RTFileOpen(&fh, "c:\\temp\\mixbuf_writeex.pcm",
    12991336                   RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    13001337        RTFileWrite(fh, pSamplesDst1, AUDIOMIXBUF_S2B(pMixBuf, cLenDst1), NULL);
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