VirtualBox

Ignore:
Timestamp:
Apr 27, 2015 8:01:05 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
99809
Message:

Audio: Fixed minor format conversion errors, added a testcase (16-bit signed test only so far).

File:
1 edited

Legend:

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

    r55449 r55462  
    236236}
    237237
     238static int tstConversion(RTTEST hTest)
     239{
     240    unsigned        i;
     241    uint32_t        cBufSize = 256;
     242    PDMPCMPROPS     props;
     243
     244
     245    RTTestSubF(hTest, "Sample conversion");
     246
     247    PDMAUDIOSTREAMCFG cfg_p =
     248    {
     249        44100,                   /* Hz */
     250        1                        /* Channels */,
     251        AUD_FMT_S16              /* Format */,
     252        PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
     253    };
     254
     255    int rc = drvAudioStreamCfgToProps(&cfg_p, &props);
     256    AssertRC(rc);
     257
     258    PDMAUDIOMIXBUF parent;
     259    RTTESTI_CHECK_RC_OK(audioMixBufInit(&parent, "Parent", &props, cBufSize));
     260
     261    /* Child uses half the sample rate; that ensures the mixing engine can't
     262     * take shortcuts and performs conversion. Because conversion to double
     263     * the sample rate effectively inserts one additional sample between every
     264     * two source samples, N source samples will be converted to N * 2 - 1
     265     * samples. However, the last source sample will be saved for later
     266     * interpolation and not immediately output.
     267     */
     268    PDMAUDIOSTREAMCFG cfg_c =   /* Upmixing to parent */
     269    {
     270        22050,                   /* Hz */
     271        1                        /* Channels */,
     272        AUD_FMT_S16              /* Format */,
     273        PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
     274    };
     275
     276    rc = drvAudioStreamCfgToProps(&cfg_c, &props);
     277    AssertRC(rc);
     278
     279    PDMAUDIOMIXBUF child;
     280    RTTESTI_CHECK_RC_OK(audioMixBufInit(&child, "Child", &props, cBufSize));
     281    RTTESTI_CHECK_RC_OK(audioMixBufLinkTo(&child, &parent));
     282
     283    /*
     284     * Writing + mixing from child -> parent, sequential.
     285     */
     286    uint32_t cbBuf = 256;
     287    char pvBuf[256];
     288    int16_t samples[16] = { 0xAA, 0xBB, INT16_MIN, INT16_MIN + 1, INT16_MIN / 2, -3, -2, -1,
     289                            0, 1, 2, 3, INT16_MAX / 2, INT16_MAX - 1, INT16_MAX, 0 };
     290    uint32_t read, written, mixed, temp;
     291
     292    uint32_t cChildFree     = cBufSize;
     293    uint32_t cChildMixed    = 0;
     294    uint32_t cSamplesChild  = 16;
     295    uint32_t cSamplesParent = cSamplesChild * 2 - 2;
     296    uint32_t cSamplesRead   = 0;
     297
     298    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch\n", cfg_c.uHz, cfg_c.cChannels);
     299    RTTESTI_CHECK_RC_OK(audioMixBufWriteAt(&child, 0, &samples, sizeof(samples), &written));
     300    RTTESTI_CHECK_MSG(written == cSamplesChild, ("Child: Expected %RU32 written samples, got %RU32\n", cSamplesChild, written));
     301    RTTESTI_CHECK_RC_OK(audioMixBufMixToParent(&child, written, &mixed));
     302    temp = audioMixBufProcessed(&parent);
     303    RTTESTI_CHECK_MSG(audioMixBufMixed(&child) == temp, ("Child: Expected %RU32 mixed samples, got %RU32\n", audioMixBufMixed(&child), temp));
     304
     305    RTTESTI_CHECK(audioMixBufProcessed(&parent) == audioMixBufMixed(&child));
     306
     307    for (;;)
     308    {
     309        RTTESTI_CHECK_RC_OK_BREAK(audioMixBufReadCirc(&parent, pvBuf, cbBuf, &read));
     310        if (!read)
     311            break;
     312        cSamplesRead += read;
     313        audioMixBufFinish(&parent, read);
     314    }
     315    RTTESTI_CHECK_MSG(cSamplesRead == cSamplesParent, ("Parent: Expected %RU32 mixed samples, got %RU32\n", cSamplesParent, cSamplesRead));
     316
     317    /* Check that the samples came out unharmed. Every other sample is interpolated and we ignore it. */
     318    int16_t *pSrc16 = &samples[0];
     319    int16_t *pDst16 = (int16_t *)pvBuf;
     320
     321    for (i = 0; i < cSamplesChild; ++i)
     322    {
     323        RTTESTI_CHECK_MSG(*pSrc16 == *pDst16, ("index %u: Dst=%d, Src=%d\n", i, *pDst16, *pSrc16));
     324        pSrc16 += 1;
     325        pDst16 += 2;
     326    }
     327
     328    RTTESTI_CHECK(audioMixBufProcessed(&parent) == 0);
     329    RTTESTI_CHECK(audioMixBufMixed(&child) == 0);
     330
     331    return RTTestSubErrorCount(hTest) ? VERR_GENERAL_FAILURE : VINF_SUCCESS;
     332}
     333
    238334int main(int argc, char **argv)
    239335{
     
    252348    if (RT_SUCCESS(rc))
    253349        rc = tstParentChild(hTest);
     350    if (RT_SUCCESS(rc))
     351        rc = tstConversion(hTest);
    254352
    255353    /*
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