VirtualBox

Changeset 89305 in vbox


Ignore:
Timestamp:
May 27, 2021 12:48:46 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144652
Message:

Audio: Reworking the capture (recording) code path, part 2: Mixer buffer blending (untested). bugref:9890

File:
1 edited

Legend:

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

    r89302 r89305  
    384384    return VERR_NO_MEMORY;
    385385}
     386
     387
     388/**
     389 * Merges @a i64Src into the value stored at @a pi64Dst.
     390 *
     391 * @param   pi64Dst     The value to merge @a i64Src into.
     392 * @param   i64Src      The new value to add.
     393 */
     394DECL_FORCE_INLINE(void) audioMixBufBlendSample(int64_t *pi64Dst, int64_t i64Src)
     395{
     396    if (i64Src)
     397    {
     398        int64_t const i64Dst = *pi64Dst;
     399        if (!pi64Dst)
     400            *pi64Dst = i64Src;
     401        else
     402            *pi64Dst = (i64Dst + i64Src) / 2;
     403    }
     404}
     405
     406
     407/**
     408 * Variant of audioMixBufBlendSample that returns the result rather than storing it.
     409 *
     410 * This is used for stereo -> mono.
     411 */
     412DECL_FORCE_INLINE(int64_t) audioMixBufBlendSampleRet(int64_t i64Sample1, int64_t i64Sample2)
     413{
     414    if (!i64Sample1)
     415        return i64Sample2;
     416    if (!i64Sample2)
     417        return i64Sample1;
     418    return (i64Sample1 + i64Sample2) / 2;
     419}
     420
     421
     422/**
     423 * Blends (merges) the source buffer into the destination buffer.
     424 *
     425 * We're taking a very simple approach here, working sample by sample:
     426 *  - if one is silent, use the other one.
     427 *  - otherwise sum and divide by two.
     428 *
     429 * @param   pi64Dst     The destination stream buffer (input and output).
     430 * @param   pi64Src     The source stream buffer.
     431 * @param   cFrames     Number of frames to process.
     432 * @param   cChannels   Number of channels.
     433 */
     434static void audioMixBufBlendBuffer(int64_t *pi64Dst, int64_t const *pi64Src, uint32_t cFrames, uint8_t cChannels)
     435{
     436    switch (cChannels)
     437    {
     438        case 2:
     439            while (cFrames-- > 0)
     440            {
     441                int64_t const i64DstL = pi64Dst[0];
     442                int64_t const i64SrcL = pi64Src[0];
     443                if (!i64DstL)
     444                    pi64Dst[0] = i64SrcL;
     445                else if (!i64SrcL)
     446                    pi64Dst[0] = (i64DstL + i64SrcL) / 2;
     447
     448                int64_t const i64DstR = pi64Dst[1];
     449                int64_t const i64SrcR = pi64Src[1];
     450                if (!i64DstR)
     451                    pi64Dst[1] = i64SrcR;
     452                else if (!i64SrcR)
     453                    pi64Dst[1] = (i64DstR + i64SrcR) / 2;
     454
     455                pi64Dst += 2;
     456                pi64Src += 2;
     457            }
     458            break;
     459
     460        default:
     461            cFrames *= cChannels;
     462            RT_FALL_THROUGH();
     463        case 1:
     464            while (cFrames-- > 0)
     465            {
     466                int64_t const i64Dst = *pi64Dst;
     467                int64_t const i64Src = *pi64Src;
     468                if (!i64Dst)
     469                    *pi64Dst = i64Src;
     470                else if (!i64Src)
     471                    *pi64Dst = (i64Dst + i64Src) / 2;
     472                pi64Dst++;
     473                pi64Src++;
     474            }
     475            break;
     476    }
     477}
     478
    386479
    387480#ifdef AUDIOMIXBUF_DEBUG_MACROS
     
    512605        while (cFrames-- > 0) \
    513606        { \
    514              pDst[0] = audioMixBufClipTo##a_Name((pi64Src[0] + pi64Src[1]) / 2); \
     607             pDst[0] = audioMixBufClipTo##a_Name(audioMixBufBlendSampleRet(pi64Src[0], pi64Src[1])); \
    515608             pDst    += 1; \
    516609             pi64Src += 2; \
     
    572665        while (cFrames-- > 0) \
    573666        { \
    574             pi64Dst[0] = (audioMixBufClipFrom##a_Name(pSrc[0]) + audioMixBufClipFrom##a_Name(pSrc[1])) / 2; \
     667            pi64Dst[0] = audioMixBufBlendSampleRet(audioMixBufClipFrom##a_Name(pSrc[0]), audioMixBufClipFrom##a_Name(pSrc[1])); \
    575668            pi64Dst  += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */ \
    576669            pSrc     += 2; \
     
    604697            pSrc     += 1; \
    605698        } \
    606     }
     699    } \
     700    \
     701    /* Decoders for blending: */ \
     702    \
     703    /* 2ch -> 2ch */ \
     704    static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo2Ch,a_Name,Blend)(int64_t *pi64Dst, void const *pvSrc, \
     705                                                                                 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
     706    { \
     707        RT_NOREF_PV(pState); \
     708        a_Type const *pSrc = (a_Type const *)pvSrc; \
     709        while (cFrames-- > 0) \
     710        { \
     711            audioMixBufBlendSample(&pi64Dst[0], audioMixBufClipFrom##a_Name(pSrc[0])); \
     712            audioMixBufBlendSample(&pi64Dst[1], audioMixBufClipFrom##a_Name(pSrc[1])); \
     713            AUDMIXBUF_MACRO_LOG(("%p: %RI64 / %RI64 => %RI64 / %RI64\n", \
     714                                 &pSrc[0], (int64_t)pSrc[0], (int64_t)pSrc[1], pi64Dst[0], pi64Dst[1])); \
     715            pi64Dst  += 2; \
     716            pSrc     += 2; \
     717        } \
     718    } \
     719    \
     720    /* 2ch -> 1ch */ \
     721    static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo1Ch,a_Name,Blend)(int64_t *pi64Dst, void const *pvSrc, \
     722                                                                                 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
     723    { \
     724        RT_NOREF_PV(pState); \
     725        a_Type const *pSrc = (a_Type const *)pvSrc; \
     726        while (cFrames-- > 0) \
     727        { \
     728            audioMixBufBlendSample(&pi64Dst[0], audioMixBufBlendSampleRet(audioMixBufClipFrom##a_Name(pSrc[0]), \
     729                                                                          audioMixBufClipFrom##a_Name(pSrc[1]))); \
     730            pi64Dst  += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */ \
     731            pSrc     += 2; \
     732        } \
     733    } \
     734    \
     735    /* 1ch -> 2ch */ \
     736    static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo2Ch,a_Name,Blend)(int64_t *pi64Dst, void const *pvSrc, \
     737                                                                                 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
     738    { \
     739        RT_NOREF_PV(pState); \
     740        a_Type const *pSrc = (a_Type const *)pvSrc; \
     741        while (cFrames-- > 0) \
     742        { \
     743            int64_t const i64Src = audioMixBufClipFrom##a_Name(pSrc[0]); \
     744            audioMixBufBlendSample(&pi64Dst[0], i64Src); \
     745            audioMixBufBlendSample(&pi64Dst[1], i64Src); \
     746            pi64Dst  += 2; \
     747            pSrc     += 1; \
     748        } \
     749    } \
     750    \
     751    /* 1ch -> 1ch */ \
     752    static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo1Ch,a_Name,Blend)(int64_t *pi64Dst, void const *pvSrc, \
     753                                                                                 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \
     754    { \
     755        RT_NOREF_PV(pState); \
     756        a_Type const *pSrc = (a_Type const *)pvSrc; \
     757        while (cFrames-- > 0) \
     758        { \
     759            audioMixBufBlendSample(&pi64Dst[0], audioMixBufClipFrom##a_Name(pSrc[0])); \
     760            pi64Dst  += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */ \
     761            pSrc     += 1; \
     762        } \
     763    }
     764
    607765
    608766/* audioMixBufConvXXXS8: 8 bit, signed. */
     
    665823    while (cFrames-- > 0)
    666824    {
    667          *pi64Dst = (pi64Src[0] + pi64Src[1]) / 2;
    668          pi64Dst += 1;
    669          pi64Src += 2;
     825        *pi64Dst = (pi64Src[0] + pi64Src[1]) / 2;
     826        pi64Dst += 1;
     827        pi64Src += 2;
    670828    }
    671829}
     
    678836    while (cFrames-- > 0)
    679837    {
    680          pi64Dst[0] = pi64Dst[1] = *pi64Src;
    681          pi64Dst += 2;
    682          pi64Src += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */
     838        pi64Dst[0] = pi64Dst[1] = *pi64Src;
     839        pi64Dst += 2;
     840        pi64Src += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */
    683841    }
    684842}
     
    693851    while (cFrames-- > 0)
    694852    {
    695          *pi64Dst = *pi64Src;
    696          pi64Dst += 1;
    697          pi64Src += 2;
     853        *pi64Dst = *pi64Src;
     854        pi64Dst += 1;
     855        pi64Src += 2;
    698856    }
    699857}
     
    716874    while (cFrames-- > 0)
    717875    {
    718          *pi64Dst = (pi64Src[0] + pi64Src[1]) / 2;
    719          pi64Dst += 2;  /** @todo when we do multi channel mixbuf support, this can change to 1 */
    720          pi64Src += 2;
     876        *pi64Dst = (pi64Src[0] + pi64Src[1]) / 2;
     877        pi64Dst += 2;  /** @todo when we do multi channel mixbuf support, this can change to 1 */
     878        pi64Src += 2;
    721879    }
    722880}
     
    729887    while (cFrames-- > 0)
    730888    {
    731          pi64Dst[0] = pi64Dst[1] = *pi64Src;
    732          pi64Dst += 2;
    733          pi64Src += 1;
     889        pi64Dst[0] = pi64Dst[1] = *pi64Src;
     890        pi64Dst += 2;
     891        pi64Src += 1;
    734892    }
    735893}
     
    744902    while (cFrames-- > 0)
    745903    {
    746          *pi64Dst = *pi64Src;
    747          pi64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */
    748          pi64Src += 1;
     904        *pi64Dst = *pi64Src;
     905        pi64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */
     906        pi64Src += 1;
     907    }
     908}
     909
     910
     911/* Decoders for blending: */
     912
     913static DECLCALLBACK(void)
     914audioMixBufDecode2ChTo2ChRawBlend(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
     915{
     916    RT_NOREF_PV(pState);
     917    audioMixBufBlendBuffer(pi64Dst, (int64_t const *)pvSrc, cFrames, 2);
     918}
     919
     920static DECLCALLBACK(void)
     921audioMixBufDecode2ChTo1ChRawBlend(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
     922{
     923    RT_NOREF_PV(pState);
     924    int64_t const *pi64Src = (int64_t const *)pvSrc;
     925    while (cFrames-- > 0)
     926    {
     927        audioMixBufBlendSample(pi64Dst, audioMixBufBlendSampleRet(pi64Src[0], pi64Src[1]));
     928        pi64Dst += 2;  /** @todo when we do multi channel mixbuf support, this can change to 1 */
     929        pi64Src += 2;
     930    }
     931}
     932
     933static DECLCALLBACK(void)
     934audioMixBufDecode1ChTo2ChRawBlend(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
     935{
     936    RT_NOREF_PV(pState);
     937    int64_t const *pi64Src = (int64_t const *)pvSrc;
     938    while (cFrames-- > 0)
     939    {
     940        int64_t const i64Src = *pi64Src;
     941        audioMixBufBlendSample(&pi64Dst[0], i64Src);
     942        audioMixBufBlendSample(&pi64Dst[1], i64Src);
     943        pi64Dst += 2;
     944        pi64Src += 1;
     945    }
     946}
     947
     948static DECLCALLBACK(void)
     949audioMixBufDecode1ChTo1ChRawBlend(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
     950{
     951    RT_NOREF_PV(pState);
     952    /** @todo memcpy(pi64Dst, pvSrc, sizeof(int64_t) * 1 * cFrames); when we do
     953     *        multi channel mixbuf support. */
     954    int64_t const *pi64Src = (int64_t const *)pvSrc;
     955    while (cFrames-- > 0)
     956    {
     957        audioMixBufBlendSample(&pi64Dst[0], *pi64Src);
     958        pi64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */
     959        pi64Src += 1;
    749960    }
    750961}
     
    21222333                {
    21232334                    case 1:
    2124                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChS8  : audioMixBufDecode2ChTo1ChS8;
     2335                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChS8       : audioMixBufDecode2ChTo1ChS8;
     2336                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChS8Blend  : audioMixBufDecode2ChTo1ChS8Blend;
    21252337                        break;
    21262338                    case 2:
    2127                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChS16 : audioMixBufDecode2ChTo1ChS16;
     2339                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChS16      : audioMixBufDecode2ChTo1ChS16;
     2340                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChS16Blend : audioMixBufDecode2ChTo1ChS16Blend;
    21282341                        break;
    21292342                    case 4:
    2130                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChS32 : audioMixBufDecode2ChTo1ChS32;
     2343                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChS32      : audioMixBufDecode2ChTo1ChS32;
     2344                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChS32Blend : audioMixBufDecode2ChTo1ChS32Blend;
    21312345                        break;
    21322346                    case 8:
    21332347                        AssertReturn(pProps->fRaw, VERR_DISK_INVALID_FORMAT);
    2134                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChRaw : audioMixBufDecode2ChTo1ChRaw;
     2348                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChRaw      : audioMixBufDecode2ChTo1ChRaw;
     2349                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChRawBlend : audioMixBufDecode2ChTo1ChRawBlend;
    21352350                        break;
    21362351                    default:
     
    21432358                {
    21442359                    case 1:
    2145                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChS8  : audioMixBufDecode2ChTo2ChS8;
     2360                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChS8       : audioMixBufDecode2ChTo2ChS8;
     2361                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChS8Blend  : audioMixBufDecode2ChTo2ChS8Blend;
    21462362                        break;
    21472363                    case 2:
    2148                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChS16 : audioMixBufDecode2ChTo2ChS16;
     2364                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChS16      : audioMixBufDecode2ChTo2ChS16;
     2365                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChS16Blend : audioMixBufDecode2ChTo2ChS16Blend;
    21492366                        break;
    21502367                    case 4:
    2151                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChS32 : audioMixBufDecode2ChTo2ChS32;
     2368                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChS32      : audioMixBufDecode2ChTo2ChS32;
     2369                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChS32Blend : audioMixBufDecode2ChTo2ChS32Blend;
    21522370                        break;
    21532371                    case 8:
    21542372                        AssertReturn(pProps->fRaw, VERR_DISK_INVALID_FORMAT);
    2155                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChRaw : audioMixBufDecode2ChTo2ChRaw;
     2373                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChRaw      : audioMixBufDecode2ChTo2ChRaw;
     2374                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChRawBlend : audioMixBufDecode2ChTo2ChRawBlend;
    21562375                        break;
    21572376                    default:
     
    21762395                {
    21772396                    case 1:
    2178                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChU8  : audioMixBufDecode2ChTo1ChU8;
     2397                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChU8       : audioMixBufDecode2ChTo1ChU8;
     2398                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChU8Blend  : audioMixBufDecode2ChTo1ChU8Blend;
    21792399                        break;
    21802400                    case 2:
    2181                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChU16 : audioMixBufDecode2ChTo1ChU16;
     2401                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChU16      : audioMixBufDecode2ChTo1ChU16;
     2402                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChU16Blend : audioMixBufDecode2ChTo1ChU16Blend;
    21822403                        break;
    21832404                    case 4:
    2184                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChU32 : audioMixBufDecode2ChTo1ChU32;
     2405                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChU32      : audioMixBufDecode2ChTo1ChU32;
     2406                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo1ChU32Blend : audioMixBufDecode2ChTo1ChU32Blend;
    21852407                        break;
    21862408                    default:
     
    21932415                {
    21942416                    case 1:
    2195                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChU8  : audioMixBufDecode2ChTo2ChU8;
     2417                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChU8       : audioMixBufDecode2ChTo2ChU8;
     2418                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChU8Blend  : audioMixBufDecode2ChTo2ChU8Blend;
    21962419                        break;
    21972420                    case 2:
    2198                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChU16 : audioMixBufDecode2ChTo2ChU16;
     2421                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChU16      : audioMixBufDecode2ChTo2ChU16;
     2422                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChU16Blend : audioMixBufDecode2ChTo2ChU16Blend;
    21992423                        break;
    22002424                    case 4:
    2201                         pState->pfnDecode = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChU32 : audioMixBufDecode2ChTo2ChU32;
     2425                        pState->pfnDecode      = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChU32      : audioMixBufDecode2ChTo2ChU32;
     2426                        pState->pfnDecodeBlend = cSrcCh == 1 ? audioMixBufDecode1ChTo2ChU32Blend : audioMixBufDecode2ChTo2ChU32Blend;
    22022427                        break;
    22032428                    default:
     
    23202545
    23212546/**
    2322  * Worker for AudioMixBufPeek that handles the rate conversion case.
     2547 * Worker for AudioMixBufWrite that handles the rate conversion case.
    23232548 */
    23242549DECL_NO_INLINE(static, void)
    2325 AudioMixBufWriteResampling(PAUDIOMIXBUF pMixBuf, PAUDIOMIXBUFWRITESTATE pState, const void *pvSrcBuf, uint32_t cbSrcBuf,
     2550audioMixBufWriteResampling(PAUDIOMIXBUF pMixBuf, PAUDIOMIXBUFWRITESTATE pState, const void *pvSrcBuf, uint32_t cbSrcBuf,
    23262551                           uint32_t offDstFrame, uint32_t cMaxDstFrames, uint32_t *pcDstFramesWritten)
    23272552{
     
    23882613    Assert(cMaxDstFrames <= pMixBuf->cFrames - pMixBuf->cUsed);
    23892614    Assert(offDstFrame <= pMixBuf->cFrames);
    2390     AssertPtr(pcDstFramesWritten);
    23912615    AssertPtr(pvSrcBuf);
    23922616    Assert(!(cbSrcBuf % pState->cbSrcFrame));
     
    24182642    }
    24192643    else
    2420         AudioMixBufWriteResampling(pMixBuf, pState, pvSrcBuf, cbSrcBuf, offDstFrame, cMaxDstFrames, pcDstFramesWritten);
     2644        audioMixBufWriteResampling(pMixBuf, pState, pvSrcBuf, cbSrcBuf, offDstFrame, cMaxDstFrames, pcDstFramesWritten);
     2645}
     2646
     2647
     2648/**
     2649 * Worker for AudioMixBufBlend that handles the rate conversion case.
     2650 */
     2651DECL_NO_INLINE(static, void)
     2652audioMixBufBlendResampling(PAUDIOMIXBUF pMixBuf, PAUDIOMIXBUFWRITESTATE pState, const void *pvSrcBuf, uint32_t cbSrcBuf,
     2653                           uint32_t offDstFrame, uint32_t cMaxDstFrames, uint32_t *pcDstFramesBlended)
     2654{
     2655    *pcDstFramesBlended = 0;
     2656    while (cMaxDstFrames > 0 && cbSrcBuf >= pState->cbSrcFrame)
     2657    {
     2658        /* Decode into temporary buffer. */
     2659        int64_t  ai64SrcDecoded[1024];
     2660        uint32_t cFramesDecoded = RT_MIN(RT_ELEMENTS(ai64SrcDecoded) / pState->cSrcChannels, cbSrcBuf / pState->cbSrcFrame);
     2661        pState->pfnDecode(ai64SrcDecoded, pvSrcBuf, cFramesDecoded, pState);
     2662        cbSrcBuf -= cFramesDecoded * pState->cbSrcFrame;
     2663        pvSrcBuf  = (uint8_t const *)pvSrcBuf + cFramesDecoded * pState->cbSrcFrame;
     2664
     2665        /* Rate convert that into another temporary buffer and then blend that into the mixer. */
     2666        uint32_t iFrameDecoded = 0;
     2667        while (iFrameDecoded < cFramesDecoded)
     2668        {
     2669            int64_t  ai64SrcRate[1024];
     2670            uint32_t cDstMaxFrames    = RT_MIN(RT_ELEMENTS(ai64SrcRate), cMaxDstFrames);
     2671            uint32_t cSrcFrames       = cFramesDecoded - iFrameDecoded;
     2672            uint32_t const cDstFrames = pState->Rate.pfnResample(&ai64SrcRate[0], cDstMaxFrames,
     2673                                                                 &ai64SrcDecoded[iFrameDecoded * pState->cSrcChannels],
     2674                                                                 cSrcFrames, &cSrcFrames, &pState->Rate);
     2675
     2676            /* First chunk.*/
     2677            uint32_t const cDstFrames1 = RT_MIN(pMixBuf->cFrames - offDstFrame, cDstFrames);
     2678            audioMixBufBlendBuffer(&pMixBuf->pFrames[offDstFrame].i64LSample, ai64SrcRate, cDstFrames1, pState->cSrcChannels);
     2679
     2680            /* Another chunk from the start of the mixing buffer? */
     2681            if (cDstFrames > cDstFrames1)
     2682                audioMixBufBlendBuffer(&pMixBuf->pFrames[0].i64LSample, &ai64SrcRate[cDstFrames1 * pState->cSrcChannels],
     2683                                       cDstFrames - cDstFrames1, pState->cSrcChannels);
     2684
     2685            /* Advance */
     2686            iFrameDecoded       += cSrcFrames;
     2687            *pcDstFramesBlended += cDstFrames;
     2688            offDstFrame          = (offDstFrame + cDstFrames) % pMixBuf->cFrames;
     2689        }
     2690    }
     2691
     2692    /** @todo How to squeeze odd frames out of 22050 => 44100 conversion?   */
    24212693}
    24222694
     
    24292701                      uint32_t offDstFrame, uint32_t cMaxDstFrames, uint32_t *pcDstFramesBlended)
    24302702{
    2431     /** @todo */
    2432     RT_NOREF(pMixBuf, pState, pvSrcBuf, cbSrcBuf, offDstFrame, cMaxDstFrames, pcDstFramesBlended);
     2703    /*
     2704     * Check inputs.
     2705     */
     2706    AssertPtr(pMixBuf);
     2707    Assert(pMixBuf->uMagic == AUDIOMIXBUF_MAGIC);
     2708    AssertPtr(pState);
     2709    AssertPtr(pState->pfnDecode);
     2710    AssertPtr(pState->pfnDecodeBlend);
     2711    Assert(pState->cDstChannels == PDMAudioPropsChannels(&pMixBuf->Props));
     2712    Assert(cMaxDstFrames > 0);
     2713    Assert(cMaxDstFrames <= pMixBuf->cFrames - pMixBuf->cUsed);
     2714    Assert(offDstFrame <= pMixBuf->cFrames);
     2715    AssertPtr(pvSrcBuf);
     2716    Assert(!(cbSrcBuf % pState->cbSrcFrame));
     2717    AssertPtr(pcDstFramesBlended);
     2718
     2719    /*
     2720     * Make start frame absolute.
     2721     */
     2722    offDstFrame = (pMixBuf->offWrite + offDstFrame) % pMixBuf->cFrames;
     2723
     2724    /*
     2725     * Hopefully no sample rate conversion is necessary...
     2726     */
     2727    if (pState->Rate.fNoConversionNeeded)
     2728    {
     2729        /* Figure out how much we should convert. */
     2730        Assert(cMaxDstFrames >= cbSrcBuf / pState->cbSrcFrame);
     2731        cMaxDstFrames       = RT_MIN(cMaxDstFrames, cbSrcBuf / pState->cbSrcFrame);
     2732        *pcDstFramesBlended = cMaxDstFrames;
     2733
     2734        /* First chunk. */
     2735        uint32_t const cDstFrames1 = RT_MIN(pMixBuf->cFrames - offDstFrame, cMaxDstFrames);
     2736        pState->pfnDecodeBlend(&pMixBuf->pFrames[offDstFrame].i64LSample, pvSrcBuf, cDstFrames1, pState);
     2737
     2738        /* Another chunk from the start of the mixing buffer? */
     2739        if (cMaxDstFrames > cDstFrames1)
     2740            pState->pfnDecodeBlend(&pMixBuf->pFrames[0].i64LSample, (uint8_t *)pvSrcBuf + cDstFrames1 * pState->cbSrcFrame,
     2741                                   cMaxDstFrames - cDstFrames1, pState);
     2742    }
     2743    else
     2744        audioMixBufBlendResampling(pMixBuf, pState, pvSrcBuf, cbSrcBuf, offDstFrame, cMaxDstFrames, pcDstFramesBlended);
    24332745}
    24342746
     
    24412753 * @param   pMixBuf     The mixing buffer.
    24422754 * @param   pState      The write state.
    2443  * @param   offFrames   Where to start writing silence relative to the current
     2755 * @param   offFrame    Where to start writing silence relative to the current
    24442756 *                      write position.
    24452757 * @param   cFrames     Number of frames of silence.
Note: See TracChangeset for help on using the changeset viewer.

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