VirtualBox

Ignore:
Timestamp:
Apr 28, 2015 4:26:12 PM (10 years ago)
Author:
vboxsync
Message:

Audio: Extended testcase.

File:
1 edited

Legend:

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

    r55486 r55492  
    242242}
    243243
    244 static int tstConversion(RTTEST hTest)
     244/* Test 8-bit sample conversion (8-bit -> internal -> 8-bit). */
     245static int tstConversion8(RTTEST hTest)
    245246{
    246247    unsigned        i;
     
    255256        44100,                   /* Hz */
    256257        1                        /* Channels */,
    257         AUD_FMT_S16              /* Format */,
     258        AUD_FMT_U8               /* Format */,
    258259        PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
    259260    };
     
    276277        22050,                   /* Hz */
    277278        1                        /* Channels */,
    278         AUD_FMT_S16              /* Format */,
     279        AUD_FMT_U8               /* Format */,
    279280        PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
    280281    };
     
    287288    RTTESTI_CHECK_RC_OK(audioMixBufLinkTo(&child, &parent));
    288289
     290    /* 8-bit unsigned samples. Often used with SB16 device. */
     291    uint8_t     samples[16]  = { 0xAA, 0xBB, 0, 1, 43, 125, 126, 127,
     292                                 128, 129, 130, 131, 132, UINT8_MAX - 1, UINT8_MAX, 0 };
     293
    289294    /*
    290295     * Writing + mixing from child -> parent, sequential.
    291296     */
    292     uint32_t cbBuf = 256;
    293     char pvBuf[256];
    294     int16_t samples[16] = { 0xAA, 0xBB, INT16_MIN, INT16_MIN + 1, INT16_MIN / 2, -3, -2, -1,
    295                             0, 1, 2, 3, INT16_MAX / 2, INT16_MAX - 1, INT16_MAX, 0 };
    296     uint32_t read, written, mixed, temp;
     297    uint32_t    cbBuf = 256;
     298    char        achBuf[256];
     299    uint32_t    read, written, mixed, temp;
    297300
    298301    uint32_t cChildFree     = cBufSize;
     
    302305    uint32_t cSamplesRead   = 0;
    303306
    304     RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch\n", cfg_c.uHz, cfg_c.cChannels);
     307    /**** 8-bit unsigned samples ****/
     308    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 8-bit\n", cfg_c.uHz, cfg_c.cChannels);
    305309    RTTESTI_CHECK_RC_OK(audioMixBufWriteAt(&child, 0, &samples, sizeof(samples), &written));
    306310    RTTESTI_CHECK_MSG(written == cSamplesChild, ("Child: Expected %RU32 written samples, got %RU32\n", cSamplesChild, written));
     
    313317    for (;;)
    314318    {
    315         RTTESTI_CHECK_RC_OK_BREAK(audioMixBufReadCirc(&parent, pvBuf, cbBuf, &read));
     319        RTTESTI_CHECK_RC_OK_BREAK(audioMixBufReadCirc(&parent, achBuf, cbBuf, &read));
    316320        if (!read)
    317321            break;
     
    322326
    323327    /* Check that the samples came out unharmed. Every other sample is interpolated and we ignore it. */
     328    /* NB: This also checks that the default volume setting is 0dB attenuation. */
     329    uint8_t *pSrc8 = &samples[0];
     330    uint8_t *pDst8 = (uint8_t *)achBuf;
     331
     332    for (i = 0; i < cSamplesChild - 1; ++i)
     333    {
     334        RTTESTI_CHECK_MSG(*pSrc8 == *pDst8, ("index %u: Dst=%d, Src=%d\n", i, *pDst8, *pSrc8));
     335        pSrc8 += 1;
     336        pDst8 += 2;
     337    }
     338
     339    RTTESTI_CHECK(audioMixBufProcessed(&parent) == 0);
     340    RTTESTI_CHECK(audioMixBufMixed(&child) == 0);
     341
     342
     343    return RTTestSubErrorCount(hTest) ? VERR_GENERAL_FAILURE : VINF_SUCCESS;
     344}
     345
     346/* Test 16-bit sample conversion (16-bit -> internal -> 16-bit). */
     347static int tstConversion16(RTTEST hTest)
     348{
     349    unsigned        i;
     350    uint32_t        cBufSize = 256;
     351    PDMPCMPROPS     props;
     352
     353
     354    RTTestSubF(hTest, "Sample conversion 16-bit");
     355
     356    PDMAUDIOSTREAMCFG cfg_p =
     357    {
     358        44100,                   /* Hz */
     359        1                        /* Channels */,
     360        AUD_FMT_S16              /* Format */,
     361        PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
     362    };
     363
     364    int rc = drvAudioStreamCfgToProps(&cfg_p, &props);
     365    AssertRC(rc);
     366
     367    PDMAUDIOMIXBUF parent;
     368    RTTESTI_CHECK_RC_OK(audioMixBufInit(&parent, "Parent", &props, cBufSize));
     369
     370    PDMAUDIOSTREAMCFG cfg_c =   /* Upmixing to parent */
     371    {
     372        22050,                   /* Hz */
     373        1                        /* Channels */,
     374        AUD_FMT_S16              /* Format */,
     375        PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
     376    };
     377
     378    rc = drvAudioStreamCfgToProps(&cfg_c, &props);
     379    AssertRC(rc);
     380
     381    PDMAUDIOMIXBUF child;
     382    RTTESTI_CHECK_RC_OK(audioMixBufInit(&child, "Child", &props, cBufSize));
     383    RTTESTI_CHECK_RC_OK(audioMixBufLinkTo(&child, &parent));
     384
     385    /* 16-bit signed. More or less exclusively used as output, and usually as input, too. */
     386    int16_t     samples[16] = { 0xAA, 0xBB, INT16_MIN, INT16_MIN + 1, INT16_MIN / 2, -3, -2, -1,
     387                                0, 1, 2, 3, INT16_MAX / 2, INT16_MAX - 1, INT16_MAX, 0 };
     388
     389    /*
     390     * Writing + mixing from child -> parent, sequential.
     391     */
     392    uint32_t    cbBuf = 256;
     393    char        achBuf[256];
     394    uint32_t    read, written, mixed, temp;
     395
     396    uint32_t cChildFree     = cBufSize;
     397    uint32_t cChildMixed    = 0;
     398    uint32_t cSamplesChild  = 16;
     399    uint32_t cSamplesParent = cSamplesChild * 2 - 2;
     400    uint32_t cSamplesRead   = 0;
     401
     402    /**** 16-bit signed samples ****/
     403    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 16-bit\n", cfg_c.uHz, cfg_c.cChannels);
     404    RTTESTI_CHECK_RC_OK(audioMixBufWriteAt(&child, 0, &samples, sizeof(samples), &written));
     405    RTTESTI_CHECK_MSG(written == cSamplesChild, ("Child: Expected %RU32 written samples, got %RU32\n", cSamplesChild, written));
     406    RTTESTI_CHECK_RC_OK(audioMixBufMixToParent(&child, written, &mixed));
     407    temp = audioMixBufProcessed(&parent);
     408    RTTESTI_CHECK_MSG(audioMixBufMixed(&child) == temp, ("Child: Expected %RU32 mixed samples, got %RU32\n", audioMixBufMixed(&child), temp));
     409
     410    RTTESTI_CHECK(audioMixBufProcessed(&parent) == audioMixBufMixed(&child));
     411
     412    for (;;)
     413    {
     414        RTTESTI_CHECK_RC_OK_BREAK(audioMixBufReadCirc(&parent, achBuf, cbBuf, &read));
     415        if (!read)
     416            break;
     417        cSamplesRead += read;
     418        audioMixBufFinish(&parent, read);
     419    }
     420    RTTESTI_CHECK_MSG(cSamplesRead == cSamplesParent, ("Parent: Expected %RU32 mixed samples, got %RU32\n", cSamplesParent, cSamplesRead));
     421
     422    /* Check that the samples came out unharmed. Every other sample is interpolated and we ignore it. */
     423    /* NB: This also checks that the default volume setting is 0dB attenuation. */
    324424    int16_t *pSrc16 = &samples[0];
    325     int16_t *pDst16 = (int16_t *)pvBuf;
     425    int16_t *pDst16 = (int16_t *)achBuf;
    326426
    327427    for (i = 0; i < cSamplesChild - 1; ++i)
     
    341441}
    342442
     443/* Test volume control. */
     444static int tstVolume(RTTEST hTest)
     445{
     446    unsigned        i;
     447    uint32_t        cBufSize = 256;
     448    PDMPCMPROPS     props;
     449
     450
     451    RTTestSubF(hTest, "Volume control");
     452
     453    /* Same for parent/child. */
     454    PDMAUDIOSTREAMCFG cfg =
     455    {
     456        44100,                   /* Hz */
     457        2                        /* Channels */,
     458        AUD_FMT_S16              /* Format */,
     459        PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
     460    };
     461
     462    int rc = drvAudioStreamCfgToProps(&cfg, &props);
     463    AssertRC(rc);
     464
     465    PDMAUDIOVOLUME vol = { false, 0, 0 };   /* Not muted. */
     466    PDMAUDIOMIXBUF parent;
     467    RTTESTI_CHECK_RC_OK(audioMixBufInit(&parent, "Parent", &props, cBufSize));
     468
     469    PDMAUDIOMIXBUF child;
     470    RTTESTI_CHECK_RC_OK(audioMixBufInit(&child, "Child", &props, cBufSize));
     471    RTTESTI_CHECK_RC_OK(audioMixBufLinkTo(&child, &parent));
     472
     473    /* A few 16-bit signed samples. */
     474    int16_t     samples[16] = { INT16_MIN, INT16_MIN + 1, -128, -64, -4, -1, 0, 1,
     475                                2, 255, 256, INT16_MAX / 2, INT16_MAX - 2, INT16_MAX - 1, INT16_MAX, 0 };
     476
     477    /*
     478     * Writing + mixing from child -> parent.
     479     */
     480    uint32_t    cbBuf = 256;
     481    char        achBuf[256];
     482    uint32_t    read, written, mixed;
     483
     484    uint32_t cChildFree     = cBufSize;
     485    uint32_t cChildMixed    = 0;
     486    uint32_t cSamplesChild  = 8;
     487    uint32_t cSamplesParent = cSamplesChild;
     488    uint32_t cSamplesRead;
     489    int16_t *pSrc16;
     490    int16_t *pDst16;
     491
     492    /**** Volume control test ****/
     493    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Volume control test %uHz %uch \n", cfg.uHz, cfg.cChannels);
     494
     495    /* 1) Full volume/0dB attenuation (255). */
     496    vol.uLeft = vol.uRight = 255;
     497    audioMixBufSetVolume(&child, &vol);
     498
     499    RTTESTI_CHECK_RC_OK(audioMixBufWriteAt(&child, 0, &samples, sizeof(samples), &written));
     500    RTTESTI_CHECK_MSG(written == cSamplesChild, ("Child: Expected %RU32 written samples, got %RU32\n", cSamplesChild, written));
     501    RTTESTI_CHECK_RC_OK(audioMixBufMixToParent(&child, written, &mixed));
     502
     503    cSamplesRead = 0;
     504    for (;;)
     505    {
     506        RTTESTI_CHECK_RC_OK_BREAK(audioMixBufReadCirc(&parent, achBuf, cbBuf, &read));
     507        if (!read)
     508            break;
     509        cSamplesRead += read;
     510        audioMixBufFinish(&parent, read);
     511    }
     512    RTTESTI_CHECK_MSG(cSamplesRead == cSamplesParent, ("Parent: Expected %RU32 mixed samples, got %RU32\n", cSamplesParent, cSamplesRead));
     513
     514    /* Check that at 0dB the samples came out unharmed. */
     515    pSrc16 = &samples[0];
     516    pDst16 = (int16_t *)achBuf;
     517
     518    for (i = 0; i < cSamplesParent * 2 /* stereo */; ++i)
     519    {
     520        RTTESTI_CHECK_MSG(*pSrc16 == *pDst16, ("index %u: Dst=%d, Src=%d\n", i, *pDst16, *pSrc16));
     521        ++pSrc16;
     522        ++pDst16;
     523    }
     524    audioMixBufReset(&child);
     525
     526    /* 2) Half volume/-6dB attenuation (16 steps down). */
     527    vol.uLeft = vol.uRight = 255 - 16;
     528    audioMixBufSetVolume(&child, &vol);
     529
     530    RTTESTI_CHECK_RC_OK(audioMixBufWriteAt(&child, 0, &samples, sizeof(samples), &written));
     531    RTTESTI_CHECK_MSG(written == cSamplesChild, ("Child: Expected %RU32 written samples, got %RU32\n", cSamplesChild, written));
     532    RTTESTI_CHECK_RC_OK(audioMixBufMixToParent(&child, written, &mixed));
     533
     534    cSamplesRead = 0;
     535    for (;;)
     536    {
     537        RTTESTI_CHECK_RC_OK_BREAK(audioMixBufReadCirc(&parent, achBuf, cbBuf, &read));
     538        if (!read)
     539            break;
     540        cSamplesRead += read;
     541        audioMixBufFinish(&parent, read);
     542    }
     543    RTTESTI_CHECK_MSG(cSamplesRead == cSamplesParent, ("Parent: Expected %RU32 mixed samples, got %RU32\n", cSamplesParent, cSamplesRead));
     544
     545    /* Check that at -6dB the sample values are halved. */
     546    pSrc16 = &samples[0];
     547    pDst16 = (int16_t *)achBuf;
     548
     549    for (i = 0; i < cSamplesParent * 2 /* stereo */; ++i)
     550    {
     551        /* Watch out! For negative values, x >> 1 is not the same as x / 2. */
     552        RTTESTI_CHECK_MSG(*pSrc16 >> 1 == *pDst16, ("index %u: Dst=%d, Src=%d\n", i, *pDst16, *pSrc16));
     553        ++pSrc16;
     554        ++pDst16;
     555    }
     556
     557    return RTTestSubErrorCount(hTest) ? VERR_GENERAL_FAILURE : VINF_SUCCESS;
     558}
     559
    343560int main(int argc, char **argv)
    344561{
     
    358575        rc = tstParentChild(hTest);
    359576    if (RT_SUCCESS(rc))
    360         rc = tstConversion(hTest);
     577        rc = tstConversion8(hTest);
     578    if (RT_SUCCESS(rc))
     579        rc = tstConversion16(hTest);
     580    if (RT_SUCCESS(rc))
     581        rc = tstVolume(hTest);
    361582
    362583    /*
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