VirtualBox

Changeset 89456 in vbox for trunk/src/VBox/ValidationKit


Ignore:
Timestamp:
Jun 2, 2021 8:43:16 AM (4 years ago)
Author:
vboxsync
Message:

Audio/ValKit: More code for recording tests. bugref:10008

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp

    r89442 r89456  
    246246*********************************************************************************************************************************/
    247247static int audioTestCombineParms(PAUDIOTESTPARMS pBaseParms, PAUDIOTESTPARMS pOverrideParms);
     248static int audioTestCreateStreamDefaultIn(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps);
    248249static int audioTestCreateStreamDefaultOut(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps);
    249250static int audioTestStreamDestroy(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream);
     
    439440        uint8_t  abBuf[_4K];
    440441
    441         const uint32_t cbPerMs       = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint);
    442               uint32_t cbToWrite     = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration);
    443 
    444         AudioTestSetObjAddMetadataStr(pObj, "buffer_size_ms=%RU32\n", pTstEnv->cMsBufferSize);
    445         AudioTestSetObjAddMetadataStr(pObj, "prebuf_size_ms=%RU32\n", pTstEnv->cMsPreBuffer);
    446         AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint);
    447 
    448         while (cbToWrite)
    449         {
    450             uint32_t cbWritten    = 0;
    451             uint32_t cbToGenerate = RT_MIN(cbToWrite, RT_MIN(cbPerMs, sizeof(abBuf)));
    452             Assert(cbToGenerate);
    453 
    454             rc = AudioTestToneGenerate(&TstTone, abBuf, cbToGenerate, &cbBuf);
    455             if (RT_SUCCESS(rc))
     442        const uint32_t cbPerSched = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint);
     443        AssertStmt(cbPerSched, rc = VERR_INVALID_PARAMETER);
     444              uint32_t cbToWrite  = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration);
     445        AssertStmt(cbToWrite,  rc = VERR_INVALID_PARAMETER);
     446
     447        if (RT_SUCCESS(rc))
     448        {
     449            AudioTestSetObjAddMetadataStr(pObj, "buffer_size_ms=%RU32\n", pTstEnv->cMsBufferSize);
     450            AudioTestSetObjAddMetadataStr(pObj, "prebuf_size_ms=%RU32\n", pTstEnv->cMsPreBuffer);
     451            AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint);
     452
     453            while (cbToWrite)
    456454            {
    457                 /* Write stuff to disk before trying to play it. Help analysis later. */
    458                 rc = AudioTestSetObjWrite(pObj, abBuf, cbBuf);
     455                uint32_t cbWritten    = 0;
     456                uint32_t cbToGenerate = RT_MIN(cbToWrite, RT_MIN(cbPerSched, sizeof(abBuf)));
     457                Assert(cbToGenerate);
     458
     459                rc = AudioTestToneGenerate(&TstTone, abBuf, cbToGenerate, &cbBuf);
    459460                if (RT_SUCCESS(rc))
    460                     rc = audioTestDriverStackStreamPlay(&pTstEnv->DrvStack, pStream->pStream,
    461                                                         abBuf, cbBuf, &cbWritten);
     461                {
     462                    /* Write stuff to disk before trying to play it. Help analysis later. */
     463                    rc = AudioTestSetObjWrite(pObj, abBuf, cbBuf);
     464                    if (RT_SUCCESS(rc))
     465                        rc = audioTestDriverStackStreamPlay(&pTstEnv->DrvStack, pStream->pStream,
     466                                                            abBuf, cbBuf, &cbWritten);
     467                }
     468
     469                if (RT_FAILURE(rc))
     470                    break;
     471
     472                RTThreadSleep(pTstEnv->cMsSchedulingHint);
     473
     474                RTTestPrintf(g_hTest, RTTESTLVL_DEBUG,  "Written %RU32 bytes\n", cbWritten);
     475
     476                Assert(cbToWrite >= cbWritten);
     477                cbToWrite -= cbWritten;
    462478            }
    463 
    464             if (RT_FAILURE(rc))
    465                 break;
    466 
    467             RTThreadSleep(pTstEnv->cMsSchedulingHint);
    468 
    469             Assert(cbToWrite >= cbWritten);
    470             cbToWrite -= cbWritten;
    471479        }
    472480    }
     
    478486        rc = rc2;
    479487
    480     RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Play tone done\n");
     488    if (RT_FAILURE(rc))
     489        RTTestFailed(g_hTest, "Playing tone done failed with %Rrc\n", rc);
     490
     491    return rc;
     492}
     493
     494/**
     495 * Records a test tone from a specific audio test stream.
     496 *
     497 * @returns VBox status code.
     498 * @param   pTstEnv             Test environment to use for running the test.
     499 * @param   pStream             Stream to use for recording the tone.
     500 * @param   pParms              Tone parameters to use.
     501 *
     502 * @note    Blocking function.
     503 */
     504static int audioTestRecordTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms)
     505{
     506    const char *pcszPathOut = pTstEnv->Set.szPathAbs;
     507
     508    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Recording test tone (for %RU32ms)\n", pParms->msDuration);
     509    RTTestPrintf(g_hTest, RTTESTLVL_DEBUG,  "Writing to '%s'\n", pcszPathOut);
     510
     511    /** @todo Use .WAV here? */
     512    PAUDIOTESTOBJ pObj;
     513    int rc = AudioTestSetObjCreateAndRegister(&pTstEnv->Set, "tone-rec.pcm", &pObj);
     514    AssertRCReturn(rc, rc);
     515
     516    if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream))
     517    {
     518        const uint32_t cbPerSched = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint);
     519        AssertStmt(cbPerSched, rc = VERR_INVALID_PARAMETER);
     520              uint32_t cbToRead   = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration);
     521        AssertStmt(cbToRead,   rc = VERR_INVALID_PARAMETER);
     522
     523        if (RT_SUCCESS(rc))
     524        {
     525            AudioTestSetObjAddMetadataStr(pObj, "buffer_size_ms=%RU32\n", pTstEnv->cMsBufferSize);
     526            AudioTestSetObjAddMetadataStr(pObj, "prebuf_size_ms=%RU32\n", pTstEnv->cMsPreBuffer);
     527            AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint);
     528
     529            uint8_t abBuf[_4K];
     530
     531            while (cbToRead)
     532            {
     533                const uint32_t cbChunk = RT_MIN(cbToRead, RT_MIN(cbPerSched, sizeof(abBuf)));
     534
     535                uint32_t cbRead = 0;
     536                rc = audioTestDriverStackStreamCapture(&pTstEnv->DrvStack, pStream->pStream, (void *)abBuf, cbChunk, &cbRead);
     537                if (RT_SUCCESS(rc))
     538                    rc = AudioTestSetObjWrite(pObj, abBuf, cbRead);
     539
     540                if (RT_FAILURE(rc))
     541                    break;
     542
     543                RTThreadSleep(pTstEnv->cMsSchedulingHint);
     544
     545                RTTestPrintf(g_hTest, RTTESTLVL_DEBUG,  "Read %RU32 bytes\n", cbRead);
     546
     547                Assert(cbToRead >= cbRead);
     548                cbToRead -= cbRead;
     549            }
     550        }
     551    }
     552    else
     553        rc = VERR_AUDIO_STREAM_NOT_READY;
     554
     555    int rc2 = AudioTestSetObjClose(pObj);
     556    if (RT_SUCCESS(rc))
     557        rc = rc2;
     558
     559    if (RT_FAILURE(rc))
     560        RTTestFailed(g_hTest, "Recording tone done failed with %Rrc\n", rc);
    481561
    482562    return rc;
     
    555635}
    556636
     637/** @copydoc ATSCALLBACKS::pfnToneRecord */
     638static DECLCALLBACK(int) audioTestSvcToneRecordCallback(void const *pvUser, PPDMAUDIOSTREAMCFG pStreamCfg, PAUDIOTESTTONEPARMS pToneParms)
     639{
     640    PATSCALLBACKCTX pCtx    = (PATSCALLBACKCTX)pvUser;
     641    PAUDIOTESTENV   pTstEnv = pCtx->pTstEnv;
     642
     643    const PAUDIOTESTSTREAM pTstStream = &pTstEnv->aStreams[0]; /** @todo Make this dynamic. */
     644
     645    int rc = audioTestCreateStreamDefaultIn(pTstEnv, pTstStream, &pStreamCfg->Props);
     646    if (RT_SUCCESS(rc))
     647    {
     648        AUDIOTESTPARMS TstParms;
     649        RT_ZERO(TstParms);
     650        TstParms.enmType  = AUDIOTESTTYPE_TESTTONE_RECORD;
     651        TstParms.enmDir   = PDMAUDIODIR_IN;
     652        TstParms.Props    = pStreamCfg->Props;
     653        pToneParms->Props = pStreamCfg->Props;
     654        TstParms.TestTone = *pToneParms;
     655
     656        PAUDIOTESTENTRY pTst;
     657        rc = AudioTestSetTestBegin(&pTstEnv->Set, "Recording test tone", &TstParms, &pTst);
     658        if (RT_SUCCESS(rc))
     659        {
     660            rc = audioTestRecordTone(pTstEnv, pTstStream, pToneParms);
     661            if (RT_SUCCESS(rc))
     662            {
     663                AudioTestSetTestDone(pTst);
     664            }
     665            else
     666                AudioTestSetTestFailed(pTst, rc, "Recording tone failed");
     667        }
     668
     669        int rc2 = audioTestStreamDestroy(pTstEnv, pTstStream);
     670        if (RT_SUCCESS(rc))
     671            rc = rc2;
     672    }
     673    else
     674        RTTestFailed(g_hTest, "Error creating input stream, rc=%Rrc\n", rc);
     675
     676    return rc;
     677}
    557678
    558679/*********************************************************************************************************************************
     
    627748        Callbacks.pfnTestSetEnd   = audioTestSvcTestSetEndCallback;
    628749        Callbacks.pfnTonePlay     = audioTestSvcTonePlayCallback;
     750        Callbacks.pfnToneRecord   = audioTestSvcToneRecordCallback;
    629751        Callbacks.pvUser          = &Ctx;
    630752
     
    8801002
    8811003/**
    882  * Records a test tone from a specific audio test stream.
    883  *
    884  * @returns VBox status code.
    885  * @param   pTstEnv             Test environment to use for running the test.
    886  * @param   pStream             Stream to use for recording the tone.
    887  * @param   pParms              Tone parameters to use.
    888  *
    889  * @note    Blocking function.
    890  */
    891 static int audioTestRecordTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms)
    892 {
    893     const char *pcszPathOut = pTstEnv->Set.szPathAbs;
    894 
    895     RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Recording test tone (for %RU32ms)\n", pParms->msDuration);
    896     RTTestPrintf(g_hTest, RTTESTLVL_DEBUG,  "Writing to '%s'\n", pcszPathOut);
    897 
    898     /** @todo Use .WAV here? */
    899     PAUDIOTESTOBJ pObj;
    900     int rc = AudioTestSetObjCreateAndRegister(&pTstEnv->Set, "tone-rec.pcm", &pObj);
    901     AssertRCReturn(rc, rc);
    902 
    903     if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream))
    904     {
    905         uint8_t abBuf[_4K];
    906 
    907         const uint64_t tsStartMs     = RTTimeMilliTS();
    908 
    909         do
    910         {
    911             uint32_t cbRead = 0;
    912             rc = audioTestDriverStackStreamCapture(&pTstEnv->DrvStack, pStream->pStream, (void *)abBuf, sizeof(abBuf), &cbRead);
    913             if (RT_SUCCESS(rc))
    914                 rc = AudioTestSetObjWrite(pObj, abBuf, cbRead);
    915 
    916             if (RT_FAILURE(rc))
    917                 break;
    918 
    919             if (RTTimeMilliTS() - tsStartMs >= pParms->msDuration)
    920                 break;
    921 
    922             RTThreadSleep(pTstEnv->cMsSchedulingHint);
    923 
    924         } while (RT_SUCCESS(rc));
    925     }
    926     else
    927         rc = VERR_AUDIO_STREAM_NOT_READY;
    928 
    929     int rc2 = AudioTestSetObjClose(pObj);
    930     if (RT_SUCCESS(rc))
    931         rc = rc2;
    932 
    933     return rc;
    934 }
    935 
    936 /**
    9371004 * Creates an audio default output (playback) test stream.
    9381005 * Convenience function.
     
    10221089            if (RT_SUCCESS(rc))
    10231090            {
    1024                AudioTestSetTestDone(pTst);
     1091                AudioTestSetTestDone(pTst);
    10251092            }
    10261093            else
     
    10541121    pTstParmsAcq->enmType     = AUDIOTESTTYPE_TESTTONE_RECORD;
    10551122
    1056     RT_ZERO(pTstParmsAcq->TestTone);
    1057     PDMAudioPropsInit(&pTstParmsAcq->TestTone.Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */);
     1123    PDMAudioPropsInit(&pTstParmsAcq->Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */);
    10581124
    10591125    pTstParmsAcq->enmDir      = PDMAUDIODIR_IN;
     
    10771143    int rc = VINF_SUCCESS;
    10781144
    1079     PAUDIOTESTSTREAM pStream = &pTstEnv->aStreams[0];
    1080 
    10811145    for (uint32_t i = 0; i < pTstParms->cIterations; i++)
    10821146    {
     
    10871151        if (RT_SUCCESS(rc))
    10881152        {
    1089             /** @todo  For now we're (re-)creating the recording stream for each iteration. Change that to be random. */
    1090             rc = audioTestCreateStreamDefaultIn(pTstEnv, pStream, &pTstParms->TestTone.Props);
    1091             if (RT_SUCCESS(rc))
    1092                 rc = audioTestRecordTone(pTstEnv, pStream, &pTstParms->TestTone);
    1093 
    1094             int rc2 = audioTestStreamDestroy(pTstEnv, pStream);
    1095             if (RT_SUCCESS(rc))
    1096                 rc = rc2;
    1097 
     1153            PDMAUDIOSTREAMCFG Cfg;
     1154            RT_ZERO(Cfg);
     1155            /** @todo Add more parameters here? */
     1156            Cfg.Props = pTstParms->Props;
     1157
     1158            rc = AudioTestSvcClientToneRecord(&pTstEnv->u.Host.Client, &Cfg, &pTstParms->TestTone);
    10981159            if (RT_SUCCESS(rc))
    10991160            {
    1100                AudioTestSetTestDone(pTst);
     1161                AudioTestSetTestDone(pTst);
    11011162            }
    11021163            else
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