- Timestamp:
- Nov 5, 2021 8:44:14 AM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 148068
- Location:
- trunk/src/VBox
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/VBox/Devices/Audio/AudioTest.cpp ¶
r92211 r92234 2458 2458 * Adds audio data to a given beacon. 2459 2459 * 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. 2461 2461 * @param pBeacon Beacon to add data for. 2462 2462 * @param pauBuf Buffer of audio data to add. 2463 2463 * @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. 2464 2466 * 2465 2467 * @note The audio data must be a) match the beacon type and b) consecutive, that is, without any gaps, 2466 2468 * to be added as valid to the beacon. 2467 2469 */ 2468 uint32_t AudioTestBeaconAddConsecutive(PAUDIOTESTTONEBEACON pBeacon, const uint8_t *pauBuf, size_t cbBuf) 2469 { 2470 int 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; 2470 2477 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);2477 2478 2478 2479 uint8_t const byBeacon = AudioTestBeaconByteFromType(pBeacon->enmType); 2479 2480 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); 2481 2484 2482 2485 for (size_t i = 0; i < cbBuf; i += cbStep) … … 2487 2490 && pauBuf[i + 3] == byBeacon) 2488 2491 { 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 } 2493 2499 } 2494 2500 else 2495 2501 { 2496 2502 /* 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)) 2498 2504 pBeacon->cbUsed = 0; 2499 2505 } 2500 2506 } 2501 2507 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; 2507 2515 } 2508 2516 … … 2531 2539 * @param pToneParms Tone parameters to use for verification. 2532 2540 * @param puOff Where to return the absolute file offset (in bytes) right after the found beacon on success. 2541 * Optional and can be NULL. 2533 2542 */ 2534 2543 static int audioTestToneVerifyBeacon(PAUDIOTESTVERIFYJOB pVerJob, … … 2545 2554 : (fPre ? AUDIOTESTTONEBEACONTYPE_REC_PRE : AUDIOTESTTONEBEACONTYPE_REC_POST), &pToneParms->Props); 2546 2555 2547 LogRel2(("Verifying %s beacon @ %RU64\n", AudioTestBeaconTypeGetName(Beacon.enmType), pCmp->offStart)); 2548 2549 uint8_t auBuf[64]; 2556 uint8_t auBuf[_64K]; 2550 2557 uint64_t cbToCompare = pCmp->cbSize; 2551 2558 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 2555 2563 while (cbToCompare) 2556 2564 { 2557 2565 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); 2559 2567 AssertRCBreak(rc); 2560 2568 … … 2562 2570 break; 2563 2571 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 } 2567 2579 2568 2580 Assert(cbToCompare >= cbRead); … … 2585 2597 { 2586 2598 AssertReturn(AudioTestBeaconGetRemaining(&Beacon) == 0, VERR_INTERNAL_ERROR); 2599 AssertReturn(offBeaconLast != UINT32_MAX, VERR_INTERNAL_ERROR); 2587 2600 AssertReturn(offBeaconLast >= AudioTestBeaconGetSize(&Beacon), VERR_INTERNAL_ERROR); 2588 2601 … … 2981 2994 pOpts->fNormalize = false; /* Skip normalization by default now, as we now use the OS' master volume to play/record tones. */ 2982 2995 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. */ 2988 2999 } 2989 3000 -
TabularUnified trunk/src/VBox/Devices/Audio/AudioTest.h ¶
r92211 r92234 378 378 379 379 void AudioTestBeaconInit(PAUDIOTESTTONEBEACON pBeacon, AUDIOTESTTONEBEACONTYPE enmType, PPDMAUDIOPCMPROPS pProps); 380 uint32_t AudioTestBeaconAddConsecutive(PAUDIOTESTTONEBEACON pBeacon, const uint8_t *auBuf, size_t cbBuf);380 int AudioTestBeaconAddConsecutive(PAUDIOTESTTONEBEACON pBeacon, const uint8_t *auBuf, size_t cbBuf, size_t *pOff); 381 381 int AudioTestBeaconWrite(PAUDIOTESTTONEBEACON pBeacon, void *pvBuf, uint32_t cbBuf); 382 382 uint32_t AudioTestBeaconGetSize(PCAUDIOTESTTONEBEACON pBeacon); -
TabularUnified trunk/src/VBox/Devices/Audio/DrvHostAudioValidationKit.cpp ¶
r92211 r92234 298 298 pTst->idxTest, AudioTestStateToStr(pTst->enmState))); 299 299 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 } 305 308 drvHostValKiUnregisterRecTest(pThis, pTst); 306 309 } … … 315 318 pTst->idxTest, AudioTestStateToStr(pTst->enmState))); 316 319 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 } 322 328 drvHostValKiUnregisterPlayTest(pThis, pTst); 323 329 } … … 1030 1036 if (RT_SUCCESS(rc)) 1031 1037 { 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 1036 1038 switch (pTst->enmState) 1037 1039 { … … 1046 1048 bool const fStarted = AudioTestBeaconGetRemaining(pBeacon) == AudioTestBeaconGetSize(pBeacon); 1047 1049 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 } 1053 1062 1054 1063 if (fStarted) … … 1077 1086 * Currently we don't, as otherwise consequtively played tones will be cut off in the end. */ 1078 1087 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 1079 1097 pTst->t.TestTone.u.Play.cbRead += cbBuf; 1098 } 1080 1099 1081 1100 const bool fComplete = pTst->t.TestTone.u.Play.cbRead >= pTst->t.TestTone.u.Play.cbToRead; … … 1106 1125 break; 1107 1126 } 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); 1108 1132 1109 1133 /* Always report everything as being played. */ -
TabularUnified trunk/src/VBox/ValidationKit/utils/audio/vkatCommon.cpp ¶
r92211 r92234 803 803 cbRecTotal += cbRecorded; /* Do a bit of accounting. */ 804 804 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 810 805 switch (enmState) 811 806 { … … 819 814 bool const fStarted = AudioTestBeaconGetRemaining(&Beacon) == AudioTestBeaconGetSize(&Beacon); 820 815 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 } 826 828 827 829 if ( fStarted … … 852 854 * Currently we don't, as otherwise consequtively played tones will be cut off in the end. */ 853 855 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 854 865 cbTestRec += cbRecorded; 866 } 855 867 856 868 if (cbTestToRec - cbTestRec == 0) /* Done recording the test tone? */ … … 874 886 } 875 887 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". */ 877 897 break; 878 898 }
Note:
See TracChangeset
for help on using the changeset viewer.