VirtualBox

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


Ignore:
Timestamp:
Nov 16, 2021 10:37:30 AM (3 years ago)
Author:
vboxsync
Message:

Audio/Validation Kit: More capturing code for the Validation Kit audio driver -- now also using the pre/post/run stages. bugref:10008

File:
1 edited

Legend:

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

    r92438 r92450  
    5757    /** The stream's acquired configuration. */
    5858    PDMAUDIOSTREAMCFG       Cfg;
    59     /** How much bytes are available to read (only for capturing streams). */
    60     uint32_t                cbAvail;
    6159#ifdef VBOX_WITH_AUDIO_VALKIT_DUMP_STREAMS
    6260    /** Audio file to dump output to. */
     
    741739    RT_NOREF(pThis);
    742740
    743     int rc = VINF_SUCCESS;
    744741    PDMAudioStrmCfgCopy(&pStreamValKit->Cfg, pCfgAcq);
    745742
     743    int rc2;
    746744#ifdef VBOX_WITH_AUDIO_VALKIT_DUMP_STREAMS
    747     int rc2 = AudioHlpFileCreateAndOpenEx(&pStreamValKit->pFile, AUDIOHLPFILETYPE_WAV, NULL /*use temp dir*/,
    748                                           pThis->pDrvIns->iInstance, AUDIOHLPFILENAME_FLAGS_NONE, AUDIOHLPFILE_FLAGS_NONE,
    749                                           &pCfgReq->Props, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE,
    750                                           pCfgReq->enmDir == PDMAUDIODIR_IN ? "ValKitAudioIn" : "ValKitAudioOut");
     745    rc2 = AudioHlpFileCreateAndOpenEx(&pStreamValKit->pFile, AUDIOHLPFILETYPE_WAV, NULL /*use temp dir*/,
     746                                      pThis->pDrvIns->iInstance, AUDIOHLPFILENAME_FLAGS_NONE, AUDIOHLPFILE_FLAGS_NONE,
     747                                      &pCfgReq->Props, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE,
     748                                      pCfgReq->enmDir == PDMAUDIODIR_IN ? "ValKitAudioIn" : "ValKitAudioOut");
    751749    if (RT_FAILURE(rc2))
    752750        LogRel(("ValKit: Failed to creating debug file for %s stream '%s' in the temp directory: %Rrc\n",
     
    754752#endif
    755753
     754    int rc = RTCritSectEnter(&pThis->CritSect);
     755    if (RT_SUCCESS(rc))
     756    {
     757        if (pThis->pTestCurRec == NULL)
     758        {
     759            pThis->pTestCurRec = RTListGetFirst(&pThis->lstTestsRec, VALKITTESTDATA, Node);
     760            if (pThis->pTestCurRec)
     761                LogRel(("ValKit: Next guest recording test in queue is test #%RU32\n", pThis->pTestCurRec->idxTest));
     762        }
     763
     764        PVALKITTESTDATA pTst = pThis->pTestCurRec;
     765
     766        /* If we have a test registered and in the queue coming up next, use
     767         * the beacon size (if any, could be 0) as pre-buffering requirement. */
     768        if (pTst)
     769        {
     770            const uint32_t cFramesBeacon = PDMAudioPropsBytesToFrames(&pCfgAcq->Props,
     771                                                                      AudioTestBeaconGetSize(&pTst->t.TestTone.Beacon));
     772            if (cFramesBeacon) /* Only assign if not 0, otherwise stay with the default. */
     773                pCfgAcq->Backend.cFramesPreBuffering = cFramesBeacon;
     774        }
     775
     776        rc2 = RTCritSectLeave(&pThis->CritSect);
     777        AssertRC(rc2);
     778    }
     779
    756780    return rc;
    757781}
     
    834858static DECLCALLBACK(uint32_t) drvHostValKitAudioHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    835859{
    836     PDRVHOSTVALKITAUDIO pThis       = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
    837     PVALKITAUDIOSTREAM  pStrmValKit = (PVALKITAUDIOSTREAM)pStream;
    838     PVALKITTESTDATA     pTst        = NULL;
     860    PDRVHOSTVALKITAUDIO pThis         = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
     861    PVALKITAUDIOSTREAM  pStreamValKit = (PVALKITAUDIOSTREAM)pStream;
     862
     863    if (pStreamValKit->Cfg.enmDir == PDMAUDIODIR_OUT)
     864    {
     865        LogRel(("ValKit: Warning: Trying to read from non-input stream '%s' -- report this bug!\n",
     866                pStreamValKit->Cfg.szName));
     867        return 0;
     868    }
     869
     870    /* We return UINT32_MAX by default (when no tests are running [anymore] for not being marked
     871     * as "unreliable stream" in the audio mixer. See audioMixerSinkUpdateInput(). */
     872    uint32_t cbReadable = UINT32_MAX;
    839873
    840874    int rc = RTCritSectEnter(&pThis->CritSect);
     
    848882        }
    849883
    850         pTst = pThis->pTestCurRec;
     884        PVALKITTESTDATA pTst = pThis->pTestCurRec;
     885        if (pTst)
     886        {
     887            switch (pTst->enmState)
     888            {
     889                case AUDIOTESTSTATE_INIT:
     890                    RT_FALL_THROUGH();
     891                case AUDIOTESTSTATE_PRE:
     892                    RT_FALL_THROUGH();
     893                case AUDIOTESTSTATE_POST:
     894                {
     895                    cbReadable = AudioTestBeaconGetRemaining(&pTst->t.TestTone.Beacon);
     896                    break;
     897                }
     898
     899                case AUDIOTESTSTATE_RUN:
     900                {
     901                    AssertBreakStmt(pTst->t.TestTone.u.Rec.cbToWrite >= pTst->t.TestTone.u.Rec.cbWritten,
     902                                    rc = VERR_INVALID_STATE);
     903                    cbReadable = pTst->t.TestTone.u.Rec.cbToWrite - pTst->t.TestTone.u.Rec.cbWritten;
     904                    break;
     905                }
     906
     907                case AUDIOTESTSTATE_DONE:
     908                    RT_FALL_THROUGH();
     909                default:
     910                    break;
     911            }
     912
     913            LogRel2(("ValKit: Test #%RU32: Reporting %RU32 bytes readable (state is '%s')\n",
     914                     pTst->idxTest, cbReadable, AudioTestStateToStr(pTst->enmState)));
     915
     916            if (cbReadable == 0)
     917                LogRel2(("ValKit: Test #%RU32: Warning: Not readable anymore (state is '%s'), returning 0\n",
     918                         pTst->idxTest, AudioTestStateToStr(pTst->enmState)));
     919        }
    851920
    852921        int rc2 = RTCritSectLeave(&pThis->CritSect);
     
    854923    }
    855924
    856     if (   pTst
    857         && pTst->enmState == AUDIOTESTSTATE_INIT) /* Test not started yet? */
    858     {
    859         AUDIOTESTPARMS Parms;
    860         RT_ZERO(Parms);
    861         Parms.enmDir   = PDMAUDIODIR_OUT;
    862         Parms.enmType  = AUDIOTESTTYPE_TESTTONE_PLAY;
    863         Parms.TestTone = pTst->t.TestTone.Parms;
    864 
    865         rc = AudioTestSetTestBegin(&pThis->Set, "Injecting audio input data to guest",
    866                                     &Parms, &pTst->pEntry);
    867         if (RT_SUCCESS(rc))
    868             rc = AudioTestSetObjCreateAndRegister(&pThis->Set, "host-tone-play.pcm", &pTst->Obj);
    869 
    870         if (RT_SUCCESS(rc))
    871         {
    872             pTst->msStartedTS = RTTimeMilliTS();
    873             LogRel(("ValKit: Test #%RU32: Injecting audio input data (%RU16Hz, %RU32ms, %RU32 bytes) for host test #%RU32 started (delay is %RU32ms)\n",
    874                     pTst->idxTest, (uint16_t)pTst->t.TestTone.Tone.rdFreqHz,
    875                     pTst->t.TestTone.Parms.msDuration, pTst->t.TestTone.u.Rec.cbToWrite,
    876                     Parms.TestTone.Hdr.idxTest, RTTimeMilliTS() - pTst->msRegisteredTS));
    877 
    878             char szTimeCreated[RTTIME_STR_LEN];
    879             RTTimeToString(&Parms.TestTone.Hdr.tsCreated, szTimeCreated, sizeof(szTimeCreated));
    880             LogRel2(("ValKit: Test created (caller UTC): %s\n", szTimeCreated));
    881         }
    882 
    883         pStrmValKit->cbAvail += pTst->t.TestTone.u.Rec.cbToWrite;
    884         pStrmValKit->cbAvail += AudioTestBeaconGetSize(&pTst->t.TestTone.Beacon); /* Add beacon data, if any. */
    885         LogRel2(("ValKit: Now total of %RU32 bytes available for capturing\n", pStrmValKit->cbAvail));
    886 
    887         pTst->enmState = AUDIOTESTSTATE_PRE;
    888     }
    889 
    890     return pStrmValKit->cbAvail;
     925    if (RT_FAILURE(rc))
     926        LogRel(("ValKit: Reporting readable bytes failed with %Rrc\n", rc));
     927
     928    Log3Func(("returns %#x (%RU32)\n", cbReadable, cbReadable));
     929    return cbReadable;
    891930}
    892931
     
    12591298    }
    12601299
    1261     PDRVHOSTVALKITAUDIO pThis       = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
    1262     PVALKITAUDIOSTREAM  pStrmValKit = (PVALKITAUDIOSTREAM)pStream;
    1263     PVALKITTESTDATA     pTst        = NULL;
     1300    PDRVHOSTVALKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio);
     1301    PVALKITTESTDATA     pTst  = NULL;
    12641302
    12651303    LogRel3(("ValKit: Capturing stream '%s' (%RU32 bytes / %RU64ms -- %RU64 bytes / %RU64ms total so far) ...\n",
     
    12891327    if (pTst == NULL) /* Empty list? */
    12901328    {
    1291         LogRel(("ValKit: Warning: Guest is trying to record audio data when no recording test is active (%RU32 bytes available)\n",
    1292                 pStrmValKit->cbAvail));
     1329        LogRel(("ValKit: Warning: Guest is trying to record audio data when no recording test is active\n"));
    12931330
    12941331        /** @todo Not sure yet why this happens after all data has been captured sometimes,
     
    13061343    switch (pTst->enmState)
    13071344    {
     1345        case AUDIOTESTSTATE_INIT: /* Test not started yet? */
     1346        {
     1347            AUDIOTESTPARMS Parms;
     1348            RT_ZERO(Parms);
     1349            Parms.enmDir   = PDMAUDIODIR_OUT;
     1350            Parms.enmType  = AUDIOTESTTYPE_TESTTONE_PLAY;
     1351            Parms.TestTone = pTst->t.TestTone.Parms;
     1352
     1353            rc = AudioTestSetTestBegin(&pThis->Set, "Injecting audio input data to guest",
     1354                                        &Parms, &pTst->pEntry);
     1355            if (RT_SUCCESS(rc))
     1356                rc = AudioTestSetObjCreateAndRegister(&pThis->Set, "host-tone-play.pcm", &pTst->Obj);
     1357
     1358            if (RT_SUCCESS(rc))
     1359            {
     1360                pTst->msStartedTS = RTTimeMilliTS();
     1361                LogRel(("ValKit: Test #%RU32: Injecting audio input data (%RU16Hz, %RU32ms, %RU32 bytes) for host test #%RU32 started (delay is %RU32ms)\n",
     1362                        pTst->idxTest, (uint16_t)pTst->t.TestTone.Tone.rdFreqHz,
     1363                        pTst->t.TestTone.Parms.msDuration, pTst->t.TestTone.u.Rec.cbToWrite,
     1364                        Parms.TestTone.Hdr.idxTest, RTTimeMilliTS() - pTst->msRegisteredTS));
     1365
     1366                char szTimeCreated[RTTIME_STR_LEN];
     1367                RTTimeToString(&Parms.TestTone.Hdr.tsCreated, szTimeCreated, sizeof(szTimeCreated));
     1368                LogRel2(("ValKit: Test created (caller UTC): %s\n", szTimeCreated));
     1369
     1370                pTst->enmState = AUDIOTESTSTATE_PRE;
     1371            }
     1372            else
     1373                break;
     1374
     1375            RT_FALL_THROUGH();
     1376        }
     1377
    13081378        case AUDIOTESTSTATE_PRE:
    13091379            RT_FALL_THROUGH();
     
    13541424            {
    13551425                Assert(cbWritten == cbToWrite);
    1356 
    1357                 if (cbWritten > pStrmValKit->cbAvail)
    1358                     LogRel(("ValKit: Warning: Test #%RU32: Reading more from capturing stream than availabe for (%RU32 vs. %RU32)\n",
    1359                             pTst->idxTest, cbWritten, pStrmValKit->cbAvail));
    1360 
    13611426                pTst->t.TestTone.u.Rec.cbWritten += cbWritten;
    13621427            }
    13631428
    13641429            LogRel3(("ValKit: Test #%RU32: Supplied %RU32 bytes of (capturing) audio data (%RU32 bytes left)\n",
    1365                      pTst->idxTest, cbWritten, pStrmValKit->cbAvail));
     1430                     pTst->idxTest, cbWritten, pTst->t.TestTone.u.Rec.cbToWrite - pTst->t.TestTone.u.Rec.cbWritten));
    13661431
    13671432            const bool fComplete = pTst->t.TestTone.u.Rec.cbWritten >= pTst->t.TestTone.u.Rec.cbToWrite;
     
    13761441                AudioTestBeaconInit(&pTst->t.TestTone.Beacon, pTst->idxTest, AUDIOTESTTONEBEACONTYPE_PLAY_POST,
    13771442                                    &pTst->t.TestTone.Parms.Props);
    1378 
    1379                 pStrmValKit->cbAvail += AudioTestBeaconGetSize(&pTst->t.TestTone.Beacon);
    13801443            }
    13811444            break;
     
    13941457
    13951458    if (RT_SUCCESS(rc))
    1396     {
    13971459        rc = AudioTestObjWrite(pTst->Obj, pvBuf, cbWritten);
    1398         if (RT_SUCCESS(rc))
    1399             pStrmValKit->cbAvail -= RT_MIN(pStrmValKit->cbAvail, cbWritten);
    1400     }
    14011460
    14021461    if (pTst->enmState == AUDIOTESTSTATE_DONE)
     
    14281487    *pcbRead = cbWritten;
    14291488
     1489    Log3Func(("returns %Rrc *pcbRead=%#x (%#x/%#x), %#x total\n",
     1490              rc, cbWritten, pTst ? pTst->t.TestTone.u.Rec.cbWritten : 0, pTst ? pTst->t.TestTone.u.Rec.cbToWrite : 0,
     1491              pThis->cbRecordedTotal));
    14301492    return VINF_SUCCESS; /** @todo Return rc here? */
    14311493}
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