VirtualBox

Changeset 88312 in vbox


Ignore:
Timestamp:
Mar 29, 2021 1:03:54 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
143531
Message:

tstAudioMixBuffer: Test downsampling. bugref:9890

File:
1 edited

Legend:

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

    r88269 r88312  
    3232#include "../AudioMixBuffer.h"
    3333#include "../AudioHlp.h"
     34
     35#include <math.h> /* sin, M_PI */
    3436
    3537
     
    305307static int tstParentChild(RTTEST hTest)
    306308{
     309    RTTestSub(hTest, "2 Children -> Parent (AudioMixBufWriteAt)");
     310
    307311    uint32_t cParentBufSize = RTRandU32Ex(_1K /* Min */, _16K /* Max */); /* Enough room for random sizes */
    308312
     
    374378     * Using AudioMixBufWriteAt for writing to children.
    375379     */
    376     RTTestSub(hTest, "2 Children -> Parent (AudioMixBufWriteAt)");
    377 
    378380    uint32_t cChildrenSamplesMixedTotal = 0;
    379381
     
    444446}
    445447
     448
     449static void tstDownsampling(RTTEST hTest, uint32_t uFromHz, uint32_t uToHz)
     450{
     451    RTTestSubF(hTest, "Downsampling %u to %u Hz (S16)", uFromHz, uToHz);
     452
     453    struct { int16_t l, r; }
     454        aSrcFrames[4096],
     455        aDstFrames[4096];
     456
     457    /* Parent (destination) buffer is xxxHz 2ch S16 */
     458    uint32_t const         cFramesParent = RTRandU32Ex(16, RT_ELEMENTS(aDstFrames));
     459    PDMAUDIOPCMPROPS const CfgDst = PDMAUDIOPCMPROPS_INITIALIZER(2 /*cbSample*/, true /*fSigned*/, 2 /*ch*/, uToHz, false /*fSwap*/);
     460    RTTESTI_CHECK(AudioHlpPcmPropsAreValid(&CfgDst));
     461    PDMAUDIOMIXBUF Parent;
     462    RTTESTI_CHECK_RC_OK_RETV(AudioMixBufInit(&Parent, "ParentDownsampling", &CfgDst, cFramesParent));
     463
     464    /* Child (source) buffer is yyykHz 2ch S16 */
     465    PDMAUDIOPCMPROPS const CfgSrc = PDMAUDIOPCMPROPS_INITIALIZER(2 /*cbSample*/, true /*fSigned*/, 2 /*ch*/, uFromHz, false /*fSwap*/);
     466    RTTESTI_CHECK(AudioHlpPcmPropsAreValid(&CfgSrc));
     467    uint32_t const cFramesChild = RTRandU32Ex(32, RT_ELEMENTS(aSrcFrames));
     468    PDMAUDIOMIXBUF Child;
     469    RTTESTI_CHECK_RC_OK_RETV(AudioMixBufInit(&Child, "ChildDownsampling", &CfgSrc, cFramesChild));
     470    RTTESTI_CHECK_RC_OK_RETV(AudioMixBufLinkTo(&Child, &Parent));
     471
     472    /*
     473     * Test parameters.
     474     */
     475    uint32_t const cMaxSrcFrames = RT_MIN(cFramesParent * uFromHz / uToHz - 1, cFramesChild);
     476    uint32_t const cIterations   = RTRandU32Ex(4, 128);
     477    RTTestErrContext(hTest, "cFramesParent=%RU32 cFramesChild=%RU32 cMaxSrcFrames=%RU32 cIterations=%RU32",
     478                     cFramesParent, cFramesChild, cMaxSrcFrames, cIterations);
     479    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "cFramesParent=%RU32 cFramesChild=%RU32 cMaxSrcFrames=%RU32 cIterations=%RU32\n",
     480                 cFramesParent, cFramesChild, cMaxSrcFrames, cIterations);
     481
     482    /*
     483     * We generate a simple "A" sine wave as input.
     484     */
     485    uint32_t iSrcFrame = 0;
     486    uint32_t iDstFrame = 0;
     487    double   rdFixed = 2.0 * M_PI * 440.0 /* A */ / PDMAudioPropsHz(&CfgSrc); /* Fixed sin() input. */
     488    for (uint32_t i = 0; i < cIterations; i++)
     489    {
     490        RTTestPrintf(hTest, RTTESTLVL_DEBUG, "i=%RU32\n", i);
     491
     492        /*
     493         * Generate source frames and write them.
     494         */
     495        uint32_t const cSrcFrames = i < cIterations / 2
     496                                  ? RTRandU32Ex(2, cMaxSrcFrames) & ~(uint32_t)1
     497                                  : RTRandU32Ex(1, cMaxSrcFrames - 1) | 1;
     498        for (uint32_t j = 0; j < cSrcFrames; j++, iSrcFrame++)
     499            aSrcFrames[j].r = aSrcFrames[j].l = 32760 /*Amplitude*/ * sin(rdFixed * iSrcFrame);
     500
     501        uint32_t cSrcFramesWritten = UINT32_MAX / 2;
     502        RTTESTI_CHECK_RC_OK_BREAK(AudioMixBufWriteAt(&Child, 0, &aSrcFrames, cSrcFrames * sizeof(aSrcFrames[0]),
     503                                                     &cSrcFramesWritten));
     504        RTTESTI_CHECK_MSG_BREAK(cSrcFrames == cSrcFramesWritten,
     505                                ("cSrcFrames=%RU32 vs cSrcFramesWritten=%RU32\n", cSrcFrames, cSrcFramesWritten));
     506
     507        /*
     508         * Mix them.
     509         */
     510        uint32_t cSrcFramesMixed = UINT32_MAX / 2;
     511        RTTESTI_CHECK_RC_OK_BREAK(AudioMixBufMixToParent(&Child, cSrcFramesWritten, &cSrcFramesMixed));
     512        RTTESTI_CHECK_MSG(AudioMixBufUsed(&Child) == 0, ("%RU32\n", AudioMixBufUsed(&Child)));
     513        RTTESTI_CHECK_MSG_BREAK(cSrcFramesWritten == cSrcFramesMixed,
     514                                ("cSrcFramesWritten=%RU32 cSrcFramesMixed=%RU32\n", cSrcFramesWritten, cSrcFramesMixed));
     515        RTTESTI_CHECK_MSG_BREAK(AudioMixBufUsed(&Child) == 0, ("%RU32\n", AudioMixBufUsed(&Child)));
     516
     517        /*
     518         * Read out the parent buffer.
     519         */
     520        uint32_t cDstFrames = AudioMixBufUsed(&Parent);
     521        while (cDstFrames > 0)
     522        {
     523            uint32_t cFramesRead = UINT32_MAX / 2;
     524            RTTESTI_CHECK_RC_OK_BREAK(AudioMixBufAcquireReadBlock(&Parent, aDstFrames, sizeof(aDstFrames), &cFramesRead));
     525            RTTESTI_CHECK_MSG(cFramesRead > 0 && cFramesRead <= cDstFrames,
     526                              ("cFramesRead=%RU32 cDstFrames=%RU32\n", cFramesRead, cDstFrames));
     527
     528            AudioMixBufReleaseReadBlock(&Parent, cFramesRead);
     529            AudioMixBufFinish(&Parent, cFramesRead);
     530
     531            iDstFrame  += cFramesRead;
     532            cDstFrames -= cFramesRead;
     533            RTTESTI_CHECK(AudioMixBufUsed(&Parent) == cDstFrames);
     534        }
     535    }
     536
     537    RTTESTI_CHECK(AudioMixBufUsed(&Parent) == 0);
     538    RTTESTI_CHECK(AudioMixBufLive(&Child) == 0);
     539    uint32_t const cDstMinExpect =  (uint64_t)iSrcFrame * uToHz                / uFromHz;
     540    uint32_t const cDstMaxExpect = ((uint64_t)iSrcFrame * uToHz + uFromHz - 1) / uFromHz;
     541    RTTESTI_CHECK_MSG(iDstFrame == cDstMinExpect || iDstFrame == cDstMaxExpect,
     542                      ("iSrcFrame=%#x -> %#x,%#x; iDstFrame=%#x\n", iSrcFrame, cDstMinExpect, cDstMaxExpect, iDstFrame));
     543
     544    AudioMixBufDestroy(&Parent);
     545    AudioMixBufDestroy(&Child);
     546}
     547
     548
    446549/* Test 8-bit sample conversion (8-bit -> internal -> 8-bit). */
    447550static int tstConversion8(RTTEST hTest)
    448551{
     552    RTTestSub(hTest, "Convert 22kHz/U8 to 44.1kHz/S16 (mono)");
    449553    unsigned         i;
    450554    uint32_t         cBufSize = 256;
    451555
    452     RTTestSub(hTest, "Sample conversion (U8)");
    453556
    454557    /* 44100Hz, 1 Channel, U8 */
     
    550653static int tstConversion16(RTTEST hTest)
    551654{
     655    RTTestSub(hTest, "Convert 22kHz/S16 to 44.1kHz/S16 (mono)");
    552656    unsigned         i;
    553657    uint32_t         cBufSize = 256;
    554 
    555     RTTestSub(hTest, "Sample conversion (S16)");
    556658
    557659    /* 44100Hz, 1 Channel, S16 */
     
    644746static int tstVolume(RTTEST hTest)
    645747{
    646     unsigned         i;
     748    RTTestSub(hTest, "Volume control (44.1kHz S16 2ch)");
    647749    uint32_t         cBufSize = 256;
    648 
    649     RTTestSub(hTest, "Volume control");
    650750
    651751    /* Same for parent/child. */
     
    713813    pDst16 = (int16_t *)achBuf;
    714814
    715     for (i = 0; i < cFramesParent * 2 /* stereo */; ++i)
     815    for (unsigned i = 0; i < cFramesParent * 2 /* stereo */; ++i)
    716816    {
    717817        RTTESTI_CHECK_MSG(*pSrc16 == *pDst16, ("index %u: Dst=%d, Src=%d\n", i, *pDst16, *pSrc16));
     
    745845    pDst16 = (int16_t *)achBuf;
    746846
    747     for (i = 0; i < cFramesParent * 2 /* stereo */; ++i)
     847    for (unsigned i = 0; i < cFramesParent * 2 /* stereo */; ++i)
    748848    {
    749849        /* Watch out! For negative values, x >> 1 is not the same as x / 2. */
     
    778878    tstConversion16(hTest);
    779879    tstVolume(hTest);
     880    tstDownsampling(hTest, 44100, 22050);
     881    tstDownsampling(hTest, 48000, 44100);
     882    tstDownsampling(hTest, 48000, 22050);
     883    tstDownsampling(hTest, 48000, 11000);
    780884
    781885    /*
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