VirtualBox

Changeset 89463 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jun 2, 2021 11:03:47 AM (4 years ago)
Author:
vboxsync
Message:

Audio/ValKit: More code for the Validation Kit audio driver. bugref:10008

Location:
trunk/src/VBox/Devices/Audio
Files:
3 edited

Legend:

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

    r89436 r89463  
    10551055 * @param   cbBuf               Size (in bytes) of \a pvBuf to write.
    10561056 */
    1057 int AudioTestSetObjWrite(PAUDIOTESTOBJ pObj, void *pvBuf, size_t cbBuf)
     1057int AudioTestSetObjWrite(PAUDIOTESTOBJ pObj, const void *pvBuf, size_t cbBuf)
    10581058{
    10591059    /** @todo Generalize this function more once we have more object types. */
  • trunk/src/VBox/Devices/Audio/AudioTest.h

    r89461 r89463  
    366366
    367367int    AudioTestSetObjCreateAndRegister(PAUDIOTESTSET pSet, const char *pszName, PAUDIOTESTOBJ *ppObj);
    368 int    AudioTestSetObjWrite(PAUDIOTESTOBJ pObj, void *pvBuf, size_t cbBuf);
     368int    AudioTestSetObjWrite(PAUDIOTESTOBJ pObj, const void *pvBuf, size_t cbBuf);
    369369int    AudioTestSetObjAddMetadataStr(PAUDIOTESTOBJ pObj, const char *pszFormat, ...);
    370370int    AudioTestSetObjClose(PAUDIOTESTOBJ pObj);
  • trunk/src/VBox/Devices/Audio/DrvHostAudioValidationKit.cpp

    r89458 r89463  
    5858typedef struct VALKITTESTTONEDATA
    5959{
    60     /** How many bytes to write. */
    61     uint64_t           cbToWrite;
    62     /** How many bytes already written. */
    63     uint64_t           cbWritten;
     60    union
     61    {
     62        struct
     63        {
     64            /** How many bytes to write. */
     65            uint64_t           cbToWrite;
     66            /** How many bytes already written. */
     67            uint64_t           cbWritten;
     68        } Rec;
     69        struct
     70        {
     71            /** How many bytes to read. */
     72            uint64_t           cbToRead;
     73            /** How many bytes already read. */
     74            uint64_t           cbRead;
     75        } Play;
     76    } u;
    6477    /** The test tone instance to use. */
    6578    AUDIOTESTTONE      Tone;
     
    7588    /** The list node. */
    7689    RTLISTNODE             Node;
     90    /** Current test set entry to process. */
     91    PAUDIOTESTENTRY        pEntry;
     92    /** Current test object to process. */
     93    PAUDIOTESTOBJ          pObj;
    7794    /** Stream configuration to use for this test. */
    7895    PDMAUDIOSTREAMCFG      StreamCfg;
     
    98115    /** Pointer to host audio interface. */
    99116    PDMIHOSTAUDIO       IHostAudio;
     117    /** Current test set being handled. */
     118    AUDIOTESTSET        Set;
    100119    /** Number of tests in \a lstTestsRec. */
    101120    uint32_t            cTestsRec;
    102121    /** List keeping the recording tests (FIFO). */
    103122    RTLISTANCHOR        lstTestsRec;
    104     /** Pointer to current recording test being processed. */
    105     PVALKITTESTDATA     pTestRecCur;
     123    /** Number of tests in \a lstTestsPlay. */
     124    uint32_t            cTestsPlay;
     125    /** List keeping the recording tests (FIFO). */
     126    RTLISTANCHOR        lstTestsPlay;
     127    /** Pointer to current test being processed. */
     128    PVALKITTESTDATA     pTestCur;
    106129    /** Critical section for serializing access across threads. */
    107130    RTCRITSECT          CritSect;
     
    113136
    114137
    115 /**
    116  * Note: Called within server (client serving) thread.
    117  */
    118 static DECLCALLBACK(int) drvHostValKitAudioSvcTonePlayCallback(void const *pvUser, PAUDIOTESTTONEPARMS pToneParms)
     138
     139static void drvHostValKiUnregisterTest(PVALKITTESTDATA pTst)
     140{
     141    RTListNodeRemove(&pTst->Node);
     142
     143    AudioTestSetObjClose(pTst->pObj);
     144    pTst->pObj = NULL;
     145    AudioTestSetTestDone(pTst->pEntry);
     146    pTst->pEntry = NULL;
     147
     148    RTMemFree(pTst);
     149    pTst = NULL;
     150}
     151
     152static void drvHostValKiUnregisterRecTest(PDRVHOSTVALKITAUDIO pThis, PVALKITTESTDATA pTst)
     153{
     154    drvHostValKiUnregisterTest(pTst);
     155
     156    Assert(pThis->cTestsRec);
     157    pThis->cTestsRec--;
     158}
     159
     160static void drvHostValKiUnregisterPlayTest(PDRVHOSTVALKITAUDIO pThis, PVALKITTESTDATA pTst)
     161{
     162    drvHostValKiUnregisterTest(pTst);
     163
     164    Assert(pThis->cTestsPlay);
     165    pThis->cTestsPlay--;
     166}
     167
     168/** @copydoc ATSCALLBACKS::pfnTonePlay
     169 *
     170 * Creates and registers a new test tone recording test
     171 * which later then gets recorded by the guest side.
     172 */
     173static DECLCALLBACK(int) drvHostValKitRegisterGuestRecTest(void const *pvUser, PAUDIOTESTTONEPARMS pToneParms)
    119174{
    120175    PDRVHOSTVALKITAUDIO pThis = (PDRVHOSTVALKITAUDIO)pvUser;
     
    127182    AudioTestToneInit(&pTestData->t.TestTone.Tone, &pToneParms->Props, pTestData->t.TestTone.Parms.dbFreqHz);
    128183
    129     pTestData->t.TestTone.cbToWrite = PDMAudioPropsMilliToBytes(&pToneParms->Props,
     184    pTestData->t.TestTone.u.Rec.cbToWrite = PDMAudioPropsMilliToBytes(&pToneParms->Props,
     185                                                                      pTestData->t.TestTone.Parms.msDuration);
     186    int rc = RTCritSectEnter(&pThis->CritSect);
     187    if (RT_SUCCESS(rc))
     188    {
     189        LogRel(("Audio: Validation Kit: Registered guest recording test (%RU32ms, %RU64 bytes)\n",
     190                pTestData->t.TestTone.Parms.msDuration, pTestData->t.TestTone.u.Rec.cbToWrite));
     191
     192        RTListAppend(&pThis->lstTestsRec, &pTestData->Node);
     193
     194        pThis->cTestsRec++;
     195
     196        int rc2 = RTCritSectLeave(&pThis->CritSect);
     197        AssertRC(rc2);
     198    }
     199
     200    return VINF_SUCCESS;
     201}
     202
     203/** @copydoc ATSCALLBACKS::pfnToneRecord
     204 *
     205 * Creates and registers a new test tone playback test
     206 * which later then records audio played back by the guest side.
     207 */
     208static DECLCALLBACK(int) drvHostValKitRegisterGuestPlayTest(void const *pvUser, PAUDIOTESTTONEPARMS pToneParms)
     209{
     210    PDRVHOSTVALKITAUDIO pThis = (PDRVHOSTVALKITAUDIO)pvUser;
     211
     212    PVALKITTESTDATA pTestData = (PVALKITTESTDATA)RTMemAllocZ(sizeof(VALKITTESTDATA));
     213    AssertPtrReturn(pTestData, VERR_NO_MEMORY);
     214
     215    memcpy(&pTestData->t.TestTone.Parms, pToneParms, sizeof(AUDIOTESTTONEPARMS));
     216
     217    pTestData->t.TestTone.u.Rec.cbToWrite = PDMAudioPropsMilliToBytes(&pToneParms->Props,
    130218                                                                pTestData->t.TestTone.Parms.msDuration);
    131219    int rc = RTCritSectEnter(&pThis->CritSect);
    132220    if (RT_SUCCESS(rc))
    133221    {
    134         RTListAppend(&pThis->lstTestsRec, &pTestData->Node);
    135 
    136         pThis->cTestsRec++;
     222        LogRel(("Audio: Validation Kit: Registered guest playback test (%RU32ms, %RU64 bytes)\n",
     223                pTestData->t.TestTone.Parms.msDuration, pTestData->t.TestTone.u.Rec.cbToWrite));
     224
     225        RTListAppend(&pThis->lstTestsPlay, &pTestData->Node);
     226
     227        pThis->cTestsPlay++;
    137228
    138229        int rc2 = RTCritSectLeave(&pThis->CritSect);
     
    325416                                                         const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
    326417{
    327     PDRVHOSTVALKITAUDIO pThis      = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
    328     PVALKITAUDIOSTREAM  pStreamDbg = (PVALKITAUDIOSTREAM)pStream;
    329     RT_NOREF(pThis, pStreamDbg, pvBuf, cbBuf);
    330 
    331     *pcbWritten = 0;
    332     return VINF_SUCCESS;
     418    RT_NOREF(pStream);
     419
     420    PDRVHOSTVALKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
     421
     422    int rc = RTCritSectEnter(&pThis->CritSect);
     423    if (RT_SUCCESS(rc))
     424    {
     425        pThis->pTestCur = RTListGetFirst(&pThis->lstTestsPlay, VALKITTESTDATA, Node);
     426
     427        int rc2 = RTCritSectLeave(&pThis->CritSect);
     428        AssertRC(rc2);
     429    }
     430
     431    if (pThis->pTestCur == NULL) /* Empty list? */
     432    {
     433        LogRelMax(64, ("Audio: Validation Kit: Warning: Guest is playing back data when no playback test is active\n"));
     434#ifdef DEBUG_andy
     435        AssertFailed();
     436#endif
     437        *pcbWritten = 0;
     438        return VINF_SUCCESS;
     439    }
     440
     441    PVALKITTESTDATA pTst = pThis->pTestCur;
     442
     443    if (pTst->t.TestTone.u.Play.cbRead == 0)
     444    {
     445        AUDIOTESTPARMS Parms;
     446        RT_ZERO(Parms);
     447        Parms.TestTone = pTst->t.TestTone.Parms;
     448
     449        Assert(pTst->pEntry == NULL);
     450        rc = AudioTestSetTestBegin(&pThis->Set, "Recording audio data from guest",
     451                                    &Parms, &pTst->pEntry);
     452        if (RT_SUCCESS(rc))
     453            rc = AudioTestSetObjCreateAndRegister(&pThis->Set, "guest-output.pcm", &pTst->pObj);
     454
     455        if (RT_SUCCESS(rc))
     456        {
     457            pTst->msStartedTS = RTTimeMilliTS();
     458            LogRel(("Audio: Validation Kit: Recording audio data (%RU16Hz, %RU32ms) started\n",
     459                    (uint16_t)pTst->t.TestTone.Tone.rdFreqHz,
     460                    pTst->t.TestTone.Parms.msDuration));
     461        }
     462    }
     463
     464    uint32_t cbWritten = 0;
     465
     466    if (RT_SUCCESS(rc))
     467    {
     468        uint32_t cbToRead = RT_MIN(cbBuf,
     469                                   pTst->t.TestTone.u.Play.cbToRead- pTst->t.TestTone.u.Play.cbRead);
     470
     471        rc = AudioTestSetObjWrite(pTst->pObj, pvBuf, cbToRead);
     472        if (RT_SUCCESS(rc))
     473        {
     474            pTst->t.TestTone.u.Play.cbRead += cbToRead;
     475
     476            Assert(pTst->t.TestTone.u.Play.cbRead <= pTst->t.TestTone.u.Play.cbToRead);
     477
     478            const bool fComplete = pTst->t.TestTone.u.Play.cbToRead == pTst->t.TestTone.u.Play.cbRead;
     479
     480            if (fComplete)
     481            {
     482                LogRel(("Audio: Validation Kit: Recording audio data done (took %RU32ms)\n",
     483                        RTTimeMilliTS() - pTst->msStartedTS));
     484
     485                rc = RTCritSectEnter(&pThis->CritSect);
     486                if (RT_SUCCESS(rc))
     487                {
     488                    drvHostValKiUnregisterPlayTest(pThis, pTst);
     489
     490                    int rc2 = RTCritSectLeave(&pThis->CritSect);
     491                    AssertRC(rc2);
     492                }
     493            }
     494        }
     495    }
     496
     497    if (RT_FAILURE(rc))
     498    {
     499        if (pTst->pEntry)
     500            AudioTestSetTestFailed(pTst->pEntry, rc, "Recording audio data failed");
     501        LogRel(("Audio: Validation Kit: Recording audio data failed with %Rrc\n", rc));
     502    }
     503
     504    *pcbWritten = cbWritten;
     505
     506    return VINF_SUCCESS; /** @todo Return rc here? */
    333507}
    334508
     
    347521    if (RT_SUCCESS(rc))
    348522    {
    349         pThis->pTestRecCur = RTListGetFirst(&pThis->lstTestsRec, VALKITTESTDATA, Node);
     523        pThis->pTestCur = RTListGetFirst(&pThis->lstTestsRec, VALKITTESTDATA, Node);
    350524
    351525        int rc2 = RTCritSectLeave(&pThis->CritSect);
     
    353527    }
    354528
    355     if (pThis->pTestRecCur == NULL) /* Empty list? */
    356     {
     529    if (pThis->pTestCur == NULL) /* Empty list? */
     530    {
     531        LogRelMax(64, ("Audio: Validation Kit: Warning: Guest is recording audio data when no recording test is active\n"));
     532#ifdef DEBUG_andy
     533        AssertFailed();
     534#endif
    357535        *pcbRead = 0;
    358536        return VINF_SUCCESS;
    359537    }
    360538
    361     PVALKITTESTDATA pTst = pThis->pTestRecCur;
    362 
    363     if (pTst->t.TestTone.cbWritten == 0)
    364     {
    365         pTst->msStartedTS = RTTimeMilliTS();
    366 
    367         LogRel(("Audio: Validation Kit: Injecting input tone (%RU16Hz, %RU32ms)\n",
    368                 (uint16_t)pTst->t.TestTone.Tone.rdFreqHz,
    369                 pTst->t.TestTone.Parms.msDuration));
    370     }
    371 
    372     uint32_t cbToWrite = pTst->t.TestTone.cbToWrite - pTst->t.TestTone.cbWritten;
    373     uint32_t cbRead    = 0;
    374     if (cbToWrite)
    375         rc = AudioTestToneGenerate(&pTst->t.TestTone.Tone, pvBuf, RT_MIN(cbToWrite, cbBuf), &cbRead);
    376 
    377     pTst->t.TestTone.cbWritten += cbRead;
    378     Assert(pTst->t.TestTone.cbWritten <= pTst->t.TestTone.cbToWrite);
    379 
    380     const bool fComplete = pTst->t.TestTone.cbToWrite == pTst->t.TestTone.cbWritten;
    381 
    382     if (fComplete)
    383     {
    384         LogRel(("Audio: Validation Kit: Injection done (took %RU32ms)\n",
    385                 RTTimeMilliTS() - pTst->msStartedTS));
    386 
    387         rc = RTCritSectEnter(&pThis->CritSect);
     539    PVALKITTESTDATA pTst = pThis->pTestCur;
     540
     541    if (pTst->t.TestTone.u.Rec.cbWritten == 0)
     542    {
     543        AUDIOTESTPARMS Parms;
     544        RT_ZERO(Parms);
     545        Parms.TestTone = pTst->t.TestTone.Parms;
     546
     547        Assert(pTst->pEntry == NULL);
     548        rc = AudioTestSetTestBegin(&pThis->Set, "Injecting audio input data to guest",
     549                                    &Parms, &pTst->pEntry);
     550        if (RT_SUCCESS(rc))
     551            rc = AudioTestSetObjCreateAndRegister(&pThis->Set, "host-input.pcm", &pTst->pObj);
     552
    388553        if (RT_SUCCESS(rc))
    389554        {
    390             RTListNodeRemove(&pTst->Node);
    391 
    392             RTMemFree(pTst);
    393             pTst = NULL;
    394 
    395             Assert(pThis->cTestsRec);
    396             pThis->cTestsRec--;
    397 
    398             int rc2 = RTCritSectLeave(&pThis->CritSect);
    399             AssertRC(rc2);
     555            pTst->msStartedTS = RTTimeMilliTS();
     556            LogRel(("Audio: Validation Kit: Injecting audio input data (%RU16Hz, %RU32ms) started\n",
     557                    (uint16_t)pTst->t.TestTone.Tone.rdFreqHz,
     558                    pTst->t.TestTone.Parms.msDuration));
    400559        }
    401560    }
    402561
     562    uint32_t cbRead = 0;
     563
     564    if (RT_SUCCESS(rc))
     565    {
     566        uint32_t cbToWrite = pTst->t.TestTone.u.Rec.cbToWrite - pTst->t.TestTone.u.Rec.cbWritten;
     567        if (cbToWrite)
     568            rc = AudioTestToneGenerate(&pTst->t.TestTone.Tone, pvBuf, RT_MIN(cbToWrite, cbBuf), &cbRead);
     569        if (   RT_SUCCESS(rc)
     570            && cbToWrite)
     571        {
     572            rc = AudioTestSetObjWrite(pTst->pObj, pvBuf, cbToWrite);
     573            if (RT_SUCCESS(rc))
     574            {
     575                pTst->t.TestTone.u.Rec.cbWritten += cbRead;
     576                Assert(pTst->t.TestTone.u.Rec.cbWritten <= pTst->t.TestTone.u.Rec.cbToWrite);
     577
     578                const bool fComplete = pTst->t.TestTone.u.Rec.cbToWrite == pTst->t.TestTone.u.Rec.cbWritten;
     579
     580                if (fComplete)
     581                {
     582                    LogRel(("Audio: Validation Kit: Injecting audio input data done (took %RU32ms)\n",
     583                            RTTimeMilliTS() - pTst->msStartedTS));
     584
     585                    rc = RTCritSectEnter(&pThis->CritSect);
     586                    if (RT_SUCCESS(rc))
     587                    {
     588                        drvHostValKiUnregisterRecTest(pThis, pTst);
     589
     590                        int rc2 = RTCritSectLeave(&pThis->CritSect);
     591                        AssertRC(rc2);
     592                    }
     593                }
     594            }
     595        }
     596    }
     597
     598    if (RT_FAILURE(rc))
     599    {
     600        if (pTst->pEntry)
     601            AudioTestSetTestFailed(pTst->pEntry, rc, "Injecting audio input data failed");
     602        LogRel(("Audio: Validation Kit: Injecting audio input data failed with %Rrc\n", rc));
     603    }
     604
    403605    *pcbRead = cbRead;
    404606
    405     return VINF_SUCCESS;
     607    return VINF_SUCCESS; /** @todo Return rc here? */
    406608}
    407609
     
    458660
    459661    RTListInit(&pThis->lstTestsRec);
    460     pThis->cTestsRec = 0;
     662    pThis->cTestsRec  = 0;
     663    RTListInit(&pThis->lstTestsPlay);
     664    pThis->cTestsPlay = 0;
    461665
    462666    ATSCALLBACKS Callbacks;
    463     Callbacks.pfnTonePlay = drvHostValKitAudioSvcTonePlayCallback;
    464     Callbacks.pvUser      = pThis;
     667    Callbacks.pfnTonePlay   = drvHostValKitRegisterGuestRecTest;
     668    Callbacks.pfnToneRecord = drvHostValKitRegisterGuestPlayTest;
     669    Callbacks.pvUser        = pThis;
    465670
    466671    LogRel(("Audio: Validation Kit: Starting Audio Test Service (ATS) ...\n"));
     
    498703        LogRel(("Audio: Validation Kit: Shutdown of Audio Test Service complete\n"));
    499704
    500         PVALKITTESTDATA pData, pDataNext;
    501         RTListForEachSafe(&pThis->lstTestsRec, pData, pDataNext, VALKITTESTDATA, Node)
    502         {
    503             RTListNodeRemove(&pData->Node);
    504 
    505             RTMemFree(pData);
    506 
    507             Assert(pThis->cTestsRec);
    508             pThis->cTestsRec--;
    509         }
     705        if (pThis->cTestsRec)
     706            LogRel(("Audio: Validation Kit: Warning: %RU32 guest recording tests still outstanding\n", pThis->cTestsRec));
     707        if (pThis->cTestsPlay)
     708            LogRel(("Audio: Validation Kit: Warning: %RU32 guest playback tests still outstanding\n", pThis->cTestsPlay));
     709
     710        PVALKITTESTDATA pTst, pTstNext;
     711        RTListForEachSafe(&pThis->lstTestsRec, pTst, pTstNext, VALKITTESTDATA, Node)
     712            drvHostValKiUnregisterRecTest(pThis, pTst);
     713
     714        RTListForEachSafe(&pThis->lstTestsPlay, pTst, pTstNext, VALKITTESTDATA, Node)
     715            drvHostValKiUnregisterPlayTest(pThis, pTst);
    510716
    511717        Assert(pThis->cTestsRec == 0);
     718        Assert(pThis->cTestsPlay == 0);
    512719    }
    513720    else
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette