VirtualBox

Changeset 90183 in vbox


Ignore:
Timestamp:
Jul 14, 2021 2:14:32 PM (3 years ago)
Author:
vboxsync
Message:

Audio/ValKit: More code for guest recording tests in the Validation Kit audio driver. bugref:10008

File:
1 edited

Legend:

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

    r90056 r90183  
    5151    /** The stream's acquired configuration. */
    5252    PDMAUDIOSTREAMCFG       Cfg;
     53    /** How much bytes are available to read (only for capturing streams). */
     54    uint32_t                cbAvail;
    5355} VALKITAUDIOSTREAM;
    5456/** Pointer to a Validation Kit stream. */
     
    123125    /** Output path to use. */
    124126    char                szPathOut[RTPATH_MAX];
    125     /** Current test set being handled. */
     127    /** Current test set being handled.
     128     *  At the moment only one test set can be around at a time. */
    126129    AUDIOTESTSET        Set;
    127130    /** Number of total tests created. */
     
    143146    /** Critical section for serializing access across threads. */
    144147    RTCRITSECT          CritSect;
    145     bool                fTestSetEnded;
     148    /** Whether the test set needs to end.
     149     *  Needed for packing up (to archive) and termination, as capturing and playback
     150     *  can run in asynchronous threads. */
     151    bool                fTestSetEnd;
     152    /** Event semaphore for waiting on the current test set to end. */
    146153    RTSEMEVENT          EventSemEnded;
    147154    /** The Audio Test Service (ATS) instance. */
     
    295302        if (AudioTestSetIsRunning(pSet))
    296303        {
    297             pThis->fTestSetEnded = true;
     304            ASMAtomicWriteBool(&pThis->fTestSetEnd, true);
    298305
    299306            rc = RTCritSectLeave(&pThis->CritSect);
     
    655662            pTst                = NULL;
    656663
    657             if (pThis->fTestSetEnded)
     664            if (ASMAtomicReadBool(&pThis->fTestSetEnd))
    658665                rc = RTSemEventSignal(pThis->EventSemEnded);
    659666        }
     
    672679static DECLCALLBACK(uint32_t) drvHostValKitAudioHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    673680{
    674     RT_NOREF(pStream);
    675 
    676     PDRVHOSTVALKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
    677     PVALKITTESTDATA     pTst  = NULL;
     681    PDRVHOSTVALKITAUDIO pThis       = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
     682    PVALKITAUDIOSTREAM  pStrmValKit = (PVALKITAUDIOSTREAM)pStream;
     683    PVALKITTESTDATA     pTst        = NULL;
    678684
    679685    int rc = RTCritSectEnter(&pThis->CritSect);
    680686    if (RT_SUCCESS(rc))
    681687    {
    682         pTst = RTListGetFirst(&pThis->lstTestsRec, VALKITTESTDATA, Node);
     688        if (pThis->pTestCurRec == NULL)
     689        {
     690            pThis->pTestCurRec = RTListGetFirst(&pThis->lstTestsRec, VALKITTESTDATA, Node);
     691            if (pThis->pTestCurRec)
     692                LogRel(("ValKit: Next guest recording test in queue is test #%RU32\n", pThis->pTestCurRec->idxTest));
     693        }
     694
     695        pTst = pThis->pTestCurRec;
    683696
    684697        int rc2 = RTCritSectLeave(&pThis->CritSect);
     
    686699    }
    687700
    688     if (pTst == NULL) /* Empty list? */
    689         return 0;
    690 
    691     Assert(pTst->t.TestTone.u.Rec.cbToWrite >= pTst->t.TestTone.u.Rec.cbWritten);
    692     return pTst->t.TestTone.u.Rec.cbToWrite - pTst->t.TestTone.u.Rec.cbWritten;
     701    if (   pTst
     702        && pTst->pEntry == NULL) /* Test not started yet? */
     703    {
     704        AUDIOTESTPARMS Parms;
     705        RT_ZERO(Parms);
     706        Parms.enmDir   = PDMAUDIODIR_OUT;
     707        Parms.enmType  = AUDIOTESTTYPE_TESTTONE_PLAY;
     708        Parms.TestTone = pTst->t.TestTone.Parms;
     709
     710        rc = AudioTestSetTestBegin(&pThis->Set, "Injecting audio input data to guest",
     711                                    &Parms, &pTst->pEntry);
     712        if (RT_SUCCESS(rc))
     713            rc = AudioTestSetObjCreateAndRegister(&pThis->Set, "host-tone-play.pcm", &pTst->Obj);
     714
     715        if (RT_SUCCESS(rc))
     716        {
     717            pTst->msStartedTS = RTTimeMilliTS();
     718            LogRel(("ValKit: Injecting audio input data (%RU16Hz, %RU32ms, %RU32 bytes) started\n",
     719                    (uint16_t)pTst->t.TestTone.Tone.rdFreqHz,
     720                    pTst->t.TestTone.Parms.msDuration, pTst->t.TestTone.u.Rec.cbToWrite));
     721        }
     722
     723        pStrmValKit->cbAvail += pTst->t.TestTone.u.Rec.cbToWrite;
     724        LogRel(("ValKit: Now total of %RU32 bytes available for capturing\n", pStrmValKit->cbAvail));
     725    }
     726
     727    LogRel(("ValKit: Test #%RU32: Reporting %RU32 bytes as available\n",
     728            pTst ? pTst->idxTest : 9999, pStrmValKit->cbAvail));
     729    return pStrmValKit->cbAvail;
    693730}
    694731
     
    710747                                                                                 PPDMAUDIOBACKENDSTREAM pStream)
    711748{
    712     RT_NOREF(pInterface);
    713749    AssertPtrReturn(pStream, PDMHOSTAUDIOSTREAMSTATE_INVALID);
    714     return PDMHOSTAUDIOSTREAMSTATE_OKAY;
     750
     751    PDRVHOSTVALKITAUDIO     pThis    = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
     752    PDMHOSTAUDIOSTREAMSTATE enmState = PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING;
     753
     754    if (pStream->pStream->Cfg.enmDir == PDMAUDIODIR_IN)
     755    {
     756        int rc2 = RTCritSectEnter(&pThis->CritSect);
     757        if (RT_SUCCESS(rc2))
     758        {
     759            enmState = pThis->cTestsRec == 0
     760                     ? PDMHOSTAUDIOSTREAMSTATE_INACTIVE : PDMHOSTAUDIOSTREAMSTATE_OKAY;
     761
     762            rc2 = RTCritSectLeave(&pThis->CritSect);
     763            AssertRC(rc2);
     764        }
     765    }
     766    else
     767        enmState = PDMHOSTAUDIOSTREAMSTATE_OKAY;
     768
     769    return enmState;
    715770}
    716771
     
    861916    }
    862917
    863     PDRVHOSTVALKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
    864     PVALKITTESTDATA     pTst  = NULL;
     918    PDRVHOSTVALKITAUDIO pThis       = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
     919    PVALKITAUDIOSTREAM  pStrmValKit = (PVALKITAUDIOSTREAM)pStream;
     920    PVALKITTESTDATA     pTst        = NULL;
    865921
    866922    int rc = RTCritSectEnter(&pThis->CritSect);
     
    882938    if (pTst == NULL) /* Empty list? */
    883939    {
    884         LogRelMax(64, ("ValKit: Warning: Guest is trying to record audio data when no recording test is active\n"));
    885 
    886         *pcbRead = 0;
     940        LogRel(("ValKit: Warning: Guest is trying to record %RU32 bytes (%RU32ms) of audio data when no recording test is active (%RU32 bytes available)\n",
     941                cbBuf, PDMAudioPropsBytesToMilli(&pStream->pStream->Cfg.Props, cbBuf), pStrmValKit->cbAvail));
     942
     943        /** @todo Not sure yet why this happens after all data has been captured sometimes,
     944         *        but the guest side just will record silence and the audio test verification
     945         *        will have to deal with (and/or report) it then. */
     946        PDMAudioPropsClearBuffer(&pStream->pStream->Cfg.Props, pvBuf, cbBuf,
     947                                 PDMAudioPropsBytesToFrames(&pStream->pStream->Cfg.Props, cbBuf));
     948
     949        *pcbRead = cbBuf; /* Just report back stuff as being "recorded" (silence). */
    887950        return VINF_SUCCESS;
    888951    }
    889952
    890     if (pTst->pEntry == NULL) /* Test not started yet? */
    891     {
    892         AUDIOTESTPARMS Parms;
    893         RT_ZERO(Parms);
    894         Parms.enmDir   = PDMAUDIODIR_OUT;
    895         Parms.enmType  = AUDIOTESTTYPE_TESTTONE_PLAY;
    896         Parms.TestTone = pTst->t.TestTone.Parms;
    897 
    898         rc = AudioTestSetTestBegin(&pThis->Set, "Injecting audio input data to guest",
    899                                     &Parms, &pTst->pEntry);
    900         if (RT_SUCCESS(rc))
    901             rc = AudioTestSetObjCreateAndRegister(&pThis->Set, "host-tone-play.pcm", &pTst->Obj);
    902 
    903         if (RT_SUCCESS(rc))
    904         {
    905             pTst->msStartedTS = RTTimeMilliTS();
    906             LogRel(("ValKit: Injecting audio input data (%RU16Hz, %RU32ms) started\n",
    907                     (uint16_t)pTst->t.TestTone.Tone.rdFreqHz,
    908                     pTst->t.TestTone.Parms.msDuration));
    909         }
    910     }
    911 
    912953    uint32_t cbRead = 0;
    913954
    914955    if (RT_SUCCESS(rc))
    915956    {
    916         uint32_t cbToWrite = pTst->t.TestTone.u.Rec.cbToWrite - pTst->t.TestTone.u.Rec.cbWritten;
     957        uint32_t cbToWrite = RT_MIN(cbBuf,
     958                                    pTst->t.TestTone.u.Rec.cbToWrite - pTst->t.TestTone.u.Rec.cbWritten);
    917959        if (cbToWrite)
    918             rc = AudioTestToneGenerate(&pTst->t.TestTone.Tone, pvBuf, RT_MIN(cbToWrite, cbBuf), &cbRead);
     960            rc = AudioTestToneGenerate(&pTst->t.TestTone.Tone, pvBuf, cbToWrite, &cbRead);
    919961        if (   RT_SUCCESS(rc)
    920962            && cbRead)
    921963        {
     964            Assert(cbRead == cbToWrite);
     965
     966            if (cbRead > pStrmValKit->cbAvail)
     967                LogRel(("ValKit: Warning: Test #%RU32: Reading more from capturing stream than availabe for (%RU32 vs. %RU32)\n",
     968                        pTst->idxTest, cbRead, pStrmValKit->cbAvail));
     969
     970            pStrmValKit->cbAvail -= RT_MIN(pStrmValKit->cbAvail, cbRead);
     971
    922972            rc = AudioTestObjWrite(pTst->Obj, pvBuf, cbRead);
    923973            if (RT_SUCCESS(rc))
     
    926976                Assert(pTst->t.TestTone.u.Rec.cbWritten <= pTst->t.TestTone.u.Rec.cbToWrite);
    927977
    928                 const bool fComplete = pTst->t.TestTone.u.Rec.cbToWrite >= pTst->t.TestTone.u.Rec.cbWritten;
     978                LogRel(("ValKit: Test #%RU32: Read %RU32 bytes of (capturing) audio data (%RU32 bytes left)\n",
     979                        pTst->idxTest, cbRead, pStrmValKit->cbAvail));
     980
     981                const bool fComplete = pTst->t.TestTone.u.Rec.cbWritten >= pTst->t.TestTone.u.Rec.cbToWrite;
    929982                if (fComplete)
    930983                {
    931                     LogRel(("ValKit: Injecting audio input data done (took %RU32ms)\n",
    932                             RTTimeMilliTS() - pTst->msStartedTS));
     984                    LogRel(("ValKit: Test #%RU32: Recording done (took %RU32ms)\n",
     985                            pTst->idxTest, RTTimeMilliTS() - pTst->msStartedTS));
    933986
    934987                    AudioTestSetTestDone(pTst->pEntry);
     
    9501003    }
    9511004
     1005    if (ASMAtomicReadBool(&pThis->fTestSetEnd))
     1006    {
     1007        int rc2 = RTSemEventSignal(pThis->EventSemEnded);
     1008        AssertRC(rc2);
     1009    }
     1010
    9521011    if (RT_FAILURE(rc))
    9531012    {
    954         if (   pTst
    955             && pTst->pEntry)
     1013        if (pTst->pEntry)
    9561014            AudioTestSetTestFailed(pTst->pEntry, rc, "Injecting audio input data failed");
    957         LogRel(("ValKit: Injecting audio input data failed with %Rrc\n", rc));
     1015        LogRel(("ValKit: Test #%RU32: Failed with %Rrc\n", pTst->idxTest, rc));
    9581016    }
    9591017
     
    10231081    AssertRCReturn(rc, rc);
    10241082
    1025     pThis->fTestSetEnded = false;
     1083    pThis->fTestSetEnd = false;
    10261084
    10271085    RTListInit(&pThis->lstTestsRec);
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