VirtualBox

Changeset 89992 in vbox


Ignore:
Timestamp:
Jul 2, 2021 8:56:55 AM (4 years ago)
Author:
vboxsync
Message:

Audio/ValKit: More testing code fixes and additions. bugref:10008

Location:
trunk/src/VBox
Files:
3 edited

Legend:

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

    r89962 r89992  
    719719                                                         const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
    720720{
    721     RT_NOREF(pStream);
    722 
    723721    if (cbBuf == 0)
    724722    {
     
    730728    PDRVHOSTVALKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
    731729
    732     PVALKITTESTDATA pTst = NULL;
     730    bool const fIsSilence = PDMAudioPropsIsBufferSilence(&pStream->pStream->Cfg.Props, pvBuf, cbBuf);
    733731
    734732    int rc = RTCritSectEnter(&pThis->CritSect);
     
    736734    {
    737735        if (pThis->pTestCur == NULL)
     736        {
    738737            pThis->pTestCur = RTListGetFirst(&pThis->lstTestsPlay, VALKITTESTDATA, Node);
    739 
    740         pTst = pThis->pTestCur;
     738            if (pThis->pTestCur)
     739                LogRel(("ValKit: Next guest playback test in queue is test #%RU32\n", pThis->pTestCur->idxTest));
     740        }
    741741
    742742        int rc2 = RTCritSectLeave(&pThis->CritSect);
     
    744744    }
    745745
    746     if (pTst == NULL) /* Empty list? */
    747     {
    748         LogRel(("ValKit: Warning: Guest is playing back data when no playback test is active\n"));
     746    if (pThis->pTestCur == NULL) /* Empty list? */
     747    {
     748#ifdef DEBUG_andy
     749        if (!fIsSilence)
     750#endif
     751            LogRel(("ValKit: Warning: Guest is playing back audio (%s, %RU32 bytes, %RU64ms) when no playback test is active\n",
     752                    fIsSilence ? "silence" : "audible", cbBuf, PDMAudioPropsBytesToMilli(&pStream->pStream->Cfg.Props, cbBuf)));
    749753
    750754        *pcbWritten = cbBuf;
     
    752756    }
    753757
    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     }
     758#ifndef DEBUG_andy
     759    if (fIsSilence)
     760        LogRel2(("ValKit: Guest is playing back %RU32 bytes (%RU64ms) silence\n",
     761                 cbBuf, PDMAudioPropsBytesToMilli(&pStream->pStream->Cfg.Props, cbBuf)));
    762762#endif
    763763
    764     if (pTst->t.TestTone.u.Play.cbRead == 0)
     764    PVALKITTESTDATA pTst = pThis->pTestCur;
     765
     766    const bool fHandleSilence = false; /** @todo Skip blocks of entire silence for now. */
     767
     768    if (pTst->pEntry == NULL)
    765769    {
    766770        AUDIOTESTPARMS Parms;
     
    770774        Parms.TestTone = pTst->t.TestTone.Parms;
    771775
    772         Assert(pTst->pEntry == NULL);
    773776        rc = AudioTestSetTestBegin(&pThis->Set, "Recording audio data from guest",
    774777                                    &Parms, &pTst->pEntry);
     
    788791    if (RT_SUCCESS(rc))
    789792    {
    790         rc = AudioTestSetObjWrite(pTst->pObj, pvBuf, cbBuf);
    791         if (RT_SUCCESS(rc))
    792         {
     793        if (   !fIsSilence
     794            || (fIsSilence && fHandleSilence))
     795        {
     796            rc = AudioTestSetObjWrite(pTst->pObj, pvBuf, cbBuf);
    793797            pTst->t.TestTone.u.Play.cbRead += cbBuf;
    794798
    795         #if 0
    796799            const bool fComplete = pTst->t.TestTone.u.Play.cbRead >= pTst->t.TestTone.u.Play.cbToRead;
    797800            if (fComplete)
     
    804807                            pTst->idxTest, pTst->t.TestTone.u.Play.cbRead - pTst->t.TestTone.u.Play.cbToRead));
    805808
     809                AudioTestSetTestDone(pTst->pEntry);
     810
    806811                rc = RTCritSectEnter(&pThis->CritSect);
    807812                if (RT_SUCCESS(rc))
    808813                {
    809                     AudioTestSetTestDone(pTst->pEntry);
     814                    drvHostValKiUnregisterPlayTest(pThis, pTst);
    810815
    811816                    pThis->pTestCur = NULL;
    812817                    pTst            = NULL;
    813 
    814                     if (pThis->fTestSetEnded)
    815                         rc = RTSemEventSignal(pThis->EventSemEnded);
    816818
    817819                    int rc2 = RTCritSectLeave(&pThis->CritSect);
     
    820822                }
    821823            }
    822         #endif
    823 
    824             cbWritten = cbBuf;
    825         }
     824        }
     825
     826        /* Always report everything as being played. */
     827        cbWritten = cbBuf;
    826828    }
    827829
     
    848850    RT_NOREF(pStream);
    849851
     852    if (cbBuf == 0)
     853    {
     854        /* Fend off draining calls. */
     855        *pcbRead = 0;
     856        return VINF_SUCCESS;
     857    }
     858
    850859    PDRVHOSTVALKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
    851860
     
    854863    {
    855864        if (pThis->pTestCur == NULL)
     865        {
    856866            pThis->pTestCur = RTListGetFirst(&pThis->lstTestsRec, VALKITTESTDATA, Node);
     867            if (pThis->pTestCur)
     868                LogRel(("ValKit: Next guest recording test in queue is test #%RU32\n", pThis->pTestCur->idxTest));
     869        }
    857870
    858871        int rc2 = RTCritSectLeave(&pThis->CritSect);
     
    862875    if (pThis->pTestCur == NULL) /* Empty list? */
    863876    {
    864         LogRelMax(64, ("ValKit: Warning: Guest is recording audio data when no recording test is active\n"));
     877        LogRelMax(64, ("ValKit: Warning: Guest is trying to record audio data when no recording test is active\n"));
    865878
    866879        *pcbRead = 0;
     
    870883    PVALKITTESTDATA pTst = pThis->pTestCur;
    871884
    872     if (pTst->t.TestTone.u.Rec.cbWritten == 0)
     885    if (pTst->pEntry == NULL)
    873886    {
    874887        AUDIOTESTPARMS Parms;
     
    878891        Parms.TestTone = pTst->t.TestTone.Parms;
    879892
    880         Assert(pTst->pEntry == NULL);
    881893        rc = AudioTestSetTestBegin(&pThis->Set, "Injecting audio input data to guest",
    882894                                    &Parms, &pTst->pEntry);
     
    909921                Assert(pTst->t.TestTone.u.Rec.cbWritten <= pTst->t.TestTone.u.Rec.cbToWrite);
    910922
    911                 const bool fComplete = pTst->t.TestTone.u.Rec.cbToWrite == pTst->t.TestTone.u.Rec.cbWritten;
    912 
     923                const bool fComplete = pTst->t.TestTone.u.Rec.cbToWrite >= pTst->t.TestTone.u.Rec.cbWritten;
    913924                if (fComplete)
    914925                {
    915926                    LogRel(("ValKit: Injecting audio input data done (took %RU32ms)\n",
    916927                            RTTimeMilliTS() - pTst->msStartedTS));
     928
     929                    AudioTestSetTestDone(pTst->pEntry);
    917930
    918931                    rc = RTCritSectEnter(&pThis->CritSect);
  • trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp

    r89966 r89992  
    253253    pTstParmsAcq->enmDir      = PDMAUDIODIR_OUT;
    254254#ifdef DEBUG
    255     pTstParmsAcq->cIterations = 1;
     255    pTstParmsAcq->cIterations = 4;
    256256#else
    257257    pTstParmsAcq->cIterations = RTRandU32Ex(1, 10);
     
    265265    pToneParms->msPrequel      = 0; /** @todo Implement analyzing this first! */
    266266#ifdef DEBUG_andy
    267     pToneParms->msDuration     = 2000;
     267    pToneParms->msDuration     = RTRandU32Ex(50, 2500);
    268268#else
    269269    pToneParms->msDuration     = RTRandU32Ex(0, RT_MS_10SEC); /** @todo Probably a bit too long, but let's see. */
     
    286286    for (uint32_t i = 0; i < pTstParms->cIterations; i++)
    287287    {
     288        PAUDIOTESTTONEPARMS const pToneParms = &pTstParms->TestTone;
     289
     290        RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test #%RU32/%RU16: Playing test tone (%RU16Hz, %RU32ms)\n",
     291                     pTstParms->idxCurrent, i, (uint16_t)pToneParms->dbFreqHz, pToneParms->msDuration);
     292
    288293        /*
    289294         * 1. Arm the (host) ValKit ATS with the recording parameters.
    290295         */
    291         PAUDIOTESTTONEPARMS const pToneParms = &pTstParms->TestTone;
    292296        rc = AudioTestSvcClientToneRecord(&pTstEnv->u.Host.AtsClValKit, pToneParms);
    293297        if (RT_SUCCESS(rc))
     
    299303        }
    300304
    301         if (RT_FAILURE(rc))
    302             RTTestFailed(g_hTest, "Playing tone failed\n");
     305        if (RT_SUCCESS(rc))
     306        {
     307            if (pTstParms->cIterations)
     308                RTThreadSleep(RTRandU32Ex(2000, 5000));
     309        }
     310        else
     311            RTTestFailed(g_hTest, "Test #%RU32/%RU16: Playing tone failed\n", pTstParms->idxCurrent, i);
    303312    }
    304313
     
    336345    pTstParmsAcq->enmDir      = PDMAUDIODIR_IN;
    337346#ifdef DEBUG
    338     pTstParmsAcq->cIterations = 1;
     347    pTstParmsAcq->cIterations = 4;
    339348#else
    340349    pTstParmsAcq->cIterations = RTRandU32Ex(1, 10);
     
    342351    pTstParmsAcq->idxCurrent  = 0;
    343352
     353    PAUDIOTESTTONEPARMS pToneParms = &pTstParmsAcq->TestTone;
     354
     355    pToneParms->Props          = pTstParmsAcq->Props;
     356    pToneParms->dbFreqHz       = AudioTestToneGetRandomFreq();
     357    pToneParms->msPrequel      = 0; /** @todo Implement analyzing this first! */
     358    pToneParms->Props          = pTstParmsAcq->Props;
     359#ifdef DEBUG_andy
     360    pToneParms->msDuration     = RTRandU32Ex(50 /* ms */, 2500);
     361#else
     362    pToneParms->msDuration     = RTRandU32Ex(50 /* ms */, RT_MS_30SEC); /** @todo Record even longer? */
     363#endif
     364    pToneParms->msSequel       = 0;   /** @todo Implement analyzing this first! */
     365    pToneParms->uVolumePercent = 100; /** @todo Implement analyzing this first! */
     366
    344367    return rc;
    345368}
     
    356379    for (uint32_t i = 0; i < pTstParms->cIterations; i++)
    357380    {
    358         pTstParms->TestTone.Props      = pTstParms->Props;
    359 #ifdef DEBUG_andy
    360         pTstParms->TestTone.msDuration = RTRandU32Ex(50 /* ms */, 2000);
    361 #else
    362         pTstParms->TestTone.msDuration = RTRandU32Ex(50 /* ms */, RT_MS_30SEC); /** @todo Record even longer? */
    363 #endif
     381        PAUDIOTESTTONEPARMS const pToneParms = &pTstParms->TestTone;
     382
     383        RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test #%RU32/%RU16: Recording test tone (%RU16Hz, %RU32ms)\n",
     384                     pTstParms->idxCurrent, i, (uint16_t)pToneParms->dbFreqHz, pToneParms->msDuration);
     385
    364386        /*
    365387         * 1. Arm the (host) ValKit ATS with the playback parameters.
     
    375397
    376398        if (RT_FAILURE(rc))
    377             RTTestFailed(g_hTest, "Recording tone failed\n");
     399            RTTestFailed(g_hTest, "Test #%RU32/%RU16: Recording tone failed\n", pTstParms->idxCurrent, i);
     400
     401        /* Wait a bit to let the left over audio bits being processed. */
     402        if (pTstParms->cIterations)
     403            RTThreadSleep(RTRandU32Ex(2000, 5000));
    378404    }
    379405
     
    427453    if (pTstDesc->fExcluded)
    428454    {
    429         RTTestSkipped(g_hTest, "Excluded from list");
     455        RTTestSkipped(g_hTest, "Test #%u is excluded from list, skipping", uSeq);
    430456        return VINF_SUCCESS;
    431457    }
     
    438464        if (RT_FAILURE(rc))
    439465        {
    440             RTTestFailed(g_hTest, "Test setup failed with %Rrc\n", rc);
     466            RTTestFailed(g_hTest, "Test #%u setup failed with %Rrc\n", uSeq, rc);
    441467            return rc;
    442468        }
    443469    }
    444470
    445     RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test #%u: %RU32 iterations\n", uSeq, TstParms.cIterations);
     471    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test #%u (%RU32 iterations total)\n", uSeq, TstParms.cIterations);
    446472
    447473    AssertPtr(pTstDesc->pfnExec);
    448474    rc = pTstDesc->pfnExec(pTstEnv, pvCtx, &TstParms);
    449475    if (RT_FAILURE(rc))
    450         RTTestFailed(g_hTest, "Test failed with %Rrc\n", rc);
     476        RTTestFailed(g_hTest, "Test #%u failed with %Rrc\n", uSeq, rc);
    451477
    452478    RTTestSubDone(g_hTest);
     
    459485
    460486        if (RT_FAILURE(rc2))
    461             RTTestFailed(g_hTest, "Test destruction failed with %Rrc\n", rc2);
     487            RTTestFailed(g_hTest, "Test #%u destruction failed with %Rrc\n", uSeq, rc2);
    462488    }
    463489
  • trunk/src/VBox/ValidationKit/utils/audio/vkatCommon.cpp

    r89988 r89992  
    368368    const char *pcszPathOut = pTstEnv->Set.szPathAbs;
    369369
    370     RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Recording test tone (for %RU32ms)\n", pParms->msDuration);
     370    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Recording test tone (tone frequency is %RU16Hz, %RU32ms)\n", (uint16_t)pParms->dbFreqHz, pParms->msDuration);
    371371    RTTestPrintf(g_hTest, RTTESTLVL_DEBUG,  "Writing to '%s'\n", pcszPathOut);
    372372
     
    376376    AssertRCReturn(rc, rc);
    377377
    378     if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream))
    379     {
    380         const uint32_t cbPerSched = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint);
    381         AssertStmt(cbPerSched, rc = VERR_INVALID_PARAMETER);
    382               uint32_t cbToRead   = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration);
    383         AssertStmt(cbToRead,   rc = VERR_INVALID_PARAMETER);
    384 
     378    PAUDIOTESTDRVMIXSTREAM pMix = &pStream->Mix;
     379
     380    rc = AudioTestMixStreamEnable(pMix);
     381    if (RT_SUCCESS(rc))
     382    {
     383        uint64_t cbToRecTotal = PDMAudioPropsMilliToBytes(&pStream->Cfg.Props, pParms->msDuration);
     384
     385        RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Recording %RU32 bytes total\n", cbToRecTotal);
     386
     387        AudioTestSetObjAddMetadataStr(pObj, "stream_to_record_bytes=%RU32\n", cbToRecTotal);
     388        AudioTestSetObjAddMetadataStr(pObj, "stream_buffer_size_ms=%RU32\n", pTstEnv->cMsBufferSize);
     389        AudioTestSetObjAddMetadataStr(pObj, "stream_prebuf_size_ms=%RU32\n", pTstEnv->cMsPreBuffer);
     390        /* Note: This mostly is provided by backend (e.g. PulseAudio / ALSA / ++) and
     391         *       has nothing to do with the device emulation scheduling hint. */
     392        AudioTestSetObjAddMetadataStr(pObj, "device_scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint);
     393
     394        uint8_t         abSamples[16384];
     395        uint32_t const  cbSamplesAligned = PDMAudioPropsFloorBytesToFrame(pMix->pProps, sizeof(abSamples));
     396        uint64_t        cbRecTotal  = 0;
     397        while (!g_fTerminate && cbRecTotal < cbToRecTotal)
     398        {
     399            /*
     400             * Anything we can read?
     401             */
     402            uint32_t const cbCanRead = AudioTestMixStreamGetReadable(pMix);
     403            if (cbCanRead)
     404            {
     405                uint32_t const cbToRead   = RT_MIN(cbCanRead, cbSamplesAligned);
     406                uint32_t       cbRecorded = 0;
     407                rc = AudioTestMixStreamCapture(pMix, abSamples, cbToRead, &cbRecorded);
     408                if (RT_SUCCESS(rc))
     409                {
     410                    if (cbRecorded)
     411                    {
     412                        rc = AudioTestSetObjWrite(pObj, abSamples, cbRecorded);
     413                        if (RT_SUCCESS(rc))
     414                        {
     415                            cbRecTotal += cbRecorded;
     416
     417                            /** @todo Clamp result? */
     418                        }
     419                    }
     420                }
     421            }
     422            else if (AudioTestMixStreamIsOkay(pMix))
     423                RTThreadSleep(RT_MIN(RT_MAX(1, pTstEnv->cMsSchedulingHint), 256));
     424
     425            if (RT_FAILURE(rc))
     426                break;
     427        }
     428
     429        int rc2 = AudioTestMixStreamDisable(pMix);
    385430        if (RT_SUCCESS(rc))
    386         {
    387             AudioTestSetObjAddMetadataStr(pObj, "buffer_size_ms=%RU32\n", pTstEnv->cMsBufferSize);
    388             AudioTestSetObjAddMetadataStr(pObj, "prebuf_size_ms=%RU32\n", pTstEnv->cMsPreBuffer);
    389             AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint);
    390 
    391             uint8_t abBuf[_4K];
    392 
    393             while (cbToRead)
    394             {
    395                 const uint32_t cbChunk = RT_MIN(cbToRead, RT_MIN(cbPerSched, sizeof(abBuf)));
    396 
    397                 uint32_t cbRead = 0;
    398                 rc = audioTestDriverStackStreamCapture(&pTstEnv->DrvStack, pStream->pStream, (void *)abBuf, cbChunk, &cbRead);
    399                 if (RT_SUCCESS(rc))
    400                     rc = AudioTestSetObjWrite(pObj, abBuf, cbRead);
    401 
    402                 if (RT_FAILURE(rc))
    403                     break;
    404 
    405                 RTThreadSleep(pTstEnv->cMsSchedulingHint);
    406 
    407                 Assert(cbToRead >= cbRead);
    408                 cbToRead -= cbRead;
    409             }
    410         }
    411     }
    412     else
    413         rc = VERR_AUDIO_STREAM_NOT_READY;
     431            rc = rc2;
     432    }
    414433
    415434    int rc2 = AudioTestSetObjClose(pObj);
     
    465484    PATSCALLBACKCTX pCtx    = (PATSCALLBACKCTX)pvUser;
    466485    PAUDIOTESTENV   pTstEnv = pCtx->pTstEnv;
    467 
    468     AUDIOTESTTONE TstTone;
    469     AudioTestToneInitRandom(&TstTone, &pToneParms->Props);
    470486
    471487    const PAUDIOTESTSTREAM pTstStream = &pTstEnv->aStreams[0]; /** @todo Make this dynamic. */
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