VirtualBox

Changeset 92234 in vbox for trunk/src


Ignore:
Timestamp:
Nov 5, 2021 8:44:14 AM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
148068
Message:

Audio/Validation Kit: More code for audio data beacon handling. Now has dedicated beacons for recording / playback tests. bugref:10008

Location:
trunk/src/VBox
Files:
4 edited

Legend:

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

    r92211 r92234  
    24582458 * Adds audio data to a given beacon.
    24592459 *
    2460  * @returns Bytes added to the beacon, or 0 if invalid / nothing was added.
     2460 * @returns VBox status code, VERR_NOT_FOUND if not beacon data was not found.
    24612461 * @param   pBeacon             Beacon to add data for.
    24622462 * @param   pauBuf              Buffer of audio data to add.
    24632463 * @param   cbBuf               Size (in bytes) of \a pauBuf.
     2464 * @param   pOff                Where to return the offset within \a pauBuf where beacon ended on success.
     2465 *                              Optional and can be NULL.
    24642466 *
    24652467 * @note    The audio data must be a) match the beacon type and b) consecutive, that is, without any gaps,
    24662468 *          to be added as valid to the beacon.
    24672469 */
    2468 uint32_t AudioTestBeaconAddConsecutive(PAUDIOTESTTONEBEACON pBeacon, const uint8_t *pauBuf, size_t cbBuf)
    2469 {
     2470int AudioTestBeaconAddConsecutive(PAUDIOTESTTONEBEACON pBeacon, const uint8_t *pauBuf, size_t cbBuf, size_t *pOff)
     2471{
     2472    AssertPtrReturn(pBeacon, VERR_INVALID_POINTER);
     2473    AssertPtrReturn(pauBuf,  VERR_INVALID_POINTER);
     2474    /* pOff is optional. */
     2475
     2476    size_t         offBeacon   = UINT64_MAX;
    24702477    uint32_t const cbFrameSize = PDMAudioPropsFrameSize(&pBeacon->Props); /* Use the audio frame size as chunk size. */
    2471 
    2472     if (cbBuf < cbFrameSize) /* Fend-off data which isn't at least one full frame. */
    2473         return 0;
    2474 
    2475     AssertMsgReturn(cbBuf % cbFrameSize == 0,
    2476                     ("Buffer size must be frame-aligned"), 0);
    24772478
    24782479    uint8_t  const byBeacon      = AudioTestBeaconByteFromType(pBeacon->enmType);
    24792480    unsigned const cbStep        = cbFrameSize;
    2480     uint32_t const cbUsedInitial = pBeacon->cbUsed;
     2481
     2482    /* Make sure that we do frame-aligned reads. */
     2483    cbBuf = PDMAudioPropsFloorBytesToFrame(&pBeacon->Props, cbBuf);
    24812484
    24822485    for (size_t i = 0; i < cbBuf; i += cbStep)
     
    24872490            && pauBuf[i + 3] == byBeacon)
    24882491        {
    2489             pBeacon->cbUsed += cbStep;
    2490 
    2491             if (pBeacon->cbUsed > pBeacon->cbSize)
    2492                 pBeacon->cbUsed -= pBeacon->cbSize;
     2492            /* Make sure to handle overflows and let beacon start from scratch. */
     2493            pBeacon->cbUsed = (pBeacon->cbUsed + cbStep) % pBeacon->cbSize;
     2494            if (pBeacon->cbUsed == 0) /* Beacon complete (see module line above)? */
     2495            {
     2496                pBeacon->cbUsed = pBeacon->cbSize;
     2497                offBeacon       = i + cbStep; /* Point to data right *after* the beacon. */
     2498            }
    24932499        }
    24942500        else
    24952501        {
    24962502            /* If beacon is not complete yet, we detected a gap here. Start all over then. */
    2497             if (pBeacon->cbUsed < pBeacon->cbSize)
     2503            if (RT_LIKELY(pBeacon->cbUsed != pBeacon->cbSize))
    24982504                pBeacon->cbUsed = 0;
    24992505        }
    25002506    }
    25012507
    2502     if (!pBeacon->cbUsed)
    2503         return 0;
    2504 
    2505     AssertMsg(pBeacon->cbUsed >= cbUsedInitial, ("cbUsed (%RU32) < cbUsedInitial (%RU32)\n", pBeacon->cbUsed, cbUsedInitial));
    2506     return pBeacon->cbUsed - cbUsedInitial;
     2508    if (offBeacon != UINT32_MAX)
     2509    {
     2510        if (pOff)
     2511            *pOff = offBeacon;
     2512    }
     2513
     2514    return offBeacon == UINT64_MAX ? VERR_NOT_FOUND : VINF_SUCCESS;
    25072515}
    25082516
     
    25312539 * @param   pToneParms          Tone parameters to use for verification.
    25322540 * @param   puOff               Where to return the absolute file offset (in bytes) right after the found beacon on success.
     2541 *                              Optional and can be NULL.
    25332542 */
    25342543static int audioTestToneVerifyBeacon(PAUDIOTESTVERIFYJOB pVerJob,
     
    25452554                        : (fPre ? AUDIOTESTTONEBEACONTYPE_REC_PRE  : AUDIOTESTTONEBEACONTYPE_REC_POST), &pToneParms->Props);
    25462555
    2547     LogRel2(("Verifying %s beacon @ %RU64\n", AudioTestBeaconTypeGetName(Beacon.enmType), pCmp->offStart));
    2548 
    2549     uint8_t        auBuf[64];
     2556    uint8_t        auBuf[_64K];
    25502557    uint64_t       cbToCompare   = pCmp->cbSize;
    25512558    uint32_t const cbFrameSize   = PDMAudioPropsFrameSize(&Beacon.Props);
    2552     uint64_t       offBeaconLast = 0;
    2553 
    2554     /* Slow as heck, but does the job for now. */
     2559    uint64_t       offBeaconLast = UINT64_MAX;
     2560
     2561    Assert(sizeof(auBuf) % cbFrameSize == 0);
     2562
    25552563    while (cbToCompare)
    25562564    {
    25572565        size_t cbRead;
    2558         rc = RTFileRead(pCmp->hFile, auBuf, RT_MIN(cbToCompare, cbFrameSize), &cbRead);
     2566        rc = RTFileRead(pCmp->hFile, auBuf, RT_MIN(cbToCompare, sizeof(auBuf)), &cbRead);
    25592567        AssertRCBreak(rc);
    25602568
     
    25622570            break;
    25632571
    2564         const uint32_t cbAdded = AudioTestBeaconAddConsecutive(&Beacon, auBuf, cbRead);
    2565         if (cbAdded)
    2566             offBeaconLast = RTFileTell(pCmp->hFile);
     2572        size_t uOff;
     2573        int rc2 = AudioTestBeaconAddConsecutive(&Beacon, auBuf, cbRead, &uOff);
     2574        if (RT_SUCCESS(rc2))
     2575        {
     2576            /* Save the last found (absolute bytes, in file) position of a (partially) found beacon. */
     2577            offBeaconLast = RTFileTell(pCmp->hFile) - (cbRead - uOff);
     2578        }
    25672579
    25682580        Assert(cbToCompare >= cbRead);
     
    25852597    {
    25862598        AssertReturn(AudioTestBeaconGetRemaining(&Beacon) == 0, VERR_INTERNAL_ERROR);
     2599        AssertReturn(offBeaconLast != UINT32_MAX, VERR_INTERNAL_ERROR);
    25872600        AssertReturn(offBeaconLast >= AudioTestBeaconGetSize(&Beacon), VERR_INTERNAL_ERROR);
    25882601
     
    29812994    pOpts->fNormalize      = false; /* Skip normalization by default now, as we now use the OS' master volume to play/record tones. */
    29822995    pOpts->cMaxDiff        = 0;     /* By default we're very strict and consider any diff as being erroneous. */
    2983     pOpts->uMaxSizePercent = 1;     /* 1% is okay for us; might be due to any buffering / setup phase. */
    2984 
    2985     /* We use a search window of 10ms by default for finding (non-)silent parts. */
    2986     pOpts->msSearchWindow  = 10;
    2987 
     2996    pOpts->uMaxSizePercent = 10;    /* 10% is okay for us for now; might be due to any buffering / setup phase.
     2997                                       Anything above this is suspicious and should be reported for further investigation. */
     2998    pOpts->msSearchWindow  = 10;    /* We use a search window of 10ms by default for finding (non-)silent parts. */
    29882999}
    29893000
  • TabularUnified trunk/src/VBox/Devices/Audio/AudioTest.h

    r92211 r92234  
    378378
    379379void   AudioTestBeaconInit(PAUDIOTESTTONEBEACON pBeacon, AUDIOTESTTONEBEACONTYPE enmType, PPDMAUDIOPCMPROPS pProps);
    380 uint32_t AudioTestBeaconAddConsecutive(PAUDIOTESTTONEBEACON pBeacon, const uint8_t *auBuf, size_t cbBuf);
     380int    AudioTestBeaconAddConsecutive(PAUDIOTESTTONEBEACON pBeacon, const uint8_t *auBuf, size_t cbBuf, size_t *pOff);
    381381int    AudioTestBeaconWrite(PAUDIOTESTTONEBEACON pBeacon, void *pvBuf, uint32_t cbBuf);
    382382uint32_t AudioTestBeaconGetSize(PCAUDIOTESTTONEBEACON pBeacon);
  • TabularUnified trunk/src/VBox/Devices/Audio/DrvHostAudioValidationKit.cpp

    r92211 r92234  
    298298                    pTst->idxTest, AudioTestStateToStr(pTst->enmState)));
    299299
    300         size_t const cbOutstanding = pTst->t.TestTone.u.Rec.cbToWrite - pTst->t.TestTone.u.Rec.cbWritten;
    301         if (cbOutstanding)
    302             LogRel(("ValKit: \tWarning: Recording test #%RU32 has %RU64 bytes (%RU32ms) outstanding (%RU8%% left)\n",
    303                     pTst->idxTest, cbOutstanding, PDMAudioPropsBytesToMilli(&pTst->t.TestTone.Parms.Props, (uint32_t)cbOutstanding),
    304                     100 - (pTst->t.TestTone.u.Rec.cbWritten * 100) / RT_MAX(pTst->t.TestTone.u.Rec.cbToWrite, 1)));
     300        if (pTst->t.TestTone.u.Rec.cbToWrite > pTst->t.TestTone.u.Rec.cbWritten)
     301        {
     302            size_t const cbOutstanding = pTst->t.TestTone.u.Rec.cbToWrite - pTst->t.TestTone.u.Rec.cbWritten;
     303            if (cbOutstanding)
     304                LogRel(("ValKit: \tWarning: Recording test #%RU32 has %RU64 bytes (%RU32ms) outstanding (%RU8%% left)\n",
     305                        pTst->idxTest, cbOutstanding, PDMAudioPropsBytesToMilli(&pTst->t.TestTone.Parms.Props, (uint32_t)cbOutstanding),
     306                        100 - (pTst->t.TestTone.u.Rec.cbWritten * 100) / RT_MAX(pTst->t.TestTone.u.Rec.cbToWrite, 1)));
     307        }
    305308        drvHostValKiUnregisterRecTest(pThis, pTst);
    306309    }
     
    315318                    pTst->idxTest, AudioTestStateToStr(pTst->enmState)));
    316319
    317         size_t const cbOutstanding = pTst->t.TestTone.u.Play.cbToRead - pTst->t.TestTone.u.Play.cbRead;
    318         if (cbOutstanding)
    319             LogRel(("ValKit: \tWarning: Playback test #%RU32 has %RU64 bytes (%RU32ms) outstanding (%RU8%% left)\n",
    320                     pTst->idxTest, cbOutstanding, PDMAudioPropsBytesToMilli(&pTst->t.TestTone.Parms.Props, (uint32_t)cbOutstanding),
    321                     100 - (pTst->t.TestTone.u.Play.cbRead * 100) / RT_MAX(pTst->t.TestTone.u.Play.cbToRead, 1)));
     320        if (pTst->t.TestTone.u.Play.cbToRead > pTst->t.TestTone.u.Play.cbRead)
     321        {
     322            size_t const cbOutstanding = pTst->t.TestTone.u.Play.cbToRead - pTst->t.TestTone.u.Play.cbRead;
     323            if (cbOutstanding)
     324                LogRel(("ValKit: \tWarning: Playback test #%RU32 has %RU64 bytes (%RU32ms) outstanding (%RU8%% left)\n",
     325                        pTst->idxTest, cbOutstanding, PDMAudioPropsBytesToMilli(&pTst->t.TestTone.Parms.Props, (uint32_t)cbOutstanding),
     326                        100 - (pTst->t.TestTone.u.Play.cbRead * 100) / RT_MAX(pTst->t.TestTone.u.Play.cbToRead, 1)));
     327        }
    322328        drvHostValKiUnregisterPlayTest(pThis, pTst);
    323329    }
     
    10301036    if (RT_SUCCESS(rc))
    10311037    {
    1032         /* Always write (record) everything, no matter if the current audio contains complete silence or not.
    1033          * Might be also become handy later if we want to have a look at start/stop timings and so on. */
    1034         rc = AudioTestObjWrite(pTst->Obj, pvBuf, cbBuf);
    1035 
    10361038        switch (pTst->enmState)
    10371039        {
     
    10461048                    bool const fStarted = AudioTestBeaconGetRemaining(pBeacon) == AudioTestBeaconGetSize(pBeacon);
    10471049
    1048                     /* Limit adding data to the beacon size. */
    1049                     uint32_t const cbToAddMax = RT_MIN(cbBuf, AudioTestBeaconGetRemaining(pBeacon));
    1050 
    1051                     AudioTestBeaconAddConsecutive(pBeacon, (uint8_t *)pvBuf, cbToAddMax);
    1052                     /** @todo Take left-over data into account (and stash them away for the test tone)? */
     1050                    size_t uOff; /* Points at the data right *after the found beacon data. */
     1051                    rc2 = AudioTestBeaconAddConsecutive(pBeacon, (uint8_t *)pvBuf, cbBuf, &uOff);
     1052                    if (RT_SUCCESS(rc2))
     1053                    {
     1054                        /*
     1055                         * When being in the AUDIOTESTSTATE_PRE state, we might get more audio data
     1056                         * than we need for the pre-beacon to complete. In other words, that "more data"
     1057                         * needs to be counted to the actual recorded test tone data then.
     1058                         */
     1059                        if (pTst->enmState == AUDIOTESTSTATE_PRE)
     1060                            pTst->t.TestTone.u.Play.cbRead += cbBuf - (uint32_t)uOff; /* Add data after pre-beacon */
     1061                    }
    10531062
    10541063                    if (fStarted)
     
    10771086                 * Currently we don't, as otherwise consequtively played tones will be cut off in the end. */
    10781087                if (!fIsAllSilence)
     1088                {
     1089                    uint32_t const cbToAddMax = pTst->t.TestTone.u.Play.cbToRead - pTst->t.TestTone.u.Play.cbRead;
     1090
     1091                    /* Don't read more than we're told to.
     1092                     * After the actual test tone data there might come a post beacon which also
     1093                     * needs to be handled in the AUDIOTESTSTATE_POST state then. */
     1094                    if (cbBuf > cbToAddMax)
     1095                        cbBuf = cbToAddMax;
     1096
    10791097                    pTst->t.TestTone.u.Play.cbRead += cbBuf;
     1098                }
    10801099
    10811100                const bool fComplete = pTst->t.TestTone.u.Play.cbRead >= pTst->t.TestTone.u.Play.cbToRead;
     
    11061125                break;
    11071126        }
     1127
     1128        /* Always write (record) everything, no matter if the current audio contains complete silence or not.
     1129         * Might be also become handy later if we want to have a look at start/stop timings and so on. */
     1130        rc = AudioTestObjWrite(pTst->Obj, pvBuf, cbBuf);
     1131        AssertRC(rc);
    11081132
    11091133        /* Always report everything as being played. */
  • TabularUnified trunk/src/VBox/ValidationKit/utils/audio/vkatCommon.cpp

    r92211 r92234  
    803803                    cbRecTotal += cbRecorded; /* Do a bit of accounting. */
    804804
    805                     /* Always write (record) everything, no matter if the current audio contains complete silence or not.
    806                      * Might be also become handy later if we want to have a look at start/stop timings and so on. */
    807                     rc = AudioTestObjWrite(Obj, abSamples, cbRecorded);
    808                     AssertRCBreak(rc);
    809 
    810805                    switch (enmState)
    811806                    {
     
    819814                                bool const fStarted = AudioTestBeaconGetRemaining(&Beacon) == AudioTestBeaconGetSize(&Beacon);
    820815
    821                                 /* Limit adding data to the beacon size. */
    822                                 uint32_t const cbToAddMax = RT_MIN(cbRecorded, AudioTestBeaconGetRemaining(&Beacon));
    823 
    824                                 AudioTestBeaconAddConsecutive(&Beacon, abSamples, cbToAddMax);
    825                                 /** @todo Take left-over data into account (and stash them away for the test tone)? */
     816                                size_t uOff;
     817                                rc = AudioTestBeaconAddConsecutive(&Beacon, abSamples, cbRecorded, &uOff);
     818                                if (RT_SUCCESS(rc))
     819                                {
     820                                    /*
     821                                     * When being in the AUDIOTESTSTATE_PRE state, we might get more audio data
     822                                     * than we need for the pre-beacon to complete. In other words, that "more data"
     823                                     * needs to be counted to the actual recorded test tone data then.
     824                                     */
     825                                    if (enmState == AUDIOTESTSTATE_PRE)
     826                                        cbTestRec += cbRecorded - (uint32_t)uOff;
     827                                }
    826828
    827829                                if (   fStarted
     
    852854                             * Currently we don't, as otherwise consequtively played tones will be cut off in the end. */
    853855                            if (!fIsAllSilence)
     856                            {
     857                                uint32_t const cbToAddMax = cbTestToRec - cbTestRec;
     858
     859                                /* Don't read more than we're told to.
     860                                 * After the actual test tone data there might come a post beacon which also
     861                                 * needs to be handled in the AUDIOTESTSTATE_POST state then. */
     862                                if (cbRecorded > cbToAddMax)
     863                                    cbRecorded = cbToAddMax;
     864
    854865                                cbTestRec += cbRecorded;
     866                            }
    855867
    856868                            if (cbTestToRec - cbTestRec == 0) /* Done recording the test tone? */
     
    874886                }
    875887
    876                 if (enmState == AUDIOTESTSTATE_DONE)
     888                if (cbRecorded)
     889                {
     890                    /* Always write (record) everything, no matter if the current audio contains complete silence or not.
     891                     * Might be also become handy later if we want to have a look at start/stop timings and so on. */
     892                    rc = AudioTestObjWrite(Obj, abSamples, cbRecorded);
     893                    AssertRCBreak(rc);
     894                }
     895
     896                if (enmState == AUDIOTESTSTATE_DONE) /* Bail out when in state "done". */
    877897                    break;
    878898            }
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