VirtualBox

Changeset 89890 in vbox


Ignore:
Timestamp:
Jun 24, 2021 3:56:05 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
145348
Message:

Audio/ValKit: More code for audio verification. bugref:10008

Location:
trunk/src/VBox
Files:
7 edited

Legend:

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

    r89889 r89890  
    128128
    129129/**
    130  * Returns a random test tone frequency.
    131  */
    132 DECLINLINE(double) audioTestToneGetRandomFreq(void)
    133 {
    134     return s_aAudioTestToneFreqsHz[RTRandU32Ex(0, RT_ELEMENTS(s_aAudioTestToneFreqsHz) - 1)];
    135 }
    136 
    137 /**
    138130 * Initializes a test tone with a specific frequency (in Hz).
    139131 *
     
    147139{
    148140    if (dbFreq == 0.0)
    149         dbFreq = audioTestToneGetRandomFreq();
     141        dbFreq = AudioTestToneGetRandomFreq();
    150142
    151143    pTone->rdFreqHz = dbFreq;
     
    290282
    291283/**
    292  * Initializes an audio test tone parameters struct with random values.
    293  * @param   pToneParams         Test tone parameters to initialize.
    294  * @param   pProps              PCM properties to use for the test tone.
    295  */
    296 int AudioTestToneParamsInitRandom(PAUDIOTESTTONEPARMS pToneParams, PPDMAUDIOPCMPROPS pProps)
    297 {
    298     AssertReturn(PDMAudioPropsAreValid(pProps), VERR_INVALID_PARAMETER);
    299 
    300     memcpy(&pToneParams->Props, pProps, sizeof(PDMAUDIOPCMPROPS));
    301 
    302     /** @todo Make this a bit more sophisticated later, e.g. muting and prequel/sequel are not very balanced. */
    303 
    304     pToneParams->dbFreqHz       = audioTestToneGetRandomFreq();
    305     pToneParams->msPrequel      = RTRandU32Ex(0, RT_MS_5SEC);
    306 #ifdef DEBUG_andy
    307     pToneParams->msDuration     = RTRandU32Ex(0, RT_MS_1SEC);
    308 #else
    309     pToneParams->msDuration     = RTRandU32Ex(0, RT_MS_10SEC); /** @todo Probably a bit too long, but let's see. */
    310 #endif
    311     pToneParams->msSequel       = RTRandU32Ex(0, RT_MS_5SEC);
    312     pToneParams->uVolumePercent = RTRandU32Ex(0, 100);
    313 
    314     return VINF_SUCCESS;
     284 * Returns a random test tone frequency.
     285 */
     286double AudioTestToneGetRandomFreq(void)
     287{
     288    return s_aAudioTestToneFreqsHz[RTRandU32Ex(0, RT_ELEMENTS(s_aAudioTestToneFreqsHz) - 1)];
    315289}
    316290
     
    14111385
    14121386/**
     1387 * Returns whether a test set has running (active) tests or not.
     1388 *
     1389 * @returns \c true if it has running tests, or \c false if not.
     1390 * @param   pSet                Test set to return status for.
     1391 */
     1392bool AudioTestSetIsRunning(PAUDIOTESTSET pSet)
     1393{
     1394    return (pSet->cTestsRunning > 0);
     1395}
     1396
     1397/**
    14131398 * Unpacks a formerly packed audio test set.
    14141399 *
     
    17131698    rc = RTFileQuerySize(pObjB->File.hFile, &cbSizeB);
    17141699    AssertRCReturn(rc, rc);
    1715     if (   cbSizeA != cbSizeB
    1716         || !audioTestFilesCompareBinary(pObjA->File.hFile, pObjB->File.hFile, cbSizeA))
     1700
     1701    if (!cbSizeA)
     1702    {
     1703        int rc2 = audioTestErrorDescAdd(pVerJob->pErr, pVerJob->idxTest, "File '%s' is empty\n", pObjA->szName);
     1704        AssertRC(rc2);
     1705    }
     1706
     1707    if (!cbSizeB)
     1708    {
     1709        int rc2 = audioTestErrorDescAdd(pVerJob->pErr, pVerJob->idxTest, "File '%s' is empty\n", pObjB->szName);
     1710        AssertRC(rc2);
     1711    }
     1712
     1713    if (cbSizeA != cbSizeB)
     1714    {
     1715        int rc2 = audioTestErrorDescAdd(pVerJob->pErr, pVerJob->idxTest, "File '%s' is %zu bytes %s than '%s'\n",
     1716                                        pObjA->szName,
     1717                                        cbSizeA > cbSizeB ? cbSizeA - cbSizeB : cbSizeB - cbSizeA,
     1718                                        cbSizeA > cbSizeB ? "bigger" : "smaller",
     1719                                        pObjB->szName);
     1720        AssertRC(rc2);
     1721    }
     1722    else if (audioTestFilesCompareBinary(pObjA->File.hFile, pObjB->File.hFile, cbSizeA))
    17171723    {
    17181724        /** @todo Add more sophisticated stuff here. */
    17191725
    1720         int rc2 = audioTestErrorDescAdd(pVerJob->pErr, pVerJob->idxTest, "Files '%s' and '%s' don't match\n", szObjA, szObjB);
     1726        int rc2 = audioTestErrorDescAdd(pVerJob->pErr, pVerJob->idxTest, "Files '%s' and '%s' have different content\n",
     1727                                        pObjA->szName, pObjB->szName);
    17211728        AssertRC(rc2);
    17221729    }
  • trunk/src/VBox/Devices/Audio/AudioTest.h

    r89889 r89890  
    340340double AudioTestToneInit(PAUDIOTESTTONE pTone, PPDMAUDIOPCMPROPS pProps, double dbFreq);
    341341double AudioTestToneInitRandom(PAUDIOTESTTONE pTone, PPDMAUDIOPCMPROPS pProps);
     342double AudioTestToneGetRandomFreq(void);
    342343int    AudioTestToneGenerate(PAUDIOTESTTONE pTone, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten);
    343 
    344 int    AudioTestToneParamsInitRandom(PAUDIOTESTTONEPARMS pToneParams, PPDMAUDIOPCMPROPS pProps);
    345344
    346345int    AudioTestGenTag(char *pszTag, size_t cbTag);
     
    367366const char *AudioTestSetGetTag(PAUDIOTESTSET pSet);
    368367bool   AudioTestSetIsPacked(const char *pszPath);
     368bool   AudioTestSetIsRunning(PAUDIOTESTSET pSet);
    369369int    AudioTestSetPack(PAUDIOTESTSET pSet, const char *pszOutDir, char *pszFileName, size_t cbFileName);
    370370int    AudioTestSetUnpack(const char *pszFile, const char *pszOutDir);
  • trunk/src/VBox/Devices/Audio/DrvHostAudioValidationKit.cpp

    r89838 r89890  
    2525#include <iprt/mem.h>
    2626#include <iprt/path.h>
     27#include <iprt/semaphore.h>
    2728#include <iprt/stream.h>
    2829#include <iprt/uuid.h> /* For PDMIBASE_2_PDMDRV. */
     
    138139    /** Critical section for serializing access across threads. */
    139140    RTCRITSECT          CritSect;
     141    bool                fTestSetEnded;
     142    RTSEMEVENT          EventSemEnded;
    140143    /** The Audio Test Service (ATS) instance. */
    141144    ATSSERVER           Srv;
     
    173176    {
    174177        AssertPtrReturnVoid(pTst->pEntry);
    175         AudioTestSetTestDone(pTst->pEntry);
    176178        pTst->pEntry = NULL;
    177179    }
     
    218220static void drvHostValKitCleanup(PDRVHOSTVALKITAUDIO pThis)
    219221{
    220     LogRel(("Audio: Validation Kit: Cleaning up ...\n"));
     222    LogRel(("ValKit: Cleaning up ...\n"));
    221223
    222224    if (pThis->cTestsRec)
    223         LogRel(("Audio: Validation Kit: Warning: %RU32 guest recording tests still outstanding:\n", pThis->cTestsRec));
     225        LogRel(("ValKit: Warning: %RU32 guest recording tests still outstanding:\n", pThis->cTestsRec));
    224226
    225227    PVALKITTESTDATA pTst, pTstNext;
     
    228230        size_t const cbOutstanding = pTst->t.TestTone.u.Rec.cbToWrite - pTst->t.TestTone.u.Rec.cbWritten;
    229231        if (cbOutstanding)
    230             LogRel(("Audio: Validation Kit: \tRecording test #%RU32 has %RU64 bytes (%RU32ms) outstanding\n",
     232            LogRel(("ValKit: \tRecording test #%RU32 has %RU64 bytes (%RU32ms) outstanding\n",
    231233                    pTst->idxTest, cbOutstanding, PDMAudioPropsBytesToMilli(&pTst->t.TestTone.Parms.Props, (uint32_t)cbOutstanding)));
    232234        drvHostValKiUnregisterRecTest(pThis, pTst);
     
    234236
    235237    if (pThis->cTestsPlay)
    236         LogRel(("Audio: Validation Kit: Warning: %RU32 guest playback tests still outstanding:\n", pThis->cTestsPlay));
     238        LogRel(("ValKit: Warning: %RU32 guest playback tests still outstanding:\n", pThis->cTestsPlay));
    237239
    238240    RTListForEachSafe(&pThis->lstTestsPlay, pTst, pTstNext, VALKITTESTDATA, Node)
     
    240242        size_t const cbOutstanding = pTst->t.TestTone.u.Play.cbToRead - pTst->t.TestTone.u.Play.cbRead;
    241243        if (cbOutstanding)
    242             LogRel(("Audio: Validation Kit: \tPlayback test #%RU32 has %RU64 bytes (%RU32ms) outstanding\n",
     244            LogRel(("ValKit: \tPlayback test #%RU32 has %RU64 bytes (%RU32ms) outstanding\n",
    243245                    pTst->idxTest, cbOutstanding, PDMAudioPropsBytesToMilli(&pTst->t.TestTone.Parms.Props, (uint32_t)cbOutstanding)));
    244246        drvHostValKiUnregisterPlayTest(pThis, pTst);
     
    259261    PDRVHOSTVALKITAUDIO pThis = (PDRVHOSTVALKITAUDIO)pvUser;
    260262
    261     LogRel(("Audio: Validation Kit: Beginning test set '%s'\n", pszTag));
    262     return AudioTestSetCreate(&pThis->Set, pThis->szPathTemp, pszTag);
     263    int rc = RTCritSectEnter(&pThis->CritSect);
     264    if (RT_SUCCESS(rc))
     265    {
     266
     267        LogRel(("ValKit: Beginning test set '%s'\n", pszTag));
     268        rc = AudioTestSetCreate(&pThis->Set, pThis->szPathTemp, pszTag);
     269
     270        int rc2 = RTCritSectLeave(&pThis->CritSect);
     271        if (RT_SUCCESS(rc))
     272            rc = rc2;
     273    }
     274
     275    if (RT_FAILURE(rc))
     276        LogRel(("ValKit: Beginning test set failed with %Rrc\n", rc));
     277
     278    return rc;
    263279}
    264280
     
    268284    PDRVHOSTVALKITAUDIO pThis = (PDRVHOSTVALKITAUDIO)pvUser;
    269285
    270     const PAUDIOTESTSET pSet  = &pThis->Set;
    271 
    272     LogRel(("Audio: Validation Kit: Ending test set '%s'\n", pszTag));
    273 
    274     /* Close the test set first. */
    275     AudioTestSetClose(pSet);
    276 
    277     /* Before destroying the test environment, pack up the test set so
    278      * that it's ready for transmission. */
    279     int rc = AudioTestSetPack(pSet, pThis->szPathOut, pThis->szTestSetArchive, sizeof(pThis->szTestSetArchive));
    280     if (RT_SUCCESS(rc))
    281         LogRel(("Audio: Validation Kit: Packed up to '%s'\n", pThis->szTestSetArchive));
    282 
    283     /* Do some internal housekeeping. */
    284     drvHostValKitCleanup(pThis);
    285 
    286     int rc2 = AudioTestSetWipe(pSet);
    287     if (RT_SUCCESS(rc))
    288         rc = rc2;
    289 
    290     AudioTestSetDestroy(pSet);
     286    int rc = RTCritSectEnter(&pThis->CritSect);
     287    if (RT_SUCCESS(rc))
     288    {
     289        const PAUDIOTESTSET pSet  = &pThis->Set;
     290
     291        if (AudioTestSetIsRunning(pSet))
     292        {
     293            pThis->fTestSetEnded = true;
     294
     295            rc = RTCritSectLeave(&pThis->CritSect);
     296            if (RT_SUCCESS(rc))
     297            {
     298                LogRel(("ValKit: Waiting for runnig test set '%s' to end ...\n", pszTag));
     299                rc = RTSemEventWait(pThis->EventSemEnded, RT_MS_30SEC);
     300
     301                int rc2 = RTCritSectEnter(&pThis->CritSect);
     302                if (RT_SUCCESS(rc))
     303                    rc = rc2;
     304            }
     305        }
     306
     307        if (RT_SUCCESS(rc))
     308        {
     309            LogRel(("ValKit: Ending test set '%s'\n", pszTag));
     310
     311            /* Close the test set first. */
     312            rc = AudioTestSetClose(pSet);
     313            if (RT_SUCCESS(rc))
     314            {
     315                /* Before destroying the test environment, pack up the test set so
     316                 * that it's ready for transmission. */
     317                rc = AudioTestSetPack(pSet, pThis->szPathOut, pThis->szTestSetArchive, sizeof(pThis->szTestSetArchive));
     318                if (RT_SUCCESS(rc))
     319                    LogRel(("ValKit: Packed up to '%s'\n", pThis->szTestSetArchive));
     320
     321                /* Do some internal housekeeping. */
     322                drvHostValKitCleanup(pThis);
     323
     324#ifndef DEBUG_andy
     325                int rc2 = AudioTestSetWipe(pSet);
     326                if (RT_SUCCESS(rc))
     327                    rc = rc2;
     328#endif
     329            }
     330
     331            AudioTestSetDestroy(pSet);
     332        }
     333
     334        int rc2 = RTCritSectLeave(&pThis->CritSect);
     335        if (RT_SUCCESS(rc))
     336            rc = rc2;
     337    }
    291338
    292339    if (RT_FAILURE(rc))
    293         LogRel(("Audio: Validation Kit: Ending test set failed with %Rrc\n", rc));
     340        LogRel(("ValKit: Ending test set failed with %Rrc\n", rc));
    294341
    295342    return rc;
     
    310357    memcpy(&pTestData->t.TestTone.Parms, pToneParms, sizeof(AUDIOTESTTONEPARMS));
    311358
    312     AudioTestToneInit(&pTestData->t.TestTone.Tone, &pToneParms->Props, pTestData->t.TestTone.Parms.dbFreqHz);
    313 
    314     pTestData->t.TestTone.u.Rec.cbToWrite = PDMAudioPropsMilliToBytes(&pToneParms->Props,
     359    AssertReturn(pTestData->t.TestTone.Parms.msDuration, VERR_INVALID_PARAMETER);
     360    AssertReturn(PDMAudioPropsAreValid(&pTestData->t.TestTone.Parms.Props), VERR_INVALID_PARAMETER);
     361
     362    AudioTestToneInit(&pTestData->t.TestTone.Tone, &pTestData->t.TestTone.Parms.Props, pTestData->t.TestTone.Parms.dbFreqHz);
     363
     364    pTestData->t.TestTone.u.Rec.cbToWrite = PDMAudioPropsMilliToBytes(&pTestData->t.TestTone.Parms.Props,
    315365                                                                      pTestData->t.TestTone.Parms.msDuration);
    316366    int rc = RTCritSectEnter(&pThis->CritSect);
    317367    if (RT_SUCCESS(rc))
    318368    {
    319         LogRel(("Audio: Validation Kit: Registered guest recording test #%RU32 (%RU32ms, %RU64 bytes)\n",
     369        LogRel(("ValKit: Registered guest recording test #%RU32 (%RU32ms, %RU64 bytes)\n",
    320370                pThis->cTestsTotal, pTestData->t.TestTone.Parms.msDuration, pTestData->t.TestTone.u.Rec.cbToWrite));
    321371
     
    347397    memcpy(&pTestData->t.TestTone.Parms, pToneParms, sizeof(AUDIOTESTTONEPARMS));
    348398
    349     pTestData->t.TestTone.u.Play.cbToRead = PDMAudioPropsMilliToBytes(&pToneParms->Props,
     399    AssertReturn(pTestData->t.TestTone.Parms.msDuration, VERR_INVALID_PARAMETER);
     400    AssertReturn(PDMAudioPropsAreValid(&pTestData->t.TestTone.Parms.Props), VERR_INVALID_PARAMETER);
     401
     402    pTestData->t.TestTone.u.Play.cbToRead = PDMAudioPropsMilliToBytes(&pTestData->t.TestTone.Parms.Props,
    350403                                                                      pTestData->t.TestTone.Parms.msDuration);
    351404    int rc = RTCritSectEnter(&pThis->CritSect);
    352405    if (RT_SUCCESS(rc))
    353406    {
    354         LogRel(("Audio: Validation Kit: Registered guest playback test #%RU32 (%RU32ms, %RU64 bytes)\n",
     407        LogRel(("ValKit: Registered guest playback test #%RU32 (%RU32ms, %RU64 bytes)\n",
    355408                pThis->cTestsTotal, pTestData->t.TestTone.Parms.msDuration, pTestData->t.TestTone.u.Play.cbToRead));
    356409
     
    375428    PDRVHOSTVALKITAUDIO pThis = (PDRVHOSTVALKITAUDIO)pvUser;
    376429
    377     if (!RTFileExists(pThis->szTestSetArchive)) /* Has the archive successfully been created yet? */
    378         return VERR_WRONG_ORDER;
    379 
    380     int rc = RTFileOpen(&pThis->hTestSetArchive, pThis->szTestSetArchive, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
    381     if (RT_SUCCESS(rc))
    382     {
    383         uint64_t uSize;
    384         rc = RTFileQuerySize(pThis->hTestSetArchive, &uSize);
    385         if (RT_SUCCESS(rc))
    386             LogRel(("Audio: Validation Kit: Sending test set '%s' (%zu bytes)\n", pThis->szTestSetArchive, uSize));
    387     }
     430    int rc = RTCritSectEnter(&pThis->CritSect);
     431    if (RT_SUCCESS(rc))
     432    {
     433        if (RTFileExists(pThis->szTestSetArchive)) /* Has the archive successfully been created yet? */
     434        {
     435            rc = RTFileOpen(&pThis->hTestSetArchive, pThis->szTestSetArchive, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
     436            if (RT_SUCCESS(rc))
     437            {
     438                uint64_t uSize;
     439                rc = RTFileQuerySize(pThis->hTestSetArchive, &uSize);
     440                if (RT_SUCCESS(rc))
     441                    LogRel(("ValKit: Sending test set '%s' (%zu bytes)\n", pThis->szTestSetArchive, uSize));
     442            }
     443        }
     444        else
     445            rc = VERR_FILE_NOT_FOUND;
     446
     447        int rc2 = RTCritSectLeave(&pThis->CritSect);
     448        if (RT_SUCCESS(rc))
     449            rc = rc2;
     450    }
     451
     452    if (RT_FAILURE(rc))
     453        LogRel(("ValKit: Beginning to send test set failed with %Rrc\n", rc));
    388454
    389455    return rc;
     
    398464    PDRVHOSTVALKITAUDIO pThis = (PDRVHOSTVALKITAUDIO)pvUser;
    399465
    400     return RTFileRead(pThis->hTestSetArchive, pvBuf, cbBuf, pcbRead);
     466    int rc = RTCritSectEnter(&pThis->CritSect);
     467    if (RT_SUCCESS(rc))
     468    {
     469        if (RTFileIsValid(pThis->hTestSetArchive))
     470        {
     471            rc =  RTFileRead(pThis->hTestSetArchive, pvBuf, cbBuf, pcbRead);
     472        }
     473        else
     474            rc = VERR_WRONG_ORDER;
     475
     476        int rc2 = RTCritSectLeave(&pThis->CritSect);
     477        if (RT_SUCCESS(rc))
     478            rc = rc2;
     479    }
     480
     481    if (RT_FAILURE(rc))
     482        LogRel(("ValKit: Reading from test set failed with %Rrc\n", rc));
     483
     484    return rc;
    401485}
    402486
     
    408492    PDRVHOSTVALKITAUDIO pThis = (PDRVHOSTVALKITAUDIO)pvUser;
    409493
    410     int rc = RTFileClose(pThis->hTestSetArchive);
    411     if (RT_SUCCESS(rc))
    412     {
    413         pThis->hTestSetArchive = NIL_RTFILE;
    414     }
     494    int rc = RTCritSectEnter(&pThis->CritSect);
     495    if (RT_SUCCESS(rc))
     496    {
     497        if (RTFileIsValid(pThis->hTestSetArchive))
     498        {
     499            rc = RTFileClose(pThis->hTestSetArchive);
     500            if (RT_SUCCESS(rc))
     501                pThis->hTestSetArchive = NIL_RTFILE;
     502        }
     503
     504        int rc2 = RTCritSectLeave(&pThis->CritSect);
     505        if (RT_SUCCESS(rc))
     506            rc = rc2;
     507    }
     508
     509    if (RT_FAILURE(rc))
     510        LogRel(("ValKit: Ending to send test set failed with %Rrc\n", rc));
    415511
    416512    return rc;
     
    532628static DECLCALLBACK(int) drvHostValKitAudioHA_StreamDrain(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    533629{
    534     RT_NOREF(pInterface, pStream);
     630    RT_NOREF(pStream);
     631
     632    PDRVHOSTVALKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
     633
     634    int rc = RTCritSectEnter(&pThis->CritSect);
     635    if (RT_SUCCESS(rc))
     636    {
     637        PVALKITTESTDATA pTst = pThis->pTestCur;
     638
     639        if (pTst)
     640        {
     641            LogRel(("ValKit: Test #%RU32: Recording audio data ended (took %RU32ms)\n",
     642                pTst->idxTest, RTTimeMilliTS() - pTst->msStartedTS));
     643
     644            if (pTst->t.TestTone.u.Play.cbRead > pTst->t.TestTone.u.Play.cbToRead)
     645                LogRel(("ValKit: Warning: Test #%RU32 read %RU32 bytes more than announced\n",
     646                        pTst->idxTest, pTst->t.TestTone.u.Play.cbRead - pTst->t.TestTone.u.Play.cbToRead));
     647
     648            AudioTestSetTestDone(pTst->pEntry);
     649
     650            pThis->pTestCur = NULL;
     651            pTst            = NULL;
     652
     653            if (pThis->fTestSetEnded)
     654                rc = RTSemEventSignal(pThis->EventSemEnded);
     655        }
     656
     657        int rc2 = RTCritSectLeave(&pThis->CritSect);
     658        AssertRC(rc2);
     659    }
     660
    535661    return VINF_SUCCESS;
    536662}
     
    595721    RT_NOREF(pStream);
    596722
     723    if (cbBuf == 0)
     724    {
     725        /* Fend off draining calls. */
     726        *pcbWritten = 0;
     727        return VINF_SUCCESS;
     728    }
     729
    597730    PDRVHOSTVALKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
    598731
     732    PVALKITTESTDATA pTst = NULL;
     733
    599734    int rc = RTCritSectEnter(&pThis->CritSect);
    600735    if (RT_SUCCESS(rc))
    601736    {
    602         pThis->pTestCur = RTListGetFirst(&pThis->lstTestsPlay, VALKITTESTDATA, Node);
     737        if (pThis->pTestCur == NULL)
     738            pThis->pTestCur = RTListGetFirst(&pThis->lstTestsPlay, VALKITTESTDATA, Node);
     739
     740        pTst = pThis->pTestCur;
    603741
    604742        int rc2 = RTCritSectLeave(&pThis->CritSect);
     
    606744    }
    607745
    608     if (pThis->pTestCur == NULL) /* Empty list? */
    609     {
    610         LogRelMax(64, ("Audio: Validation Kit: Warning: Guest is playing back data when no playback test is active\n"));
     746    if (pTst == NULL) /* Empty list? */
     747    {
     748        LogRel(("ValKit: Warning: Guest is playing back data when no playback test is active\n"));
    611749
    612750        *pcbWritten = cbBuf;
     
    614752    }
    615753
    616     PVALKITTESTDATA pTst = pThis->pTestCur;
     754#if 1
     755    if (PDMAudioPropsIsBufferSilence(&pStream->pStream->Cfg.Props, pvBuf, cbBuf))
     756    {
     757        LogRel(("ValKit: Skipping %RU32 bytes of silence\n", cbBuf));
     758
     759        *pcbWritten = cbBuf;
     760        return VINF_SUCCESS;
     761    }
     762#endif
    617763
    618764    if (pTst->t.TestTone.u.Play.cbRead == 0)
     
    633779        {
    634780            pTst->msStartedTS = RTTimeMilliTS();
    635             LogRel(("Audio: Validation Kit: Recording audio data (%RU16Hz, %RU32ms) started\n",
    636                     (uint16_t)Parms.TestTone.dbFreqHz, Parms.TestTone.msDuration));
     781            LogRel(("ValKit: Test #%RU32: Recording audio data (%RU16Hz, %RU32ms) started\n",
     782                    pTst->idxTest, (uint16_t)Parms.TestTone.dbFreqHz, Parms.TestTone.msDuration));
    637783        }
    638784    }
     
    642788    if (RT_SUCCESS(rc))
    643789    {
    644         uint32_t cbToRead = RT_MIN(cbBuf,
    645                                    pTst->t.TestTone.u.Play.cbToRead - pTst->t.TestTone.u.Play.cbRead);
    646 
    647         rc = AudioTestSetObjWrite(pTst->pObj, pvBuf, cbToRead);
    648         if (RT_SUCCESS(rc))
    649         {
    650             pTst->t.TestTone.u.Play.cbRead += cbToRead;
    651             Assert(pTst->t.TestTone.u.Play.cbRead <= pTst->t.TestTone.u.Play.cbToRead);
    652 
    653             const bool fComplete = pTst->t.TestTone.u.Play.cbToRead == pTst->t.TestTone.u.Play.cbRead;
    654 
     790        rc = AudioTestSetObjWrite(pTst->pObj, pvBuf, cbBuf);
     791        if (RT_SUCCESS(rc))
     792        {
     793            pTst->t.TestTone.u.Play.cbRead += cbBuf;
     794
     795        #if 0
     796            const bool fComplete = pTst->t.TestTone.u.Play.cbRead >= pTst->t.TestTone.u.Play.cbToRead;
    655797            if (fComplete)
    656798            {
    657                 LogRel(("Audio: Validation Kit: Recording audio data done (took %RU32ms)\n",
    658                         RTTimeMilliTS() - pTst->msStartedTS));
     799                LogRel(("ValKit: Test #%RU32: Recording audio data ended (took %RU32ms)\n",
     800                        pTst->idxTest, RTTimeMilliTS() - pTst->msStartedTS));
     801
     802                if (pTst->t.TestTone.u.Play.cbRead > pTst->t.TestTone.u.Play.cbToRead)
     803                    LogRel(("ValKit: Warning: Test #%RU32 read %RU32 bytes more than announced\n",
     804                            pTst->idxTest, pTst->t.TestTone.u.Play.cbRead - pTst->t.TestTone.u.Play.cbToRead));
    659805
    660806                rc = RTCritSectEnter(&pThis->CritSect);
    661807                if (RT_SUCCESS(rc))
    662808                {
    663                     drvHostValKiUnregisterPlayTest(pThis, pTst);
     809                    AudioTestSetTestDone(pTst->pEntry);
    664810
    665811                    pThis->pTestCur = NULL;
     812                    pTst            = NULL;
     813
     814                    if (pThis->fTestSetEnded)
     815                        rc = RTSemEventSignal(pThis->EventSemEnded);
    666816
    667817                    int rc2 = RTCritSectLeave(&pThis->CritSect);
    668                     AssertRC(rc2);
     818                    if (RT_SUCCESS(rc))
     819                        rc = rc2;
    669820                }
    670821            }
    671 
    672             cbWritten = cbToRead;
     822        #endif
     823
     824            cbWritten = cbBuf;
    673825        }
    674826    }
     
    676828    if (RT_FAILURE(rc))
    677829    {
    678         if (pTst->pEntry)
     830        if (   pTst
     831            && pTst->pEntry)
    679832            AudioTestSetTestFailed(pTst->pEntry, rc, "Recording audio data failed");
    680         LogRel(("Audio: Validation Kit: Recording audio data failed with %Rrc\n", rc));
     833        LogRel(("ValKit: Recording audio data failed with %Rrc\n", rc));
    681834    }
    682835
     
    700853    if (RT_SUCCESS(rc))
    701854    {
    702         pThis->pTestCur = RTListGetFirst(&pThis->lstTestsRec, VALKITTESTDATA, Node);
     855        if (pThis->pTestCur == NULL)
     856            pThis->pTestCur = RTListGetFirst(&pThis->lstTestsRec, VALKITTESTDATA, Node);
    703857
    704858        int rc2 = RTCritSectLeave(&pThis->CritSect);
     
    708862    if (pThis->pTestCur == NULL) /* Empty list? */
    709863    {
    710         LogRelMax(64, ("Audio: Validation Kit: Warning: Guest is recording audio data when no recording test is active\n"));
     864        LogRelMax(64, ("ValKit: Warning: Guest is recording audio data when no recording test is active\n"));
    711865
    712866        *pcbRead = 0;
     
    733887        {
    734888            pTst->msStartedTS = RTTimeMilliTS();
    735             LogRel(("Audio: Validation Kit: Injecting audio input data (%RU16Hz, %RU32ms) started\n",
     889            LogRel(("ValKit: Injecting audio input data (%RU16Hz, %RU32ms) started\n",
    736890                    (uint16_t)pTst->t.TestTone.Tone.rdFreqHz,
    737891                    pTst->t.TestTone.Parms.msDuration));
     
    759913                if (fComplete)
    760914                {
    761                     LogRel(("Audio: Validation Kit: Injecting audio input data done (took %RU32ms)\n",
     915                    LogRel(("ValKit: Injecting audio input data done (took %RU32ms)\n",
    762916                            RTTimeMilliTS() - pTst->msStartedTS));
    763917
     
    768922
    769923                        pThis->pTestCur = NULL;
     924                        pTst            = NULL;
    770925
    771926                        int rc2 = RTCritSectLeave(&pThis->CritSect);
     
    779934    if (RT_FAILURE(rc))
    780935    {
    781         if (pTst->pEntry)
     936        if (   pTst
     937            && pTst->pEntry)
    782938            AudioTestSetTestFailed(pTst->pEntry, rc, "Injecting audio input data failed");
    783         LogRel(("Audio: Validation Kit: Injecting audio input data failed with %Rrc\n", rc));
     939        LogRel(("ValKit: Injecting audio input data failed with %Rrc\n", rc));
    784940    }
    785941
     
    8441000    pThis->IHostAudio.pfnStreamCapture              = drvHostValKitAudioHA_StreamCapture;
    8451001
     1002    int rc = RTCritSectInit(&pThis->CritSect);
     1003    AssertRCReturn(rc, rc);
     1004    rc = RTSemEventCreate(&pThis->EventSemEnded);
     1005    AssertRCReturn(rc, rc);
     1006
     1007    pThis->fTestSetEnded = false;
     1008
    8461009    RTListInit(&pThis->lstTestsRec);
    8471010    pThis->cTestsRec  = 0;
     
    8641027       uint32_t uTcpPort   = ATS_TCP_HOST_DEFAULT_PORT;
    8651028
    866     LogRel(("Audio: Validation Kit: Starting Audio Test Service (ATS) at %s:%RU32...\n",
     1029    LogRel(("ValKit: Starting Audio Test Service (ATS) at %s:%RU32...\n",
    8671030            pszTcpAddr, uTcpPort));
    8681031
    869     int rc = AudioTestSvcInit(&pThis->Srv,
    870                               /* We only allow connections from localhost for now. */
    871                               pszTcpAddr, uTcpPort, &Callbacks);
     1032    rc = AudioTestSvcInit(&pThis->Srv,
     1033                          /* We only allow connections from localhost for now. */
     1034                          pszTcpAddr, uTcpPort, &Callbacks);
    8721035    if (RT_SUCCESS(rc))
    8731036        rc = AudioTestSvcStart(&pThis->Srv);
     
    8751038    if (RT_SUCCESS(rc))
    8761039    {
    877         LogRel(("Audio: Validation Kit: Audio Test Service (ATS) running\n"));
     1040        LogRel(("ValKit: Audio Test Service (ATS) running\n"));
    8781041
    8791042        /** @todo Let the following be customizable by CFGM later. */
     
    8811044        if (RT_SUCCESS(rc))
    8821045        {
    883             LogRel(("Audio: Validation Kit: Using temp dir '%s'\n", pThis->szPathTemp));
     1046            LogRel(("ValKit: Using temp dir '%s'\n", pThis->szPathTemp));
    8841047            rc = AudioTestPathGetTemp(pThis->szPathOut, sizeof(pThis->szPathOut));
    8851048            if (RT_SUCCESS(rc))
    886                 LogRel(("Audio: Validation Kit: Using output dir '%s'\n", pThis->szPathOut));
     1049                LogRel(("ValKit: Using output dir '%s'\n", pThis->szPathOut));
    8871050        }
    8881051    }
    8891052
    890     if (RT_SUCCESS(rc))
    891         rc = RTCritSectInit(&pThis->CritSect);
    892 
    8931053    if (RT_FAILURE(rc))
    894         LogRel(("Audio: Validation Kit: Initialization failed, rc=%Rrc\n", rc));
     1054        LogRel(("ValKit: Initialization failed, rc=%Rrc\n", rc));
    8951055
    8961056    return rc;
     
    9021062    PDRVHOSTVALKITAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTVALKITAUDIO);
    9031063
    904     LogRel(("Audio: Validation Kit: Shutting down Audio Test Service (ATS) ...\n"));
     1064    LogRel(("ValKit: Shutting down Audio Test Service (ATS) ...\n"));
    9051065
    9061066    int rc = AudioTestSvcShutdown(&pThis->Srv);
     
    9101070    if (RT_SUCCESS(rc))
    9111071    {
    912         LogRel(("Audio: Validation Kit: Shutdown of Audio Test Service (ATS) complete\n"));
     1072        LogRel(("ValKit: Shutdown of Audio Test Service (ATS) complete\n"));
    9131073        drvHostValKitCleanup(pThis);
    9141074    }
    9151075    else
    916         LogRel(("Audio: Validation Kit: Shutdown of Audio Test Service (ATS) failed, rc=%Rrc\n", rc));
     1076        LogRel(("ValKit: Shutdown of Audio Test Service (ATS) failed, rc=%Rrc\n", rc));
    9171077
    9181078    /* Try cleaning up a bit. */
     
    9201080    RTDirRemove(pThis->szPathOut);
    9211081
     1082    RTSemEventDestroy(pThis->EventSemEnded);
     1083
    9221084    if (RTCritSectIsInitialized(&pThis->CritSect))
    9231085    {
     
    9281090
    9291091    if (RT_FAILURE(rc))
    930         LogRel(("Audio: Validation Kit: Destruction failed, rc=%Rrc\n", rc));
     1092        LogRel(("ValKit: Destruction failed, rc=%Rrc\n", rc));
    9311093}
    9321094
  • trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp

    r89850 r89890  
    6161*   Internal Functions                                                                                                           *
    6262*********************************************************************************************************************************/
    63 static int audioTestCombineParms(PAUDIOTESTPARMS pBaseParms, PAUDIOTESTPARMS pOverrideParms);
    6463static int audioVerifyOne(const char *pszPathSetA, const char *pszPathSetB);
    6564
     
    230229
    231230
    232 /**
    233  * Overrides audio test base parameters with another set.
    234  *
    235  * @returns VBox status code.
    236  * @param   pBaseParms          Base parameters to override.
    237  * @param   pOverrideParms      Override parameters to use for overriding the base parameters.
    238  *
    239  * @note    Overriding a parameter depends on its type / default values.
    240  */
    241 static int audioTestCombineParms(PAUDIOTESTPARMS pBaseParms, PAUDIOTESTPARMS pOverrideParms)
    242 {
    243     RT_NOREF(pBaseParms, pOverrideParms);
    244 
    245     /** @todo Implement parameter overriding. */
    246     return VERR_NOT_IMPLEMENTED;
    247 }
    248 
    249 
    250231/*********************************************************************************************************************************
    251232*   Test callbacks                                                                                                               *
     
    257238static DECLCALLBACK(int) audioTestPlayToneSetup(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, PAUDIOTESTPARMS pTstParmsAcq, void **ppvCtx)
    258239{
    259     RT_NOREF(pTstEnv, pTstDesc, ppvCtx);
     240    RT_NOREF(pTstDesc, ppvCtx);
     241
     242    int rc;
     243
     244    if (strlen(pTstEnv->szDev))
     245    {
     246        rc = audioTestDriverStackSetDevice(&pTstEnv->DrvStack, PDMAUDIODIR_OUT, pTstEnv->szDev);
     247        if (RT_FAILURE(rc))
     248            return rc;
     249    }
    260250
    261251    pTstParmsAcq->enmType     = AUDIOTESTTYPE_TESTTONE_PLAY;
    262 
    263     PDMAudioPropsInit(&pTstParmsAcq->Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */);
    264 
     252    pTstParmsAcq->Props       = pTstEnv->Props;
    265253    pTstParmsAcq->enmDir      = PDMAUDIODIR_OUT;
    266254#ifdef DEBUG
    267     pTstParmsAcq->cIterations = 2;
     255    pTstParmsAcq->cIterations = 1;
    268256#else
    269257    pTstParmsAcq->cIterations = RTRandU32Ex(1, 10);
     
    271259    pTstParmsAcq->idxCurrent  = 0;
    272260
    273     return VINF_SUCCESS;
     261    PAUDIOTESTTONEPARMS pToneParms = &pTstParmsAcq->TestTone;
     262
     263    pToneParms->Props          = pTstParmsAcq->Props;
     264    pToneParms->dbFreqHz       = AudioTestToneGetRandomFreq();
     265    pToneParms->msPrequel      = 0; /** @todo Implement analyzing this first! */
     266#ifdef DEBUG_andy
     267    pToneParms->msDuration     = 2000;
     268#else
     269    pToneParms->msDuration     = RTRandU32Ex(0, RT_MS_10SEC); /** @todo Probably a bit too long, but let's see. */
     270#endif
     271    pToneParms->msSequel       = 0;   /** @todo Implement analyzing this first! */
     272    pToneParms->uVolumePercent = 100; /** @todo Implement analyzing this first! */
     273
     274    return rc;
    274275}
    275276
     
    285286    for (uint32_t i = 0; i < pTstParms->cIterations; i++)
    286287    {
    287         AudioTestToneParamsInitRandom(&pTstParms->TestTone, &pTstParms->Props);
    288 
     288        /*
     289         * 1. Arm the (host) ValKit ATS with the recording parameters.
     290         */
    289291        PAUDIOTESTTONEPARMS const pToneParms = &pTstParms->TestTone;
    290292        rc = AudioTestSvcClientToneRecord(&pTstEnv->u.Host.AtsClValKit, pToneParms);
    291293        if (RT_SUCCESS(rc))
     294        {
     295            /*
     296             * 2. Tell the guest ATS to start playback.
     297             */
    292298            rc = AudioTestSvcClientTonePlay(&pTstEnv->u.Host.AtsClGuest, pToneParms);
     299        }
    293300
    294301        if (RT_FAILURE(rc))
     
    314321static DECLCALLBACK(int) audioTestRecordToneSetup(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, PAUDIOTESTPARMS pTstParmsAcq, void **ppvCtx)
    315322{
    316     RT_NOREF(pTstEnv, pTstDesc, ppvCtx);
     323    RT_NOREF(pTstDesc, ppvCtx);
     324
     325    int rc;
     326
     327    if (strlen(pTstEnv->szDev))
     328    {
     329        rc = audioTestDriverStackSetDevice(&pTstEnv->DrvStack, PDMAUDIODIR_IN, pTstEnv->szDev);
     330        if (RT_FAILURE(rc))
     331            return rc;
     332    }
    317333
    318334    pTstParmsAcq->enmType     = AUDIOTESTTYPE_TESTTONE_RECORD;
    319 
    320     PDMAudioPropsInit(&pTstParmsAcq->Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */);
    321 
     335    pTstParmsAcq->Props       = pTstEnv->Props;
    322336    pTstParmsAcq->enmDir      = PDMAUDIODIR_IN;
    323337#ifdef DEBUG
    324     pTstParmsAcq->cIterations = 2;
     338    pTstParmsAcq->cIterations = 1;
    325339#else
    326340    pTstParmsAcq->cIterations = RTRandU32Ex(1, 10);
     
    328342    pTstParmsAcq->idxCurrent  = 0;
    329343
    330     return VINF_SUCCESS;
     344    return rc;
    331345}
    332346
     
    349363#endif
    350364        /*
    351          * 1. Arm the ValKit ATS with the recording parameters.
     365         * 1. Arm the (host) ValKit ATS with the playback parameters.
    352366         */
    353367        rc = AudioTestSvcClientTonePlay(&pTstEnv->u.Host.AtsClValKit, &pTstParms->TestTone);
     
    399413 * @param   pTstDesc            Test to run.
    400414 * @param   uSeq                Test sequence # in case there are more tests.
    401  * @param   pOverrideParms      Test parameters for overriding the actual test parameters. Optional.
    402  */
    403 static int audioTestOne(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc,
    404                         unsigned uSeq, PAUDIOTESTPARMS pOverrideParms)
     415 */
     416static int audioTestOne(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, unsigned uSeq)
    405417{
    406418    RT_NOREF(uSeq);
     
    431443    }
    432444
    433     audioTestCombineParms(&TstParms, pOverrideParms);
    434 
    435445    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test #%u: %RU32 iterations\n", uSeq, TstParms.cIterations);
    436 
    437     if (TstParms.Dev.pszName && strlen(TstParms.Dev.pszName)) /** @todo Refine this check. Use pszId for starters! */
    438         rc = audioTestDeviceOpen(&TstParms.Dev);
    439446
    440447    AssertPtr(pTstDesc->pfnExec);
     
    455462    }
    456463
    457     rc = audioTestDeviceClose(&TstParms.Dev);
    458 
    459464    audioTestParmsDestroy(&TstParms);
    460465
     
    467472 * @returns VBox status code.
    468473 * @param   pTstEnv             Test environment to use for running all tests.
    469  * @param   pOverrideParms      Test parameters for (some / all) specific test parameters. Optional.
    470  */
    471 int audioTestWorker(PAUDIOTESTENV pTstEnv, PAUDIOTESTPARMS pOverrideParms)
     474 */
     475int audioTestWorker(PAUDIOTESTENV pTstEnv)
    472476{
    473477    int rc = VINF_SUCCESS;
     
    501505            for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++)
    502506            {
    503                 int rc2 = audioTestOne(pTstEnv, &g_aTests[i], uSeq, pOverrideParms);
     507                int rc2 = audioTestOne(pTstEnv, &g_aTests[i], uSeq);
    504508                if (RT_SUCCESS(rc))
    505509                    rc = rc2;
     
    631635    RT_ZERO(TstEnv);
    632636
    633     AUDIOTESTPARMS TstCust;
    634     audioTestParmsInit(&TstCust);
    635 
    636637    const char *pszDevice     = NULL; /* Custom device to use. Can be NULL if not being used. */
    637638    const char *pszTag        = NULL; /* Custom tag to use. Can be NULL if not being used. */
     
    750751
    751752            case VKAT_TEST_OPT_VOL:
    752                 TstCust.TestTone.uVolumePercent = ValueUnion.u8;
     753                TstEnv.uVolumePercent = ValueUnion.u8;
    753754                break;
    754755
     
    766767
    767768    /* Initialize the custom test parameters with sensible defaults if nothing else is given. */
    768     PDMAudioPropsInit(&TstCust.TestTone.Props,
     769    PDMAudioPropsInit(&TstEnv.Props,
    769770                      cPcmSampleBit ? cPcmSampleBit / 8 : 2 /* 16-bit */, fPcmSigned, cPcmChannels ? cPcmChannels : 2,
    770771                      uPcmHz ? uPcmHz : 44100);
     
    784785                          pszGuestTcpAddr, uGuestTcpPort);
    785786    if (RT_SUCCESS(rc))
    786     {
    787         audioTestWorker(&TstEnv, &TstCust);
    788         audioTestEnvDestroy(&TstEnv);
    789     }
    790 
    791     audioTestParmsDestroy(&TstCust);
     787        rc = audioTestWorker(&TstEnv);
     788
     789    audioTestEnvDestroy(&TstEnv);
    792790
    793791    if (RT_FAILURE(rc)) /* Let us know that something went wrong in case we forgot to mention it. */
  • trunk/src/VBox/ValidationKit/utils/audio/vkatCmdSelfTest.cpp

    r89834 r89890  
    5656    PSELFTESTCTX pCtx = (PSELFTESTCTX)pvUser;
    5757
    58     AUDIOTESTPARMS TstCust;
    59     audioTestParmsInit(&TstCust);
    60 
    61     PAUDIOTESTENV pTstEnv = &pCtx->Guest.TstEnv;
     58    PAUDIOTESTENV pTstEnvGst = &pCtx->Guest.TstEnv;
    6259
    6360    /* Flag the environment for self test mode. */
    64     pTstEnv->fSelftest = true;
     61    pTstEnvGst->fSelftest = true;
    6562
    6663    /* Generate tag for guest side. */
    67     int rc = RTStrCopy(pTstEnv->szTag, sizeof(pTstEnv->szTag), pCtx->szTag);
     64    int rc = RTStrCopy(pTstEnvGst->szTag, sizeof(pTstEnvGst->szTag), pCtx->szTag);
    6865    AssertRCReturn(rc, rc);
    6966
    70     rc = AudioTestPathCreateTemp(pTstEnv->szPathTemp, sizeof(pTstEnv->szPathTemp), "selftest-guest");
     67    rc = AudioTestPathCreateTemp(pTstEnvGst->szPathTemp, sizeof(pTstEnvGst->szPathTemp), "selftest-guest");
    7168    AssertRCReturn(rc, rc);
    7269
    73     rc = AudioTestPathCreateTemp(pTstEnv->szPathOut, sizeof(pTstEnv->szPathOut), "selftest-out");
     70    rc = AudioTestPathCreateTemp(pTstEnvGst->szPathOut, sizeof(pTstEnvGst->szPathOut), "selftest-out");
    7471    AssertRCReturn(rc, rc);
    7572
    76     pTstEnv->enmMode = AUDIOTESTMODE_GUEST;
     73    pTstEnvGst->enmMode = AUDIOTESTMODE_GUEST;
    7774
    7875    /** @todo Make this customizable. */
    79     PDMAudioPropsInit(&TstCust.TestTone.Props,
     76    PDMAudioPropsInit(&pTstEnvGst->Props,
    8077                      2 /* 16-bit */, true  /* fSigned */, 2 /* cChannels */, 44100 /* uHz */);
    8178
    82     rc = audioTestEnvInit(pTstEnv, pTstEnv->DrvStack.pDrvReg, pCtx->fWithDrvAudio,
     79    rc = audioTestEnvInit(pTstEnvGst, pTstEnvGst->DrvStack.pDrvReg, pCtx->fWithDrvAudio,
    8380                          pCtx->Host.szValKitAtsAddr, pCtx->Host.uValKitAtsPort,
    8481                          pCtx->Guest.szAtsAddr, pCtx->Guest.uAtsPort);
     
    8784        RTThreadUserSignal(hThread);
    8885
    89         audioTestWorker(pTstEnv, &TstCust);
    90         audioTestEnvDestroy(pTstEnv);
    91     }
    92 
    93     audioTestParmsDestroy(&TstCust);
     86        audioTestWorker(pTstEnvGst);
     87        audioTestEnvDestroy(pTstEnvGst);
     88    }
    9489
    9590    return rc;
     
    118113     */
    119114
    120     AUDIOTESTPARMS TstCust;
    121     audioTestParmsInit(&TstCust);
    122 
    123115    /* Generate a common tag for guest and host side. */
    124116    int rc = AudioTestGenTag(pCtx->szTag, sizeof(pCtx->szTag));
    125117    AssertRCReturn(rc, RTEXITCODE_FAILURE);
    126118
    127     PAUDIOTESTENV pTstEnv = &pCtx->Host.TstEnv;
     119    PAUDIOTESTENV pTstEnvHst = &pCtx->Host.TstEnv;
    128120
    129121    /* Flag the environment for self test mode. */
    130     pTstEnv->fSelftest = true;
     122    pTstEnvHst->fSelftest = true;
    131123
    132124    /* Generate tag for host side. */
    133     rc = RTStrCopy(pTstEnv->szTag, sizeof(pTstEnv->szTag), pCtx->szTag);
     125    rc = RTStrCopy(pTstEnvHst->szTag, sizeof(pTstEnvHst->szTag), pCtx->szTag);
    134126    AssertRCReturn(rc, RTEXITCODE_FAILURE);
    135127
    136     rc = AudioTestPathCreateTemp(pTstEnv->szPathTemp, sizeof(pTstEnv->szPathTemp), "selftest-tmp");
     128    rc = AudioTestPathCreateTemp(pTstEnvHst->szPathTemp, sizeof(pTstEnvHst->szPathTemp), "selftest-tmp");
    137129    AssertRCReturn(rc, RTEXITCODE_FAILURE);
    138130
    139     rc = AudioTestPathCreateTemp(pTstEnv->szPathOut, sizeof(pTstEnv->szPathOut), "selftest-out");
     131    rc = AudioTestPathCreateTemp(pTstEnvHst->szPathOut, sizeof(pTstEnvHst->szPathOut), "selftest-out");
    140132    AssertRCReturn(rc, RTEXITCODE_FAILURE);
     133
     134    /* Initialize the PCM properties to some sane values. */
     135    PDMAudioPropsInit(&pTstEnvHst->Props,
     136                      2 /* 16-bit */, true /* fPcmSigned */, 2 /* cPcmChannels */, 44100 /* uPcmHz */);
    141137
    142138    /*
     
    161157         * Steps 2 + 3.
    162158         */
    163         pTstEnv->enmMode = AUDIOTESTMODE_HOST;
    164 
    165         rc = audioTestEnvInit(pTstEnv, &g_DrvHostValidationKitAudio, true /* fWithDrvAudio */,
     159        pTstEnvHst->enmMode = AUDIOTESTMODE_HOST;
     160
     161        rc = audioTestEnvInit(pTstEnvHst, &g_DrvHostValidationKitAudio, true /* fWithDrvAudio */,
    166162                              pCtx->Host.szValKitAtsAddr, pCtx->Host.uValKitAtsPort,
    167163                              pCtx->Host.szGuestAtsAddr, pCtx->Host.uGuestAtsPort);
    168164        if (RT_SUCCESS(rc))
    169165        {
    170             rc = audioTestWorker(pTstEnv, &TstCust);
     166            rc = audioTestWorker(pTstEnvHst);
    171167            if (RT_SUCCESS(rc))
    172168            {
     
    174170            }
    175171
    176             audioTestEnvDestroy(pTstEnv);
     172            audioTestEnvDestroy(pTstEnvHst);
    177173        }
    178174    }
    179 
    180     audioTestParmsDestroy(&TstCust);
    181175
    182176    /*
  • trunk/src/VBox/ValidationKit/utils/audio/vkatCommon.cpp

    r89837 r89890  
    6868*   Internal Functions                                                                                                           *
    6969*********************************************************************************************************************************/
    70 static int audioTestCreateStreamDefaultIn(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps);
    71 static int audioTestCreateStreamDefaultOut(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps);
     70static int audioTestStreamInit(PAUDIOTESTDRVSTACK pDrvStack, PAUDIOTESTSTREAM pStream, PDMAUDIODIR enmDir, PCPDMAUDIOPCMPROPS pProps, bool fWithMixer, uint32_t cMsBufferSize, uint32_t cMsPreBuffer, uint32_t cMsSchedulingHint);
    7271static int audioTestStreamDestroy(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream);
    7372static int audioTestDevicesEnumerateAndCheck(PAUDIOTESTENV pTstEnv, const char *pszDev, PPDMAUDIOHOSTDEV *ppDev);
     
    144143}
    145144
    146 /**
    147  * Opens an audio device.
    148  *
    149  * @returns VBox status code.
    150  * @param   pDev                Audio device to open.
    151  */
    152 int audioTestDeviceOpen(PPDMAUDIOHOSTDEV pDev)
    153 {
    154     int rc = VINF_SUCCESS;
    155 
    156     RTTestSubF(g_hTest, "Opening audio device '%s' ...", pDev->pszName);
    157 
    158     /** @todo Detect + open device here. */
    159 
    160     RTTestSubDone(g_hTest);
    161 
    162     return rc;
    163 }
    164 
    165 /**
    166  * Closes an audio device.
    167  *
    168  * @returns VBox status code.
    169  * @param   pDev                Audio device to close.
    170  */
    171 int audioTestDeviceClose(PPDMAUDIOHOSTDEV pDev)
    172 {
    173     int rc = VINF_SUCCESS;
    174 
    175     RTTestSubF(g_hTest, "Closing audio device '%s' ...", pDev->pszName);
    176 
    177     /** @todo Close device here. */
    178 
    179     RTTestSubDone(g_hTest);
     145static int audioTestStreamInit(PAUDIOTESTDRVSTACK pDrvStack, PAUDIOTESTSTREAM pStream,
     146                               PDMAUDIODIR enmDir, PCPDMAUDIOPCMPROPS pProps, bool fWithMixer,
     147                               uint32_t cMsBufferSize, uint32_t cMsPreBuffer, uint32_t cMsSchedulingHint)
     148{
     149    int rc;
     150
     151    if (enmDir == PDMAUDIODIR_IN)
     152        rc = audioTestDriverStackStreamCreateInput(pDrvStack, pProps, cMsBufferSize,
     153                                                   cMsPreBuffer, cMsSchedulingHint, &pStream->pStream, &pStream->Cfg);
     154    else if (enmDir == PDMAUDIODIR_OUT)
     155        rc = audioTestDriverStackStreamCreateOutput(pDrvStack, pProps, cMsBufferSize,
     156                                                    cMsPreBuffer, cMsSchedulingHint, &pStream->pStream, &pStream->Cfg);
     157    else
     158        rc = VERR_NOT_SUPPORTED;
     159
     160    if (RT_SUCCESS(rc))
     161    {
     162        if (!pDrvStack->pIAudioConnector)
     163        {
     164            pStream->pBackend = &((PAUDIOTESTDRVSTACKSTREAM)pStream->pStream)->Backend;
     165        }
     166        else
     167            pStream->pBackend = NULL;
     168
     169        /*
     170         * Automatically enable the mixer if the PCM properties don't match.
     171         */
     172        if (   !fWithMixer
     173            && !PDMAudioPropsAreEqual(pProps, &pStream->Cfg.Props))
     174        {
     175            RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,  "Enabling stream mixer\n");
     176            fWithMixer = true;
     177        }
     178
     179        rc = AudioTestMixStreamInit(&pStream->Mix, pDrvStack, pStream->pStream,
     180                                    fWithMixer ? pProps : NULL, 100 /* ms */); /** @todo Configure mixer buffer? */
     181    }
     182
     183    if (RT_FAILURE(rc))
     184        RTTestFailed(g_hTest, "Initializing %s stream failed with %Rrc", enmDir == PDMAUDIODIR_IN ? "input" : "output", rc);
    180185
    181186    return rc;
     
    201206    }
    202207
    203     return rc;
    204 }
    205 
    206 /**
    207  * Creates an audio default input (recording) test stream.
    208  * Convenience function.
    209  *
    210  * @returns VBox status code.
    211  * @param   pTstEnv             Test environment to use for creating the stream.
    212  * @param   pStream             Audio stream to create.
    213  * @param   pProps              PCM properties to use for creation.
    214  */
    215 static int audioTestCreateStreamDefaultIn(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps)
    216 {
    217     pStream->pBackend = NULL;
    218     int rc = audioTestDriverStackStreamCreateInput(&pTstEnv->DrvStack, pProps, pTstEnv->cMsBufferSize, pTstEnv->cMsPreBuffer,
    219                                                    pTstEnv->cMsSchedulingHint, &pStream->pStream, &pStream->Cfg);
    220     if (RT_SUCCESS(rc) && !pTstEnv->DrvStack.pIAudioConnector)
    221         pStream->pBackend = &((PAUDIOTESTDRVSTACKSTREAM)pStream->pStream)->Backend;
    222     return rc;
    223 }
    224 
    225 /**
    226  * Creates an audio default output (playback) test stream.
    227  * Convenience function.
    228  *
    229  * @returns VBox status code.
    230  * @param   pTstEnv             Test environment to use for creating the stream.
    231  * @param   pStream             Audio stream to create.
    232  * @param   pProps              PCM properties to use for creation.
    233  */
    234 static int audioTestCreateStreamDefaultOut(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps)
    235 {
    236     pStream->pBackend = NULL;
    237     int rc = audioTestDriverStackStreamCreateOutput(&pTstEnv->DrvStack, pProps, pTstEnv->cMsBufferSize, pTstEnv->cMsPreBuffer,
    238                                                     pTstEnv->cMsSchedulingHint, &pStream->pStream, &pStream->Cfg);
    239     if (RT_SUCCESS(rc) && !pTstEnv->DrvStack.pIAudioConnector)
    240         pStream->pBackend = &((PAUDIOTESTDRVSTACKSTREAM)pStream->pStream)->Backend;
     208    AudioTestMixStreamTerm(&pStream->Mix);
     209
    241210    return rc;
    242211}
     
    246215*   Test Primitives                                                                                                              *
    247216*********************************************************************************************************************************/
     217
     218/**
     219 * Returns a random scheduling hint (in ms).
     220 */
     221DECLINLINE(uint32_t) audioTestEnvGetRandomSchedulingHint(void)
     222{
     223    static const unsigned s_aSchedulingHintsMs[] =
     224    {
     225        10,
     226        25,
     227        50,
     228        100,
     229        200,
     230        250
     231    };
     232
     233    return s_aSchedulingHintsMs[RTRandU32Ex(0, RT_ELEMENTS(s_aSchedulingHintsMs) - 1)];
     234}
    248235
    249236/**
     
    260247{
    261248    AUDIOTESTTONE TstTone;
    262     AudioTestToneInit(&TstTone, &pParms->Props, pParms->dbFreqHz);
     249    AudioTestToneInit(&TstTone, &pStream->Cfg.Props, pParms->dbFreqHz);
    263250
    264251    const char *pcszPathOut = pTstEnv->Set.szPathAbs;
    265252
    266253    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Playing test tone (tone frequency is %RU16Hz, %RU32ms)\n", (uint16_t)pParms->dbFreqHz, pParms->msDuration);
    267     RTTestPrintf(g_hTest, RTTESTLVL_DEBUG,  "Writing to '%s'\n", pcszPathOut);
     254    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Using %RU32ms stream scheduling hint\n", pStream->Cfg.Device.cMsSchedulingHint);
     255    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Writing to '%s'\n", pcszPathOut);
    268256
    269257    /** @todo Use .WAV here? */
     
    272260    AssertRCReturn(rc, rc);
    273261
     262    rc = AudioTestMixStreamEnable(&pStream->Mix);
     263    if (   RT_SUCCESS(rc)
     264        && AudioTestMixStreamIsOkay(&pStream->Mix))
     265    {
     266        uint8_t  abBuf[_4K];
     267
     268        uint32_t cbToPlayTotal  = PDMAudioPropsMilliToBytes(&pStream->Cfg.Props, pParms->msDuration);
     269        AssertStmt(cbToPlayTotal, rc = VERR_INVALID_PARAMETER);
     270
     271        RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Playing %RU32 bytes total\n", cbToPlayTotal);
     272
     273        AudioTestSetObjAddMetadataStr(pObj, "stream_to_play_bytes=%RU32\n",      cbToPlayTotal);
     274        AudioTestSetObjAddMetadataStr(pObj, "stream_period_size_frames=%RU32\n", pStream->Cfg.Backend.cFramesPeriod);
     275        AudioTestSetObjAddMetadataStr(pObj, "stream_buffer_size_frames=%RU32\n", pStream->Cfg.Backend.cFramesBufferSize);
     276        AudioTestSetObjAddMetadataStr(pObj, "stream_prebuf_size_frames=%RU32\n", pStream->Cfg.Backend.cFramesPreBuffering);
     277        /* Note: This mostly is provided by backend (e.g. PulseAudio / ALSA / ++) and
     278         *       has nothing to do with the device emulation scheduling hint. */
     279        AudioTestSetObjAddMetadataStr(pObj, "device_scheduling_hint_ms=%RU32\n", pStream->Cfg.Device.cMsSchedulingHint);
     280
     281        while (cbToPlayTotal)
     282        {
     283            uint32_t       cbPlayed   = 0;
     284            uint32_t const cbCanWrite = AudioTestMixStreamGetWritable(&pStream->Mix);
     285            if (cbCanWrite)
     286            {
     287                uint32_t const cbToGenerate = RT_MIN(RT_MIN(cbToPlayTotal, sizeof(abBuf)), cbCanWrite);
     288                uint32_t       cbToPlay;
     289                rc = AudioTestToneGenerate(&TstTone, abBuf, cbToGenerate, &cbToPlay);
     290                if (RT_SUCCESS(rc))
     291                {
     292                    RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Playing %RU32 bytes ...\n", cbToPlay);
     293
     294                    /* Write stuff to disk before trying to play it. Help analysis later. */
     295                    rc = AudioTestSetObjWrite(pObj, abBuf, cbToPlay);
     296                    if (RT_SUCCESS(rc))
     297                        rc = AudioTestMixStreamPlay(&pStream->Mix, abBuf, cbToPlay, &cbPlayed);
     298                }
     299
     300                if (RT_FAILURE(rc))
     301                    break;
     302            }
     303            else if (AudioTestMixStreamIsOkay(&pStream->Mix))
     304                RTThreadSleep(RT_MIN(RT_MAX(1, pStream->Cfg.Device.cMsSchedulingHint), 256));
     305            else
     306                AssertFailedBreakStmt(rc = VERR_AUDIO_STREAM_NOT_READY);
     307
     308            Assert(cbToPlayTotal >= cbPlayed);
     309            cbToPlayTotal -= cbPlayed;
     310        }
     311
     312        if (cbToPlayTotal != 0)
     313            RTTestFailed(g_hTest, "Playback ended unexpectedly (%RU32 bytes left)\n", cbToPlayTotal);
     314    }
     315    else
     316        rc = VERR_AUDIO_STREAM_NOT_READY;
     317
     318    int rc2 = AudioTestSetObjClose(pObj);
     319    if (RT_SUCCESS(rc))
     320        rc = rc2;
     321
     322    if (RT_FAILURE(rc))
     323        RTTestFailed(g_hTest, "Playing tone failed with %Rrc\n", rc);
     324
     325    return rc;
     326}
     327
     328/**
     329 * Records a test tone from a specific audio test stream.
     330 *
     331 * @returns VBox status code.
     332 * @param   pTstEnv             Test environment to use for running the test.
     333 * @param   pStream             Stream to use for recording the tone.
     334 * @param   pParms              Tone parameters to use.
     335 *
     336 * @note    Blocking function.
     337 */
     338static int audioTestRecordTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms)
     339{
     340    const char *pcszPathOut = pTstEnv->Set.szPathAbs;
     341
     342    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Recording test tone (for %RU32ms)\n", pParms->msDuration);
     343    RTTestPrintf(g_hTest, RTTESTLVL_DEBUG,  "Writing to '%s'\n", pcszPathOut);
     344
     345    /** @todo Use .WAV here? */
     346    PAUDIOTESTOBJ pObj;
     347    int rc = AudioTestSetObjCreateAndRegister(&pTstEnv->Set, "guest-tone-rec.pcm", &pObj);
     348    AssertRCReturn(rc, rc);
     349
    274350    if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream))
    275351    {
    276         uint32_t cbBuf;
    277         uint8_t  abBuf[_4K];
    278 
    279352        const uint32_t cbPerSched = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint);
    280353        AssertStmt(cbPerSched, rc = VERR_INVALID_PARAMETER);
    281               uint32_t cbToWrite  = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration);
    282         AssertStmt(cbToWrite,  rc = VERR_INVALID_PARAMETER);
     354              uint32_t cbToRead   = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration);
     355        AssertStmt(cbToRead,   rc = VERR_INVALID_PARAMETER);
    283356
    284357        if (RT_SUCCESS(rc))
     
    288361            AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint);
    289362
    290             while (cbToWrite)
    291             {
    292                 uint32_t cbWritten    = 0;
    293                 uint32_t cbToGenerate = RT_MIN(cbToWrite, RT_MIN(cbPerSched, sizeof(abBuf)));
    294                 Assert(cbToGenerate);
    295 
    296                 rc = AudioTestToneGenerate(&TstTone, abBuf, cbToGenerate, &cbBuf);
    297                 if (RT_SUCCESS(rc))
    298                 {
    299                     /* Write stuff to disk before trying to play it. Help analysis later. */
    300                     rc = AudioTestSetObjWrite(pObj, abBuf, cbBuf);
    301                     if (RT_SUCCESS(rc))
    302                         rc = audioTestDriverStackStreamPlay(&pTstEnv->DrvStack, pStream->pStream,
    303                                                             abBuf, cbBuf, &cbWritten);
    304                 }
    305 
    306                 if (RT_FAILURE(rc))
    307                     break;
    308 
    309                 RTThreadSleep(pTstEnv->cMsSchedulingHint);
    310 
    311                 Assert(cbToWrite >= cbWritten);
    312                 cbToWrite -= cbWritten;
    313             }
    314         }
    315     }
    316     else
    317         rc = VERR_AUDIO_STREAM_NOT_READY;
    318 
    319     int rc2 = AudioTestSetObjClose(pObj);
    320     if (RT_SUCCESS(rc))
    321         rc = rc2;
    322 
    323     if (RT_FAILURE(rc))
    324         RTTestFailed(g_hTest, "Playing tone done failed with %Rrc\n", rc);
    325 
    326     return rc;
    327 }
    328 
    329 /**
    330  * Records a test tone from a specific audio test stream.
    331  *
    332  * @returns VBox status code.
    333  * @param   pTstEnv             Test environment to use for running the test.
    334  * @param   pStream             Stream to use for recording the tone.
    335  * @param   pParms              Tone parameters to use.
    336  *
    337  * @note    Blocking function.
    338  */
    339 static int audioTestRecordTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms)
    340 {
    341     const char *pcszPathOut = pTstEnv->Set.szPathAbs;
    342 
    343     RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Recording test tone (for %RU32ms)\n", pParms->msDuration);
    344     RTTestPrintf(g_hTest, RTTESTLVL_DEBUG,  "Writing to '%s'\n", pcszPathOut);
    345 
    346     /** @todo Use .WAV here? */
    347     PAUDIOTESTOBJ pObj;
    348     int rc = AudioTestSetObjCreateAndRegister(&pTstEnv->Set, "guest-tone-rec.pcm", &pObj);
    349     AssertRCReturn(rc, rc);
    350 
    351     if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream))
    352     {
    353         const uint32_t cbPerSched = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint);
    354         AssertStmt(cbPerSched, rc = VERR_INVALID_PARAMETER);
    355               uint32_t cbToRead   = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration);
    356         AssertStmt(cbToRead,   rc = VERR_INVALID_PARAMETER);
    357 
    358         if (RT_SUCCESS(rc))
    359         {
    360             AudioTestSetObjAddMetadataStr(pObj, "buffer_size_ms=%RU32\n", pTstEnv->cMsBufferSize);
    361             AudioTestSetObjAddMetadataStr(pObj, "prebuf_size_ms=%RU32\n", pTstEnv->cMsPreBuffer);
    362             AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint);
    363 
    364363            uint8_t abBuf[_4K];
    365364
     
    444443    const PAUDIOTESTSTREAM pTstStream = &pTstEnv->aStreams[0]; /** @todo Make this dynamic. */
    445444
    446     int rc = audioTestCreateStreamDefaultOut(pTstEnv, pTstStream, &pToneParms->Props);
     445    int rc = audioTestStreamInit(&pTstEnv->DrvStack, pTstStream, PDMAUDIODIR_OUT, &pTstEnv->Props, false /* fWithMixer */,
     446                                 pTstEnv->cMsBufferSize, pTstEnv->cMsPreBuffer, pTstEnv->cMsSchedulingHint);
    447447    if (RT_SUCCESS(rc))
    448448    {
     
    484484    const PAUDIOTESTSTREAM pTstStream = &pTstEnv->aStreams[0]; /** @todo Make this dynamic. */
    485485
    486     int rc = audioTestCreateStreamDefaultIn(pTstEnv, pTstStream, &pToneParms->Props);
     486    int rc = audioTestStreamInit(&pTstEnv->DrvStack, pTstStream, PDMAUDIODIR_IN, &pTstEnv->Props, false /* fWithMixer */,
     487                                 pTstEnv->cMsBufferSize, pTstEnv->cMsPreBuffer, pTstEnv->cMsSchedulingHint);
    487488    if (RT_SUCCESS(rc))
    488489    {
     
    666667    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Temp directory is '%s'\n", pTstEnv->szPathTemp);
    667668
     669    if (!pTstEnv->cMsBufferSize)
     670        pTstEnv->cMsBufferSize     = UINT32_MAX;
     671    if (!pTstEnv->cMsPreBuffer)
     672        pTstEnv->cMsPreBuffer      = UINT32_MAX;
     673    if (!pTstEnv->cMsSchedulingHint)
     674        pTstEnv->cMsSchedulingHint = UINT32_MAX;
     675
    668676    PDMAudioHostEnumInit(&pTstEnv->DevEnum);
    669 
    670     pTstEnv->cMsBufferSize     = 300; /* ms */ /** @todo Randomize this also? */
    671     pTstEnv->cMsPreBuffer      = 150; /* ms */ /** @todo Ditto. */
    672     pTstEnv->cMsSchedulingHint = RTRandU32Ex(10, 80); /* Choose a random scheduling (in ms). */
    673677
    674678    bool fUseDriverStack = false; /* Whether to init + use the audio driver stack or not. */
     
    691695
    692696        PPDMAUDIOHOSTDEV pDev;
    693         rc = audioTestDevicesEnumerateAndCheck(pTstEnv, NULL /* pszDevice */, &pDev); /** @todo Implement device checking. */
     697        rc = audioTestDevicesEnumerateAndCheck(pTstEnv, pTstEnv->szDev, &pDev);
    694698        if (RT_FAILURE(rc))
    695699            return rc;
  • trunk/src/VBox/ValidationKit/utils/audio/vkatInternal.h

    r89837 r89890  
    165165    /** The stream config. */
    166166    PDMAUDIOSTREAMCFG       Cfg;
     167    /** Associated mixing stream. Optional. */
     168    AUDIOTESTDRVMIXSTREAM   Mix;
    167169} AUDIOTESTSTREAM;
    168170/** Pointer to audio test stream. */
     
    184186    /** Whether skip the actual verification or not. */
    185187    bool                    fSkipVerify;
     188    /** The PCM properties to use. */
     189    PDMAUDIOPCMPROPS        Props;
     190    /** Name of the audio device to use.
     191     *  If empty the default audio device will be used. */
     192    char                    szDev[128];
     193    /** Audio volume to use (in percent).
     194     *  Might not be available on all systems. */
     195    uint8_t                 uVolumePercent;
    186196    /** Output path for storing the test environment's final test files. */
    187197    char                    szTag[AUDIOTEST_TAG_MAX];
     
    427437/** @}  */
    428438
    429 int         audioTestWorker(PAUDIOTESTENV pTstEnv, PAUDIOTESTPARMS pOverrideParms);
     439int         audioTestWorker(PAUDIOTESTENV pTstEnv);
    430440
    431441/** @name Command handlers
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