Changeset 89890 in vbox
- Timestamp:
- Jun 24, 2021 3:56:05 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145348
- Location:
- trunk/src/VBox
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioTest.cpp
r89889 r89890 128 128 129 129 /** 130 * Returns a random test tone frequency.131 */132 DECLINLINE(double) audioTestToneGetRandomFreq(void)133 {134 return s_aAudioTestToneFreqsHz[RTRandU32Ex(0, RT_ELEMENTS(s_aAudioTestToneFreqsHz) - 1)];135 }136 137 /**138 130 * Initializes a test tone with a specific frequency (in Hz). 139 131 * … … 147 139 { 148 140 if (dbFreq == 0.0) 149 dbFreq = audioTestToneGetRandomFreq();141 dbFreq = AudioTestToneGetRandomFreq(); 150 142 151 143 pTone->rdFreqHz = dbFreq; … … 290 282 291 283 /** 292 * Initializes an audio test tone parameters struct with random values. 293 * @param pToneParams Test tone parameters to initialize. 294 * @param pProps PCM properties to use for the test tone. 295 */ 296 int AudioTestToneParamsInitRandom(PAUDIOTESTTONEPARMS pToneParams, PPDMAUDIOPCMPROPS pProps) 297 { 298 AssertReturn(PDMAudioPropsAreValid(pProps), VERR_INVALID_PARAMETER); 299 300 memcpy(&pToneParams->Props, pProps, sizeof(PDMAUDIOPCMPROPS)); 301 302 /** @todo Make this a bit more sophisticated later, e.g. muting and prequel/sequel are not very balanced. */ 303 304 pToneParams->dbFreqHz = audioTestToneGetRandomFreq(); 305 pToneParams->msPrequel = RTRandU32Ex(0, RT_MS_5SEC); 306 #ifdef DEBUG_andy 307 pToneParams->msDuration = RTRandU32Ex(0, RT_MS_1SEC); 308 #else 309 pToneParams->msDuration = RTRandU32Ex(0, RT_MS_10SEC); /** @todo Probably a bit too long, but let's see. */ 310 #endif 311 pToneParams->msSequel = RTRandU32Ex(0, RT_MS_5SEC); 312 pToneParams->uVolumePercent = RTRandU32Ex(0, 100); 313 314 return VINF_SUCCESS; 284 * Returns a random test tone frequency. 285 */ 286 double AudioTestToneGetRandomFreq(void) 287 { 288 return s_aAudioTestToneFreqsHz[RTRandU32Ex(0, RT_ELEMENTS(s_aAudioTestToneFreqsHz) - 1)]; 315 289 } 316 290 … … 1411 1385 1412 1386 /** 1387 * Returns whether a test set has running (active) tests or not. 1388 * 1389 * @returns \c true if it has running tests, or \c false if not. 1390 * @param pSet Test set to return status for. 1391 */ 1392 bool AudioTestSetIsRunning(PAUDIOTESTSET pSet) 1393 { 1394 return (pSet->cTestsRunning > 0); 1395 } 1396 1397 /** 1413 1398 * Unpacks a formerly packed audio test set. 1414 1399 * … … 1713 1698 rc = RTFileQuerySize(pObjB->File.hFile, &cbSizeB); 1714 1699 AssertRCReturn(rc, rc); 1715 if ( cbSizeA != cbSizeB 1716 || !audioTestFilesCompareBinary(pObjA->File.hFile, pObjB->File.hFile, cbSizeA)) 1700 1701 if (!cbSizeA) 1702 { 1703 int rc2 = audioTestErrorDescAdd(pVerJob->pErr, pVerJob->idxTest, "File '%s' is empty\n", pObjA->szName); 1704 AssertRC(rc2); 1705 } 1706 1707 if (!cbSizeB) 1708 { 1709 int rc2 = audioTestErrorDescAdd(pVerJob->pErr, pVerJob->idxTest, "File '%s' is empty\n", pObjB->szName); 1710 AssertRC(rc2); 1711 } 1712 1713 if (cbSizeA != cbSizeB) 1714 { 1715 int rc2 = audioTestErrorDescAdd(pVerJob->pErr, pVerJob->idxTest, "File '%s' is %zu bytes %s than '%s'\n", 1716 pObjA->szName, 1717 cbSizeA > cbSizeB ? cbSizeA - cbSizeB : cbSizeB - cbSizeA, 1718 cbSizeA > cbSizeB ? "bigger" : "smaller", 1719 pObjB->szName); 1720 AssertRC(rc2); 1721 } 1722 else if (audioTestFilesCompareBinary(pObjA->File.hFile, pObjB->File.hFile, cbSizeA)) 1717 1723 { 1718 1724 /** @todo Add more sophisticated stuff here. */ 1719 1725 1720 int rc2 = audioTestErrorDescAdd(pVerJob->pErr, pVerJob->idxTest, "Files '%s' and '%s' don't match\n", szObjA, szObjB); 1726 int rc2 = audioTestErrorDescAdd(pVerJob->pErr, pVerJob->idxTest, "Files '%s' and '%s' have different content\n", 1727 pObjA->szName, pObjB->szName); 1721 1728 AssertRC(rc2); 1722 1729 } -
trunk/src/VBox/Devices/Audio/AudioTest.h
r89889 r89890 340 340 double AudioTestToneInit(PAUDIOTESTTONE pTone, PPDMAUDIOPCMPROPS pProps, double dbFreq); 341 341 double AudioTestToneInitRandom(PAUDIOTESTTONE pTone, PPDMAUDIOPCMPROPS pProps); 342 double AudioTestToneGetRandomFreq(void); 342 343 int AudioTestToneGenerate(PAUDIOTESTTONE pTone, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten); 343 344 int AudioTestToneParamsInitRandom(PAUDIOTESTTONEPARMS pToneParams, PPDMAUDIOPCMPROPS pProps);345 344 346 345 int AudioTestGenTag(char *pszTag, size_t cbTag); … … 367 366 const char *AudioTestSetGetTag(PAUDIOTESTSET pSet); 368 367 bool AudioTestSetIsPacked(const char *pszPath); 368 bool AudioTestSetIsRunning(PAUDIOTESTSET pSet); 369 369 int AudioTestSetPack(PAUDIOTESTSET pSet, const char *pszOutDir, char *pszFileName, size_t cbFileName); 370 370 int AudioTestSetUnpack(const char *pszFile, const char *pszOutDir); -
trunk/src/VBox/Devices/Audio/DrvHostAudioValidationKit.cpp
r89838 r89890 25 25 #include <iprt/mem.h> 26 26 #include <iprt/path.h> 27 #include <iprt/semaphore.h> 27 28 #include <iprt/stream.h> 28 29 #include <iprt/uuid.h> /* For PDMIBASE_2_PDMDRV. */ … … 138 139 /** Critical section for serializing access across threads. */ 139 140 RTCRITSECT CritSect; 141 bool fTestSetEnded; 142 RTSEMEVENT EventSemEnded; 140 143 /** The Audio Test Service (ATS) instance. */ 141 144 ATSSERVER Srv; … … 173 176 { 174 177 AssertPtrReturnVoid(pTst->pEntry); 175 AudioTestSetTestDone(pTst->pEntry);176 178 pTst->pEntry = NULL; 177 179 } … … 218 220 static void drvHostValKitCleanup(PDRVHOSTVALKITAUDIO pThis) 219 221 { 220 LogRel((" Audio: ValidationKit: Cleaning up ...\n"));222 LogRel(("ValKit: Cleaning up ...\n")); 221 223 222 224 if (pThis->cTestsRec) 223 LogRel((" Audio: ValidationKit: Warning: %RU32 guest recording tests still outstanding:\n", pThis->cTestsRec));225 LogRel(("ValKit: Warning: %RU32 guest recording tests still outstanding:\n", pThis->cTestsRec)); 224 226 225 227 PVALKITTESTDATA pTst, pTstNext; … … 228 230 size_t const cbOutstanding = pTst->t.TestTone.u.Rec.cbToWrite - pTst->t.TestTone.u.Rec.cbWritten; 229 231 if (cbOutstanding) 230 LogRel((" Audio: ValidationKit: \tRecording test #%RU32 has %RU64 bytes (%RU32ms) outstanding\n",232 LogRel(("ValKit: \tRecording test #%RU32 has %RU64 bytes (%RU32ms) outstanding\n", 231 233 pTst->idxTest, cbOutstanding, PDMAudioPropsBytesToMilli(&pTst->t.TestTone.Parms.Props, (uint32_t)cbOutstanding))); 232 234 drvHostValKiUnregisterRecTest(pThis, pTst); … … 234 236 235 237 if (pThis->cTestsPlay) 236 LogRel((" Audio: ValidationKit: Warning: %RU32 guest playback tests still outstanding:\n", pThis->cTestsPlay));238 LogRel(("ValKit: Warning: %RU32 guest playback tests still outstanding:\n", pThis->cTestsPlay)); 237 239 238 240 RTListForEachSafe(&pThis->lstTestsPlay, pTst, pTstNext, VALKITTESTDATA, Node) … … 240 242 size_t const cbOutstanding = pTst->t.TestTone.u.Play.cbToRead - pTst->t.TestTone.u.Play.cbRead; 241 243 if (cbOutstanding) 242 LogRel((" Audio: ValidationKit: \tPlayback test #%RU32 has %RU64 bytes (%RU32ms) outstanding\n",244 LogRel(("ValKit: \tPlayback test #%RU32 has %RU64 bytes (%RU32ms) outstanding\n", 243 245 pTst->idxTest, cbOutstanding, PDMAudioPropsBytesToMilli(&pTst->t.TestTone.Parms.Props, (uint32_t)cbOutstanding))); 244 246 drvHostValKiUnregisterPlayTest(pThis, pTst); … … 259 261 PDRVHOSTVALKITAUDIO pThis = (PDRVHOSTVALKITAUDIO)pvUser; 260 262 261 LogRel(("Audio: Validation Kit: Beginning test set '%s'\n", pszTag)); 262 return AudioTestSetCreate(&pThis->Set, pThis->szPathTemp, pszTag); 263 int rc = RTCritSectEnter(&pThis->CritSect); 264 if (RT_SUCCESS(rc)) 265 { 266 267 LogRel(("ValKit: Beginning test set '%s'\n", pszTag)); 268 rc = AudioTestSetCreate(&pThis->Set, pThis->szPathTemp, pszTag); 269 270 int rc2 = RTCritSectLeave(&pThis->CritSect); 271 if (RT_SUCCESS(rc)) 272 rc = rc2; 273 } 274 275 if (RT_FAILURE(rc)) 276 LogRel(("ValKit: Beginning test set failed with %Rrc\n", rc)); 277 278 return rc; 263 279 } 264 280 … … 268 284 PDRVHOSTVALKITAUDIO pThis = (PDRVHOSTVALKITAUDIO)pvUser; 269 285 270 const PAUDIOTESTSET pSet = &pThis->Set; 271 272 LogRel(("Audio: Validation Kit: Ending test set '%s'\n", pszTag)); 273 274 /* Close the test set first. */ 275 AudioTestSetClose(pSet); 276 277 /* Before destroying the test environment, pack up the test set so 278 * that it's ready for transmission. */ 279 int rc = AudioTestSetPack(pSet, pThis->szPathOut, pThis->szTestSetArchive, sizeof(pThis->szTestSetArchive)); 280 if (RT_SUCCESS(rc)) 281 LogRel(("Audio: Validation Kit: Packed up to '%s'\n", pThis->szTestSetArchive)); 282 283 /* Do some internal housekeeping. */ 284 drvHostValKitCleanup(pThis); 285 286 int rc2 = AudioTestSetWipe(pSet); 287 if (RT_SUCCESS(rc)) 288 rc = rc2; 289 290 AudioTestSetDestroy(pSet); 286 int rc = RTCritSectEnter(&pThis->CritSect); 287 if (RT_SUCCESS(rc)) 288 { 289 const PAUDIOTESTSET pSet = &pThis->Set; 290 291 if (AudioTestSetIsRunning(pSet)) 292 { 293 pThis->fTestSetEnded = true; 294 295 rc = RTCritSectLeave(&pThis->CritSect); 296 if (RT_SUCCESS(rc)) 297 { 298 LogRel(("ValKit: Waiting for runnig test set '%s' to end ...\n", pszTag)); 299 rc = RTSemEventWait(pThis->EventSemEnded, RT_MS_30SEC); 300 301 int rc2 = RTCritSectEnter(&pThis->CritSect); 302 if (RT_SUCCESS(rc)) 303 rc = rc2; 304 } 305 } 306 307 if (RT_SUCCESS(rc)) 308 { 309 LogRel(("ValKit: Ending test set '%s'\n", pszTag)); 310 311 /* Close the test set first. */ 312 rc = AudioTestSetClose(pSet); 313 if (RT_SUCCESS(rc)) 314 { 315 /* Before destroying the test environment, pack up the test set so 316 * that it's ready for transmission. */ 317 rc = AudioTestSetPack(pSet, pThis->szPathOut, pThis->szTestSetArchive, sizeof(pThis->szTestSetArchive)); 318 if (RT_SUCCESS(rc)) 319 LogRel(("ValKit: Packed up to '%s'\n", pThis->szTestSetArchive)); 320 321 /* Do some internal housekeeping. */ 322 drvHostValKitCleanup(pThis); 323 324 #ifndef DEBUG_andy 325 int rc2 = AudioTestSetWipe(pSet); 326 if (RT_SUCCESS(rc)) 327 rc = rc2; 328 #endif 329 } 330 331 AudioTestSetDestroy(pSet); 332 } 333 334 int rc2 = RTCritSectLeave(&pThis->CritSect); 335 if (RT_SUCCESS(rc)) 336 rc = rc2; 337 } 291 338 292 339 if (RT_FAILURE(rc)) 293 LogRel((" Audio: ValidationKit: Ending test set failed with %Rrc\n", rc));340 LogRel(("ValKit: Ending test set failed with %Rrc\n", rc)); 294 341 295 342 return rc; … … 310 357 memcpy(&pTestData->t.TestTone.Parms, pToneParms, sizeof(AUDIOTESTTONEPARMS)); 311 358 312 AudioTestToneInit(&pTestData->t.TestTone.Tone, &pToneParms->Props, pTestData->t.TestTone.Parms.dbFreqHz); 313 314 pTestData->t.TestTone.u.Rec.cbToWrite = PDMAudioPropsMilliToBytes(&pToneParms->Props, 359 AssertReturn(pTestData->t.TestTone.Parms.msDuration, VERR_INVALID_PARAMETER); 360 AssertReturn(PDMAudioPropsAreValid(&pTestData->t.TestTone.Parms.Props), VERR_INVALID_PARAMETER); 361 362 AudioTestToneInit(&pTestData->t.TestTone.Tone, &pTestData->t.TestTone.Parms.Props, pTestData->t.TestTone.Parms.dbFreqHz); 363 364 pTestData->t.TestTone.u.Rec.cbToWrite = PDMAudioPropsMilliToBytes(&pTestData->t.TestTone.Parms.Props, 315 365 pTestData->t.TestTone.Parms.msDuration); 316 366 int rc = RTCritSectEnter(&pThis->CritSect); 317 367 if (RT_SUCCESS(rc)) 318 368 { 319 LogRel((" Audio: ValidationKit: Registered guest recording test #%RU32 (%RU32ms, %RU64 bytes)\n",369 LogRel(("ValKit: Registered guest recording test #%RU32 (%RU32ms, %RU64 bytes)\n", 320 370 pThis->cTestsTotal, pTestData->t.TestTone.Parms.msDuration, pTestData->t.TestTone.u.Rec.cbToWrite)); 321 371 … … 347 397 memcpy(&pTestData->t.TestTone.Parms, pToneParms, sizeof(AUDIOTESTTONEPARMS)); 348 398 349 pTestData->t.TestTone.u.Play.cbToRead = PDMAudioPropsMilliToBytes(&pToneParms->Props, 399 AssertReturn(pTestData->t.TestTone.Parms.msDuration, VERR_INVALID_PARAMETER); 400 AssertReturn(PDMAudioPropsAreValid(&pTestData->t.TestTone.Parms.Props), VERR_INVALID_PARAMETER); 401 402 pTestData->t.TestTone.u.Play.cbToRead = PDMAudioPropsMilliToBytes(&pTestData->t.TestTone.Parms.Props, 350 403 pTestData->t.TestTone.Parms.msDuration); 351 404 int rc = RTCritSectEnter(&pThis->CritSect); 352 405 if (RT_SUCCESS(rc)) 353 406 { 354 LogRel((" Audio: ValidationKit: Registered guest playback test #%RU32 (%RU32ms, %RU64 bytes)\n",407 LogRel(("ValKit: Registered guest playback test #%RU32 (%RU32ms, %RU64 bytes)\n", 355 408 pThis->cTestsTotal, pTestData->t.TestTone.Parms.msDuration, pTestData->t.TestTone.u.Play.cbToRead)); 356 409 … … 375 428 PDRVHOSTVALKITAUDIO pThis = (PDRVHOSTVALKITAUDIO)pvUser; 376 429 377 if (!RTFileExists(pThis->szTestSetArchive)) /* Has the archive successfully been created yet? */ 378 return VERR_WRONG_ORDER; 379 380 int rc = RTFileOpen(&pThis->hTestSetArchive, pThis->szTestSetArchive, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 381 if (RT_SUCCESS(rc)) 382 { 383 uint64_t uSize; 384 rc = RTFileQuerySize(pThis->hTestSetArchive, &uSize); 385 if (RT_SUCCESS(rc)) 386 LogRel(("Audio: Validation Kit: Sending test set '%s' (%zu bytes)\n", pThis->szTestSetArchive, uSize)); 387 } 430 int rc = RTCritSectEnter(&pThis->CritSect); 431 if (RT_SUCCESS(rc)) 432 { 433 if (RTFileExists(pThis->szTestSetArchive)) /* Has the archive successfully been created yet? */ 434 { 435 rc = RTFileOpen(&pThis->hTestSetArchive, pThis->szTestSetArchive, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 436 if (RT_SUCCESS(rc)) 437 { 438 uint64_t uSize; 439 rc = RTFileQuerySize(pThis->hTestSetArchive, &uSize); 440 if (RT_SUCCESS(rc)) 441 LogRel(("ValKit: Sending test set '%s' (%zu bytes)\n", pThis->szTestSetArchive, uSize)); 442 } 443 } 444 else 445 rc = VERR_FILE_NOT_FOUND; 446 447 int rc2 = RTCritSectLeave(&pThis->CritSect); 448 if (RT_SUCCESS(rc)) 449 rc = rc2; 450 } 451 452 if (RT_FAILURE(rc)) 453 LogRel(("ValKit: Beginning to send test set failed with %Rrc\n", rc)); 388 454 389 455 return rc; … … 398 464 PDRVHOSTVALKITAUDIO pThis = (PDRVHOSTVALKITAUDIO)pvUser; 399 465 400 return RTFileRead(pThis->hTestSetArchive, pvBuf, cbBuf, pcbRead); 466 int rc = RTCritSectEnter(&pThis->CritSect); 467 if (RT_SUCCESS(rc)) 468 { 469 if (RTFileIsValid(pThis->hTestSetArchive)) 470 { 471 rc = RTFileRead(pThis->hTestSetArchive, pvBuf, cbBuf, pcbRead); 472 } 473 else 474 rc = VERR_WRONG_ORDER; 475 476 int rc2 = RTCritSectLeave(&pThis->CritSect); 477 if (RT_SUCCESS(rc)) 478 rc = rc2; 479 } 480 481 if (RT_FAILURE(rc)) 482 LogRel(("ValKit: Reading from test set failed with %Rrc\n", rc)); 483 484 return rc; 401 485 } 402 486 … … 408 492 PDRVHOSTVALKITAUDIO pThis = (PDRVHOSTVALKITAUDIO)pvUser; 409 493 410 int rc = RTFileClose(pThis->hTestSetArchive); 411 if (RT_SUCCESS(rc)) 412 { 413 pThis->hTestSetArchive = NIL_RTFILE; 414 } 494 int rc = RTCritSectEnter(&pThis->CritSect); 495 if (RT_SUCCESS(rc)) 496 { 497 if (RTFileIsValid(pThis->hTestSetArchive)) 498 { 499 rc = RTFileClose(pThis->hTestSetArchive); 500 if (RT_SUCCESS(rc)) 501 pThis->hTestSetArchive = NIL_RTFILE; 502 } 503 504 int rc2 = RTCritSectLeave(&pThis->CritSect); 505 if (RT_SUCCESS(rc)) 506 rc = rc2; 507 } 508 509 if (RT_FAILURE(rc)) 510 LogRel(("ValKit: Ending to send test set failed with %Rrc\n", rc)); 415 511 416 512 return rc; … … 532 628 static DECLCALLBACK(int) drvHostValKitAudioHA_StreamDrain(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 533 629 { 534 RT_NOREF(pInterface, pStream); 630 RT_NOREF(pStream); 631 632 PDRVHOSTVALKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio); 633 634 int rc = RTCritSectEnter(&pThis->CritSect); 635 if (RT_SUCCESS(rc)) 636 { 637 PVALKITTESTDATA pTst = pThis->pTestCur; 638 639 if (pTst) 640 { 641 LogRel(("ValKit: Test #%RU32: Recording audio data ended (took %RU32ms)\n", 642 pTst->idxTest, RTTimeMilliTS() - pTst->msStartedTS)); 643 644 if (pTst->t.TestTone.u.Play.cbRead > pTst->t.TestTone.u.Play.cbToRead) 645 LogRel(("ValKit: Warning: Test #%RU32 read %RU32 bytes more than announced\n", 646 pTst->idxTest, pTst->t.TestTone.u.Play.cbRead - pTst->t.TestTone.u.Play.cbToRead)); 647 648 AudioTestSetTestDone(pTst->pEntry); 649 650 pThis->pTestCur = NULL; 651 pTst = NULL; 652 653 if (pThis->fTestSetEnded) 654 rc = RTSemEventSignal(pThis->EventSemEnded); 655 } 656 657 int rc2 = RTCritSectLeave(&pThis->CritSect); 658 AssertRC(rc2); 659 } 660 535 661 return VINF_SUCCESS; 536 662 } … … 595 721 RT_NOREF(pStream); 596 722 723 if (cbBuf == 0) 724 { 725 /* Fend off draining calls. */ 726 *pcbWritten = 0; 727 return VINF_SUCCESS; 728 } 729 597 730 PDRVHOSTVALKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio); 598 731 732 PVALKITTESTDATA pTst = NULL; 733 599 734 int rc = RTCritSectEnter(&pThis->CritSect); 600 735 if (RT_SUCCESS(rc)) 601 736 { 602 pThis->pTestCur = RTListGetFirst(&pThis->lstTestsPlay, VALKITTESTDATA, Node); 737 if (pThis->pTestCur == NULL) 738 pThis->pTestCur = RTListGetFirst(&pThis->lstTestsPlay, VALKITTESTDATA, Node); 739 740 pTst = pThis->pTestCur; 603 741 604 742 int rc2 = RTCritSectLeave(&pThis->CritSect); … … 606 744 } 607 745 608 if (pT his->pTestCur== NULL) /* Empty list? */609 { 610 LogRel Max(64, ("Audio: ValidationKit: Warning: Guest is playing back data when no playback test is active\n"));746 if (pTst == NULL) /* Empty list? */ 747 { 748 LogRel(("ValKit: Warning: Guest is playing back data when no playback test is active\n")); 611 749 612 750 *pcbWritten = cbBuf; … … 614 752 } 615 753 616 PVALKITTESTDATA pTst = pThis->pTestCur; 754 #if 1 755 if (PDMAudioPropsIsBufferSilence(&pStream->pStream->Cfg.Props, pvBuf, cbBuf)) 756 { 757 LogRel(("ValKit: Skipping %RU32 bytes of silence\n", cbBuf)); 758 759 *pcbWritten = cbBuf; 760 return VINF_SUCCESS; 761 } 762 #endif 617 763 618 764 if (pTst->t.TestTone.u.Play.cbRead == 0) … … 633 779 { 634 780 pTst->msStartedTS = RTTimeMilliTS(); 635 LogRel((" Audio: Validation Kit: Recording audio data (%RU16Hz, %RU32ms) started\n",636 (uint16_t)Parms.TestTone.dbFreqHz, Parms.TestTone.msDuration));781 LogRel(("ValKit: Test #%RU32: Recording audio data (%RU16Hz, %RU32ms) started\n", 782 pTst->idxTest, (uint16_t)Parms.TestTone.dbFreqHz, Parms.TestTone.msDuration)); 637 783 } 638 784 } … … 642 788 if (RT_SUCCESS(rc)) 643 789 { 644 uint32_t cbToRead = RT_MIN(cbBuf, 645 pTst->t.TestTone.u.Play.cbToRead - pTst->t.TestTone.u.Play.cbRead); 646 647 rc = AudioTestSetObjWrite(pTst->pObj, pvBuf, cbToRead); 648 if (RT_SUCCESS(rc)) 649 { 650 pTst->t.TestTone.u.Play.cbRead += cbToRead; 651 Assert(pTst->t.TestTone.u.Play.cbRead <= pTst->t.TestTone.u.Play.cbToRead); 652 653 const bool fComplete = pTst->t.TestTone.u.Play.cbToRead == pTst->t.TestTone.u.Play.cbRead; 654 790 rc = AudioTestSetObjWrite(pTst->pObj, pvBuf, cbBuf); 791 if (RT_SUCCESS(rc)) 792 { 793 pTst->t.TestTone.u.Play.cbRead += cbBuf; 794 795 #if 0 796 const bool fComplete = pTst->t.TestTone.u.Play.cbRead >= pTst->t.TestTone.u.Play.cbToRead; 655 797 if (fComplete) 656 798 { 657 LogRel(("Audio: Validation Kit: Recording audio data done (took %RU32ms)\n", 658 RTTimeMilliTS() - pTst->msStartedTS)); 799 LogRel(("ValKit: Test #%RU32: Recording audio data ended (took %RU32ms)\n", 800 pTst->idxTest, RTTimeMilliTS() - pTst->msStartedTS)); 801 802 if (pTst->t.TestTone.u.Play.cbRead > pTst->t.TestTone.u.Play.cbToRead) 803 LogRel(("ValKit: Warning: Test #%RU32 read %RU32 bytes more than announced\n", 804 pTst->idxTest, pTst->t.TestTone.u.Play.cbRead - pTst->t.TestTone.u.Play.cbToRead)); 659 805 660 806 rc = RTCritSectEnter(&pThis->CritSect); 661 807 if (RT_SUCCESS(rc)) 662 808 { 663 drvHostValKiUnregisterPlayTest(pThis, pTst);809 AudioTestSetTestDone(pTst->pEntry); 664 810 665 811 pThis->pTestCur = NULL; 812 pTst = NULL; 813 814 if (pThis->fTestSetEnded) 815 rc = RTSemEventSignal(pThis->EventSemEnded); 666 816 667 817 int rc2 = RTCritSectLeave(&pThis->CritSect); 668 AssertRC(rc2); 818 if (RT_SUCCESS(rc)) 819 rc = rc2; 669 820 } 670 821 } 671 672 cbWritten = cbToRead; 822 #endif 823 824 cbWritten = cbBuf; 673 825 } 674 826 } … … 676 828 if (RT_FAILURE(rc)) 677 829 { 678 if (pTst->pEntry) 830 if ( pTst 831 && pTst->pEntry) 679 832 AudioTestSetTestFailed(pTst->pEntry, rc, "Recording audio data failed"); 680 LogRel((" Audio: ValidationKit: Recording audio data failed with %Rrc\n", rc));833 LogRel(("ValKit: Recording audio data failed with %Rrc\n", rc)); 681 834 } 682 835 … … 700 853 if (RT_SUCCESS(rc)) 701 854 { 702 pThis->pTestCur = RTListGetFirst(&pThis->lstTestsRec, VALKITTESTDATA, Node); 855 if (pThis->pTestCur == NULL) 856 pThis->pTestCur = RTListGetFirst(&pThis->lstTestsRec, VALKITTESTDATA, Node); 703 857 704 858 int rc2 = RTCritSectLeave(&pThis->CritSect); … … 708 862 if (pThis->pTestCur == NULL) /* Empty list? */ 709 863 { 710 LogRelMax(64, (" Audio: ValidationKit: Warning: Guest is recording audio data when no recording test is active\n"));864 LogRelMax(64, ("ValKit: Warning: Guest is recording audio data when no recording test is active\n")); 711 865 712 866 *pcbRead = 0; … … 733 887 { 734 888 pTst->msStartedTS = RTTimeMilliTS(); 735 LogRel((" Audio: ValidationKit: Injecting audio input data (%RU16Hz, %RU32ms) started\n",889 LogRel(("ValKit: Injecting audio input data (%RU16Hz, %RU32ms) started\n", 736 890 (uint16_t)pTst->t.TestTone.Tone.rdFreqHz, 737 891 pTst->t.TestTone.Parms.msDuration)); … … 759 913 if (fComplete) 760 914 { 761 LogRel((" Audio: ValidationKit: Injecting audio input data done (took %RU32ms)\n",915 LogRel(("ValKit: Injecting audio input data done (took %RU32ms)\n", 762 916 RTTimeMilliTS() - pTst->msStartedTS)); 763 917 … … 768 922 769 923 pThis->pTestCur = NULL; 924 pTst = NULL; 770 925 771 926 int rc2 = RTCritSectLeave(&pThis->CritSect); … … 779 934 if (RT_FAILURE(rc)) 780 935 { 781 if (pTst->pEntry) 936 if ( pTst 937 && pTst->pEntry) 782 938 AudioTestSetTestFailed(pTst->pEntry, rc, "Injecting audio input data failed"); 783 LogRel((" Audio: ValidationKit: Injecting audio input data failed with %Rrc\n", rc));939 LogRel(("ValKit: Injecting audio input data failed with %Rrc\n", rc)); 784 940 } 785 941 … … 844 1000 pThis->IHostAudio.pfnStreamCapture = drvHostValKitAudioHA_StreamCapture; 845 1001 1002 int rc = RTCritSectInit(&pThis->CritSect); 1003 AssertRCReturn(rc, rc); 1004 rc = RTSemEventCreate(&pThis->EventSemEnded); 1005 AssertRCReturn(rc, rc); 1006 1007 pThis->fTestSetEnded = false; 1008 846 1009 RTListInit(&pThis->lstTestsRec); 847 1010 pThis->cTestsRec = 0; … … 864 1027 uint32_t uTcpPort = ATS_TCP_HOST_DEFAULT_PORT; 865 1028 866 LogRel((" Audio: ValidationKit: Starting Audio Test Service (ATS) at %s:%RU32...\n",1029 LogRel(("ValKit: Starting Audio Test Service (ATS) at %s:%RU32...\n", 867 1030 pszTcpAddr, uTcpPort)); 868 1031 869 intrc = AudioTestSvcInit(&pThis->Srv,870 871 1032 rc = AudioTestSvcInit(&pThis->Srv, 1033 /* We only allow connections from localhost for now. */ 1034 pszTcpAddr, uTcpPort, &Callbacks); 872 1035 if (RT_SUCCESS(rc)) 873 1036 rc = AudioTestSvcStart(&pThis->Srv); … … 875 1038 if (RT_SUCCESS(rc)) 876 1039 { 877 LogRel((" Audio: ValidationKit: Audio Test Service (ATS) running\n"));1040 LogRel(("ValKit: Audio Test Service (ATS) running\n")); 878 1041 879 1042 /** @todo Let the following be customizable by CFGM later. */ … … 881 1044 if (RT_SUCCESS(rc)) 882 1045 { 883 LogRel((" Audio: ValidationKit: Using temp dir '%s'\n", pThis->szPathTemp));1046 LogRel(("ValKit: Using temp dir '%s'\n", pThis->szPathTemp)); 884 1047 rc = AudioTestPathGetTemp(pThis->szPathOut, sizeof(pThis->szPathOut)); 885 1048 if (RT_SUCCESS(rc)) 886 LogRel((" Audio: ValidationKit: Using output dir '%s'\n", pThis->szPathOut));1049 LogRel(("ValKit: Using output dir '%s'\n", pThis->szPathOut)); 887 1050 } 888 1051 } 889 1052 890 if (RT_SUCCESS(rc))891 rc = RTCritSectInit(&pThis->CritSect);892 893 1053 if (RT_FAILURE(rc)) 894 LogRel((" Audio: ValidationKit: Initialization failed, rc=%Rrc\n", rc));1054 LogRel(("ValKit: Initialization failed, rc=%Rrc\n", rc)); 895 1055 896 1056 return rc; … … 902 1062 PDRVHOSTVALKITAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTVALKITAUDIO); 903 1063 904 LogRel((" Audio: ValidationKit: Shutting down Audio Test Service (ATS) ...\n"));1064 LogRel(("ValKit: Shutting down Audio Test Service (ATS) ...\n")); 905 1065 906 1066 int rc = AudioTestSvcShutdown(&pThis->Srv); … … 910 1070 if (RT_SUCCESS(rc)) 911 1071 { 912 LogRel((" Audio: ValidationKit: Shutdown of Audio Test Service (ATS) complete\n"));1072 LogRel(("ValKit: Shutdown of Audio Test Service (ATS) complete\n")); 913 1073 drvHostValKitCleanup(pThis); 914 1074 } 915 1075 else 916 LogRel((" Audio: ValidationKit: Shutdown of Audio Test Service (ATS) failed, rc=%Rrc\n", rc));1076 LogRel(("ValKit: Shutdown of Audio Test Service (ATS) failed, rc=%Rrc\n", rc)); 917 1077 918 1078 /* Try cleaning up a bit. */ … … 920 1080 RTDirRemove(pThis->szPathOut); 921 1081 1082 RTSemEventDestroy(pThis->EventSemEnded); 1083 922 1084 if (RTCritSectIsInitialized(&pThis->CritSect)) 923 1085 { … … 928 1090 929 1091 if (RT_FAILURE(rc)) 930 LogRel((" Audio: ValidationKit: Destruction failed, rc=%Rrc\n", rc));1092 LogRel(("ValKit: Destruction failed, rc=%Rrc\n", rc)); 931 1093 } 932 1094 -
trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp
r89850 r89890 61 61 * Internal Functions * 62 62 *********************************************************************************************************************************/ 63 static int audioTestCombineParms(PAUDIOTESTPARMS pBaseParms, PAUDIOTESTPARMS pOverrideParms);64 63 static int audioVerifyOne(const char *pszPathSetA, const char *pszPathSetB); 65 64 … … 230 229 231 230 232 /**233 * Overrides audio test base parameters with another set.234 *235 * @returns VBox status code.236 * @param pBaseParms Base parameters to override.237 * @param pOverrideParms Override parameters to use for overriding the base parameters.238 *239 * @note Overriding a parameter depends on its type / default values.240 */241 static int audioTestCombineParms(PAUDIOTESTPARMS pBaseParms, PAUDIOTESTPARMS pOverrideParms)242 {243 RT_NOREF(pBaseParms, pOverrideParms);244 245 /** @todo Implement parameter overriding. */246 return VERR_NOT_IMPLEMENTED;247 }248 249 250 231 /********************************************************************************************************************************* 251 232 * Test callbacks * … … 257 238 static DECLCALLBACK(int) audioTestPlayToneSetup(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, PAUDIOTESTPARMS pTstParmsAcq, void **ppvCtx) 258 239 { 259 RT_NOREF(pTstEnv, pTstDesc, ppvCtx); 240 RT_NOREF(pTstDesc, ppvCtx); 241 242 int rc; 243 244 if (strlen(pTstEnv->szDev)) 245 { 246 rc = audioTestDriverStackSetDevice(&pTstEnv->DrvStack, PDMAUDIODIR_OUT, pTstEnv->szDev); 247 if (RT_FAILURE(rc)) 248 return rc; 249 } 260 250 261 251 pTstParmsAcq->enmType = AUDIOTESTTYPE_TESTTONE_PLAY; 262 263 PDMAudioPropsInit(&pTstParmsAcq->Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */); 264 252 pTstParmsAcq->Props = pTstEnv->Props; 265 253 pTstParmsAcq->enmDir = PDMAUDIODIR_OUT; 266 254 #ifdef DEBUG 267 pTstParmsAcq->cIterations = 2;255 pTstParmsAcq->cIterations = 1; 268 256 #else 269 257 pTstParmsAcq->cIterations = RTRandU32Ex(1, 10); … … 271 259 pTstParmsAcq->idxCurrent = 0; 272 260 273 return VINF_SUCCESS; 261 PAUDIOTESTTONEPARMS pToneParms = &pTstParmsAcq->TestTone; 262 263 pToneParms->Props = pTstParmsAcq->Props; 264 pToneParms->dbFreqHz = AudioTestToneGetRandomFreq(); 265 pToneParms->msPrequel = 0; /** @todo Implement analyzing this first! */ 266 #ifdef DEBUG_andy 267 pToneParms->msDuration = 2000; 268 #else 269 pToneParms->msDuration = RTRandU32Ex(0, RT_MS_10SEC); /** @todo Probably a bit too long, but let's see. */ 270 #endif 271 pToneParms->msSequel = 0; /** @todo Implement analyzing this first! */ 272 pToneParms->uVolumePercent = 100; /** @todo Implement analyzing this first! */ 273 274 return rc; 274 275 } 275 276 … … 285 286 for (uint32_t i = 0; i < pTstParms->cIterations; i++) 286 287 { 287 AudioTestToneParamsInitRandom(&pTstParms->TestTone, &pTstParms->Props); 288 288 /* 289 * 1. Arm the (host) ValKit ATS with the recording parameters. 290 */ 289 291 PAUDIOTESTTONEPARMS const pToneParms = &pTstParms->TestTone; 290 292 rc = AudioTestSvcClientToneRecord(&pTstEnv->u.Host.AtsClValKit, pToneParms); 291 293 if (RT_SUCCESS(rc)) 294 { 295 /* 296 * 2. Tell the guest ATS to start playback. 297 */ 292 298 rc = AudioTestSvcClientTonePlay(&pTstEnv->u.Host.AtsClGuest, pToneParms); 299 } 293 300 294 301 if (RT_FAILURE(rc)) … … 314 321 static DECLCALLBACK(int) audioTestRecordToneSetup(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, PAUDIOTESTPARMS pTstParmsAcq, void **ppvCtx) 315 322 { 316 RT_NOREF(pTstEnv, pTstDesc, ppvCtx); 323 RT_NOREF(pTstDesc, ppvCtx); 324 325 int rc; 326 327 if (strlen(pTstEnv->szDev)) 328 { 329 rc = audioTestDriverStackSetDevice(&pTstEnv->DrvStack, PDMAUDIODIR_IN, pTstEnv->szDev); 330 if (RT_FAILURE(rc)) 331 return rc; 332 } 317 333 318 334 pTstParmsAcq->enmType = AUDIOTESTTYPE_TESTTONE_RECORD; 319 320 PDMAudioPropsInit(&pTstParmsAcq->Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */); 321 335 pTstParmsAcq->Props = pTstEnv->Props; 322 336 pTstParmsAcq->enmDir = PDMAUDIODIR_IN; 323 337 #ifdef DEBUG 324 pTstParmsAcq->cIterations = 2;338 pTstParmsAcq->cIterations = 1; 325 339 #else 326 340 pTstParmsAcq->cIterations = RTRandU32Ex(1, 10); … … 328 342 pTstParmsAcq->idxCurrent = 0; 329 343 330 return VINF_SUCCESS;344 return rc; 331 345 } 332 346 … … 349 363 #endif 350 364 /* 351 * 1. Arm the ValKit ATS with the recordingparameters.365 * 1. Arm the (host) ValKit ATS with the playback parameters. 352 366 */ 353 367 rc = AudioTestSvcClientTonePlay(&pTstEnv->u.Host.AtsClValKit, &pTstParms->TestTone); … … 399 413 * @param pTstDesc Test to run. 400 414 * @param uSeq Test sequence # in case there are more tests. 401 * @param pOverrideParms Test parameters for overriding the actual test parameters. Optional. 402 */ 403 static int audioTestOne(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, 404 unsigned uSeq, PAUDIOTESTPARMS pOverrideParms) 415 */ 416 static int audioTestOne(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, unsigned uSeq) 405 417 { 406 418 RT_NOREF(uSeq); … … 431 443 } 432 444 433 audioTestCombineParms(&TstParms, pOverrideParms);434 435 445 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test #%u: %RU32 iterations\n", uSeq, TstParms.cIterations); 436 437 if (TstParms.Dev.pszName && strlen(TstParms.Dev.pszName)) /** @todo Refine this check. Use pszId for starters! */438 rc = audioTestDeviceOpen(&TstParms.Dev);439 446 440 447 AssertPtr(pTstDesc->pfnExec); … … 455 462 } 456 463 457 rc = audioTestDeviceClose(&TstParms.Dev);458 459 464 audioTestParmsDestroy(&TstParms); 460 465 … … 467 472 * @returns VBox status code. 468 473 * @param pTstEnv Test environment to use for running all tests. 469 * @param pOverrideParms Test parameters for (some / all) specific test parameters. Optional. 470 */ 471 int audioTestWorker(PAUDIOTESTENV pTstEnv, PAUDIOTESTPARMS pOverrideParms) 474 */ 475 int audioTestWorker(PAUDIOTESTENV pTstEnv) 472 476 { 473 477 int rc = VINF_SUCCESS; … … 501 505 for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++) 502 506 { 503 int rc2 = audioTestOne(pTstEnv, &g_aTests[i], uSeq , pOverrideParms);507 int rc2 = audioTestOne(pTstEnv, &g_aTests[i], uSeq); 504 508 if (RT_SUCCESS(rc)) 505 509 rc = rc2; … … 631 635 RT_ZERO(TstEnv); 632 636 633 AUDIOTESTPARMS TstCust;634 audioTestParmsInit(&TstCust);635 636 637 const char *pszDevice = NULL; /* Custom device to use. Can be NULL if not being used. */ 637 638 const char *pszTag = NULL; /* Custom tag to use. Can be NULL if not being used. */ … … 750 751 751 752 case VKAT_TEST_OPT_VOL: 752 Tst Cust.TestTone.uVolumePercent = ValueUnion.u8;753 TstEnv.uVolumePercent = ValueUnion.u8; 753 754 break; 754 755 … … 766 767 767 768 /* Initialize the custom test parameters with sensible defaults if nothing else is given. */ 768 PDMAudioPropsInit(&Tst Cust.TestTone.Props,769 PDMAudioPropsInit(&TstEnv.Props, 769 770 cPcmSampleBit ? cPcmSampleBit / 8 : 2 /* 16-bit */, fPcmSigned, cPcmChannels ? cPcmChannels : 2, 770 771 uPcmHz ? uPcmHz : 44100); … … 784 785 pszGuestTcpAddr, uGuestTcpPort); 785 786 if (RT_SUCCESS(rc)) 786 { 787 audioTestWorker(&TstEnv, &TstCust); 788 audioTestEnvDestroy(&TstEnv); 789 } 790 791 audioTestParmsDestroy(&TstCust); 787 rc = audioTestWorker(&TstEnv); 788 789 audioTestEnvDestroy(&TstEnv); 792 790 793 791 if (RT_FAILURE(rc)) /* Let us know that something went wrong in case we forgot to mention it. */ -
trunk/src/VBox/ValidationKit/utils/audio/vkatCmdSelfTest.cpp
r89834 r89890 56 56 PSELFTESTCTX pCtx = (PSELFTESTCTX)pvUser; 57 57 58 AUDIOTESTPARMS TstCust; 59 audioTestParmsInit(&TstCust); 60 61 PAUDIOTESTENV pTstEnv = &pCtx->Guest.TstEnv; 58 PAUDIOTESTENV pTstEnvGst = &pCtx->Guest.TstEnv; 62 59 63 60 /* Flag the environment for self test mode. */ 64 pTstEnv ->fSelftest = true;61 pTstEnvGst->fSelftest = true; 65 62 66 63 /* Generate tag for guest side. */ 67 int rc = RTStrCopy(pTstEnv ->szTag, sizeof(pTstEnv->szTag), pCtx->szTag);64 int rc = RTStrCopy(pTstEnvGst->szTag, sizeof(pTstEnvGst->szTag), pCtx->szTag); 68 65 AssertRCReturn(rc, rc); 69 66 70 rc = AudioTestPathCreateTemp(pTstEnv ->szPathTemp, sizeof(pTstEnv->szPathTemp), "selftest-guest");67 rc = AudioTestPathCreateTemp(pTstEnvGst->szPathTemp, sizeof(pTstEnvGst->szPathTemp), "selftest-guest"); 71 68 AssertRCReturn(rc, rc); 72 69 73 rc = AudioTestPathCreateTemp(pTstEnv ->szPathOut, sizeof(pTstEnv->szPathOut), "selftest-out");70 rc = AudioTestPathCreateTemp(pTstEnvGst->szPathOut, sizeof(pTstEnvGst->szPathOut), "selftest-out"); 74 71 AssertRCReturn(rc, rc); 75 72 76 pTstEnv ->enmMode = AUDIOTESTMODE_GUEST;73 pTstEnvGst->enmMode = AUDIOTESTMODE_GUEST; 77 74 78 75 /** @todo Make this customizable. */ 79 PDMAudioPropsInit(& TstCust.TestTone.Props,76 PDMAudioPropsInit(&pTstEnvGst->Props, 80 77 2 /* 16-bit */, true /* fSigned */, 2 /* cChannels */, 44100 /* uHz */); 81 78 82 rc = audioTestEnvInit(pTstEnv , pTstEnv->DrvStack.pDrvReg, pCtx->fWithDrvAudio,79 rc = audioTestEnvInit(pTstEnvGst, pTstEnvGst->DrvStack.pDrvReg, pCtx->fWithDrvAudio, 83 80 pCtx->Host.szValKitAtsAddr, pCtx->Host.uValKitAtsPort, 84 81 pCtx->Guest.szAtsAddr, pCtx->Guest.uAtsPort); … … 87 84 RTThreadUserSignal(hThread); 88 85 89 audioTestWorker(pTstEnv, &TstCust); 90 audioTestEnvDestroy(pTstEnv); 91 } 92 93 audioTestParmsDestroy(&TstCust); 86 audioTestWorker(pTstEnvGst); 87 audioTestEnvDestroy(pTstEnvGst); 88 } 94 89 95 90 return rc; … … 118 113 */ 119 114 120 AUDIOTESTPARMS TstCust;121 audioTestParmsInit(&TstCust);122 123 115 /* Generate a common tag for guest and host side. */ 124 116 int rc = AudioTestGenTag(pCtx->szTag, sizeof(pCtx->szTag)); 125 117 AssertRCReturn(rc, RTEXITCODE_FAILURE); 126 118 127 PAUDIOTESTENV pTstEnv = &pCtx->Host.TstEnv;119 PAUDIOTESTENV pTstEnvHst = &pCtx->Host.TstEnv; 128 120 129 121 /* Flag the environment for self test mode. */ 130 pTstEnv ->fSelftest = true;122 pTstEnvHst->fSelftest = true; 131 123 132 124 /* Generate tag for host side. */ 133 rc = RTStrCopy(pTstEnv ->szTag, sizeof(pTstEnv->szTag), pCtx->szTag);125 rc = RTStrCopy(pTstEnvHst->szTag, sizeof(pTstEnvHst->szTag), pCtx->szTag); 134 126 AssertRCReturn(rc, RTEXITCODE_FAILURE); 135 127 136 rc = AudioTestPathCreateTemp(pTstEnv ->szPathTemp, sizeof(pTstEnv->szPathTemp), "selftest-tmp");128 rc = AudioTestPathCreateTemp(pTstEnvHst->szPathTemp, sizeof(pTstEnvHst->szPathTemp), "selftest-tmp"); 137 129 AssertRCReturn(rc, RTEXITCODE_FAILURE); 138 130 139 rc = AudioTestPathCreateTemp(pTstEnv ->szPathOut, sizeof(pTstEnv->szPathOut), "selftest-out");131 rc = AudioTestPathCreateTemp(pTstEnvHst->szPathOut, sizeof(pTstEnvHst->szPathOut), "selftest-out"); 140 132 AssertRCReturn(rc, RTEXITCODE_FAILURE); 133 134 /* Initialize the PCM properties to some sane values. */ 135 PDMAudioPropsInit(&pTstEnvHst->Props, 136 2 /* 16-bit */, true /* fPcmSigned */, 2 /* cPcmChannels */, 44100 /* uPcmHz */); 141 137 142 138 /* … … 161 157 * Steps 2 + 3. 162 158 */ 163 pTstEnv ->enmMode = AUDIOTESTMODE_HOST;164 165 rc = audioTestEnvInit(pTstEnv , &g_DrvHostValidationKitAudio, true /* fWithDrvAudio */,159 pTstEnvHst->enmMode = AUDIOTESTMODE_HOST; 160 161 rc = audioTestEnvInit(pTstEnvHst, &g_DrvHostValidationKitAudio, true /* fWithDrvAudio */, 166 162 pCtx->Host.szValKitAtsAddr, pCtx->Host.uValKitAtsPort, 167 163 pCtx->Host.szGuestAtsAddr, pCtx->Host.uGuestAtsPort); 168 164 if (RT_SUCCESS(rc)) 169 165 { 170 rc = audioTestWorker(pTstEnv , &TstCust);166 rc = audioTestWorker(pTstEnvHst); 171 167 if (RT_SUCCESS(rc)) 172 168 { … … 174 170 } 175 171 176 audioTestEnvDestroy(pTstEnv );172 audioTestEnvDestroy(pTstEnvHst); 177 173 } 178 174 } 179 180 audioTestParmsDestroy(&TstCust);181 175 182 176 /* -
trunk/src/VBox/ValidationKit/utils/audio/vkatCommon.cpp
r89837 r89890 68 68 * Internal Functions * 69 69 *********************************************************************************************************************************/ 70 static int audioTestCreateStreamDefaultIn(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps); 71 static int audioTestCreateStreamDefaultOut(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps); 70 static int audioTestStreamInit(PAUDIOTESTDRVSTACK pDrvStack, PAUDIOTESTSTREAM pStream, PDMAUDIODIR enmDir, PCPDMAUDIOPCMPROPS pProps, bool fWithMixer, uint32_t cMsBufferSize, uint32_t cMsPreBuffer, uint32_t cMsSchedulingHint); 72 71 static int audioTestStreamDestroy(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream); 73 72 static int audioTestDevicesEnumerateAndCheck(PAUDIOTESTENV pTstEnv, const char *pszDev, PPDMAUDIOHOSTDEV *ppDev); … … 144 143 } 145 144 146 /** 147 * Opens an audio device. 148 * 149 * @returns VBox status code. 150 * @param pDev Audio device to open. 151 */ 152 int audioTestDeviceOpen(PPDMAUDIOHOSTDEV pDev) 153 { 154 int rc = VINF_SUCCESS; 155 156 RTTestSubF(g_hTest, "Opening audio device '%s' ...", pDev->pszName); 157 158 /** @todo Detect + open device here. */ 159 160 RTTestSubDone(g_hTest); 161 162 return rc; 163 } 164 165 /** 166 * Closes an audio device. 167 * 168 * @returns VBox status code. 169 * @param pDev Audio device to close. 170 */ 171 int audioTestDeviceClose(PPDMAUDIOHOSTDEV pDev) 172 { 173 int rc = VINF_SUCCESS; 174 175 RTTestSubF(g_hTest, "Closing audio device '%s' ...", pDev->pszName); 176 177 /** @todo Close device here. */ 178 179 RTTestSubDone(g_hTest); 145 static int audioTestStreamInit(PAUDIOTESTDRVSTACK pDrvStack, PAUDIOTESTSTREAM pStream, 146 PDMAUDIODIR enmDir, PCPDMAUDIOPCMPROPS pProps, bool fWithMixer, 147 uint32_t cMsBufferSize, uint32_t cMsPreBuffer, uint32_t cMsSchedulingHint) 148 { 149 int rc; 150 151 if (enmDir == PDMAUDIODIR_IN) 152 rc = audioTestDriverStackStreamCreateInput(pDrvStack, pProps, cMsBufferSize, 153 cMsPreBuffer, cMsSchedulingHint, &pStream->pStream, &pStream->Cfg); 154 else if (enmDir == PDMAUDIODIR_OUT) 155 rc = audioTestDriverStackStreamCreateOutput(pDrvStack, pProps, cMsBufferSize, 156 cMsPreBuffer, cMsSchedulingHint, &pStream->pStream, &pStream->Cfg); 157 else 158 rc = VERR_NOT_SUPPORTED; 159 160 if (RT_SUCCESS(rc)) 161 { 162 if (!pDrvStack->pIAudioConnector) 163 { 164 pStream->pBackend = &((PAUDIOTESTDRVSTACKSTREAM)pStream->pStream)->Backend; 165 } 166 else 167 pStream->pBackend = NULL; 168 169 /* 170 * Automatically enable the mixer if the PCM properties don't match. 171 */ 172 if ( !fWithMixer 173 && !PDMAudioPropsAreEqual(pProps, &pStream->Cfg.Props)) 174 { 175 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Enabling stream mixer\n"); 176 fWithMixer = true; 177 } 178 179 rc = AudioTestMixStreamInit(&pStream->Mix, pDrvStack, pStream->pStream, 180 fWithMixer ? pProps : NULL, 100 /* ms */); /** @todo Configure mixer buffer? */ 181 } 182 183 if (RT_FAILURE(rc)) 184 RTTestFailed(g_hTest, "Initializing %s stream failed with %Rrc", enmDir == PDMAUDIODIR_IN ? "input" : "output", rc); 180 185 181 186 return rc; … … 201 206 } 202 207 203 return rc; 204 } 205 206 /** 207 * Creates an audio default input (recording) test stream. 208 * Convenience function. 209 * 210 * @returns VBox status code. 211 * @param pTstEnv Test environment to use for creating the stream. 212 * @param pStream Audio stream to create. 213 * @param pProps PCM properties to use for creation. 214 */ 215 static int audioTestCreateStreamDefaultIn(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps) 216 { 217 pStream->pBackend = NULL; 218 int rc = audioTestDriverStackStreamCreateInput(&pTstEnv->DrvStack, pProps, pTstEnv->cMsBufferSize, pTstEnv->cMsPreBuffer, 219 pTstEnv->cMsSchedulingHint, &pStream->pStream, &pStream->Cfg); 220 if (RT_SUCCESS(rc) && !pTstEnv->DrvStack.pIAudioConnector) 221 pStream->pBackend = &((PAUDIOTESTDRVSTACKSTREAM)pStream->pStream)->Backend; 222 return rc; 223 } 224 225 /** 226 * Creates an audio default output (playback) test stream. 227 * Convenience function. 228 * 229 * @returns VBox status code. 230 * @param pTstEnv Test environment to use for creating the stream. 231 * @param pStream Audio stream to create. 232 * @param pProps PCM properties to use for creation. 233 */ 234 static int audioTestCreateStreamDefaultOut(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps) 235 { 236 pStream->pBackend = NULL; 237 int rc = audioTestDriverStackStreamCreateOutput(&pTstEnv->DrvStack, pProps, pTstEnv->cMsBufferSize, pTstEnv->cMsPreBuffer, 238 pTstEnv->cMsSchedulingHint, &pStream->pStream, &pStream->Cfg); 239 if (RT_SUCCESS(rc) && !pTstEnv->DrvStack.pIAudioConnector) 240 pStream->pBackend = &((PAUDIOTESTDRVSTACKSTREAM)pStream->pStream)->Backend; 208 AudioTestMixStreamTerm(&pStream->Mix); 209 241 210 return rc; 242 211 } … … 246 215 * Test Primitives * 247 216 *********************************************************************************************************************************/ 217 218 /** 219 * Returns a random scheduling hint (in ms). 220 */ 221 DECLINLINE(uint32_t) audioTestEnvGetRandomSchedulingHint(void) 222 { 223 static const unsigned s_aSchedulingHintsMs[] = 224 { 225 10, 226 25, 227 50, 228 100, 229 200, 230 250 231 }; 232 233 return s_aSchedulingHintsMs[RTRandU32Ex(0, RT_ELEMENTS(s_aSchedulingHintsMs) - 1)]; 234 } 248 235 249 236 /** … … 260 247 { 261 248 AUDIOTESTTONE TstTone; 262 AudioTestToneInit(&TstTone, &p Parms->Props, pParms->dbFreqHz);249 AudioTestToneInit(&TstTone, &pStream->Cfg.Props, pParms->dbFreqHz); 263 250 264 251 const char *pcszPathOut = pTstEnv->Set.szPathAbs; 265 252 266 253 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Playing test tone (tone frequency is %RU16Hz, %RU32ms)\n", (uint16_t)pParms->dbFreqHz, pParms->msDuration); 267 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Writing to '%s'\n", pcszPathOut); 254 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Using %RU32ms stream scheduling hint\n", pStream->Cfg.Device.cMsSchedulingHint); 255 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Writing to '%s'\n", pcszPathOut); 268 256 269 257 /** @todo Use .WAV here? */ … … 272 260 AssertRCReturn(rc, rc); 273 261 262 rc = AudioTestMixStreamEnable(&pStream->Mix); 263 if ( RT_SUCCESS(rc) 264 && AudioTestMixStreamIsOkay(&pStream->Mix)) 265 { 266 uint8_t abBuf[_4K]; 267 268 uint32_t cbToPlayTotal = PDMAudioPropsMilliToBytes(&pStream->Cfg.Props, pParms->msDuration); 269 AssertStmt(cbToPlayTotal, rc = VERR_INVALID_PARAMETER); 270 271 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Playing %RU32 bytes total\n", cbToPlayTotal); 272 273 AudioTestSetObjAddMetadataStr(pObj, "stream_to_play_bytes=%RU32\n", cbToPlayTotal); 274 AudioTestSetObjAddMetadataStr(pObj, "stream_period_size_frames=%RU32\n", pStream->Cfg.Backend.cFramesPeriod); 275 AudioTestSetObjAddMetadataStr(pObj, "stream_buffer_size_frames=%RU32\n", pStream->Cfg.Backend.cFramesBufferSize); 276 AudioTestSetObjAddMetadataStr(pObj, "stream_prebuf_size_frames=%RU32\n", pStream->Cfg.Backend.cFramesPreBuffering); 277 /* Note: This mostly is provided by backend (e.g. PulseAudio / ALSA / ++) and 278 * has nothing to do with the device emulation scheduling hint. */ 279 AudioTestSetObjAddMetadataStr(pObj, "device_scheduling_hint_ms=%RU32\n", pStream->Cfg.Device.cMsSchedulingHint); 280 281 while (cbToPlayTotal) 282 { 283 uint32_t cbPlayed = 0; 284 uint32_t const cbCanWrite = AudioTestMixStreamGetWritable(&pStream->Mix); 285 if (cbCanWrite) 286 { 287 uint32_t const cbToGenerate = RT_MIN(RT_MIN(cbToPlayTotal, sizeof(abBuf)), cbCanWrite); 288 uint32_t cbToPlay; 289 rc = AudioTestToneGenerate(&TstTone, abBuf, cbToGenerate, &cbToPlay); 290 if (RT_SUCCESS(rc)) 291 { 292 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Playing %RU32 bytes ...\n", cbToPlay); 293 294 /* Write stuff to disk before trying to play it. Help analysis later. */ 295 rc = AudioTestSetObjWrite(pObj, abBuf, cbToPlay); 296 if (RT_SUCCESS(rc)) 297 rc = AudioTestMixStreamPlay(&pStream->Mix, abBuf, cbToPlay, &cbPlayed); 298 } 299 300 if (RT_FAILURE(rc)) 301 break; 302 } 303 else if (AudioTestMixStreamIsOkay(&pStream->Mix)) 304 RTThreadSleep(RT_MIN(RT_MAX(1, pStream->Cfg.Device.cMsSchedulingHint), 256)); 305 else 306 AssertFailedBreakStmt(rc = VERR_AUDIO_STREAM_NOT_READY); 307 308 Assert(cbToPlayTotal >= cbPlayed); 309 cbToPlayTotal -= cbPlayed; 310 } 311 312 if (cbToPlayTotal != 0) 313 RTTestFailed(g_hTest, "Playback ended unexpectedly (%RU32 bytes left)\n", cbToPlayTotal); 314 } 315 else 316 rc = VERR_AUDIO_STREAM_NOT_READY; 317 318 int rc2 = AudioTestSetObjClose(pObj); 319 if (RT_SUCCESS(rc)) 320 rc = rc2; 321 322 if (RT_FAILURE(rc)) 323 RTTestFailed(g_hTest, "Playing tone failed with %Rrc\n", rc); 324 325 return rc; 326 } 327 328 /** 329 * Records a test tone from a specific audio test stream. 330 * 331 * @returns VBox status code. 332 * @param pTstEnv Test environment to use for running the test. 333 * @param pStream Stream to use for recording the tone. 334 * @param pParms Tone parameters to use. 335 * 336 * @note Blocking function. 337 */ 338 static int audioTestRecordTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms) 339 { 340 const char *pcszPathOut = pTstEnv->Set.szPathAbs; 341 342 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Recording test tone (for %RU32ms)\n", pParms->msDuration); 343 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Writing to '%s'\n", pcszPathOut); 344 345 /** @todo Use .WAV here? */ 346 PAUDIOTESTOBJ pObj; 347 int rc = AudioTestSetObjCreateAndRegister(&pTstEnv->Set, "guest-tone-rec.pcm", &pObj); 348 AssertRCReturn(rc, rc); 349 274 350 if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream)) 275 351 { 276 uint32_t cbBuf;277 uint8_t abBuf[_4K];278 279 352 const uint32_t cbPerSched = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint); 280 353 AssertStmt(cbPerSched, rc = VERR_INVALID_PARAMETER); 281 uint32_t cbTo Write= PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration);282 AssertStmt(cbTo Write,rc = VERR_INVALID_PARAMETER);354 uint32_t cbToRead = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration); 355 AssertStmt(cbToRead, rc = VERR_INVALID_PARAMETER); 283 356 284 357 if (RT_SUCCESS(rc)) … … 288 361 AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint); 289 362 290 while (cbToWrite)291 {292 uint32_t cbWritten = 0;293 uint32_t cbToGenerate = RT_MIN(cbToWrite, RT_MIN(cbPerSched, sizeof(abBuf)));294 Assert(cbToGenerate);295 296 rc = AudioTestToneGenerate(&TstTone, abBuf, cbToGenerate, &cbBuf);297 if (RT_SUCCESS(rc))298 {299 /* Write stuff to disk before trying to play it. Help analysis later. */300 rc = AudioTestSetObjWrite(pObj, abBuf, cbBuf);301 if (RT_SUCCESS(rc))302 rc = audioTestDriverStackStreamPlay(&pTstEnv->DrvStack, pStream->pStream,303 abBuf, cbBuf, &cbWritten);304 }305 306 if (RT_FAILURE(rc))307 break;308 309 RTThreadSleep(pTstEnv->cMsSchedulingHint);310 311 Assert(cbToWrite >= cbWritten);312 cbToWrite -= cbWritten;313 }314 }315 }316 else317 rc = VERR_AUDIO_STREAM_NOT_READY;318 319 int rc2 = AudioTestSetObjClose(pObj);320 if (RT_SUCCESS(rc))321 rc = rc2;322 323 if (RT_FAILURE(rc))324 RTTestFailed(g_hTest, "Playing tone done failed with %Rrc\n", rc);325 326 return rc;327 }328 329 /**330 * Records a test tone from a specific audio test stream.331 *332 * @returns VBox status code.333 * @param pTstEnv Test environment to use for running the test.334 * @param pStream Stream to use for recording the tone.335 * @param pParms Tone parameters to use.336 *337 * @note Blocking function.338 */339 static int audioTestRecordTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms)340 {341 const char *pcszPathOut = pTstEnv->Set.szPathAbs;342 343 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Recording test tone (for %RU32ms)\n", pParms->msDuration);344 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Writing to '%s'\n", pcszPathOut);345 346 /** @todo Use .WAV here? */347 PAUDIOTESTOBJ pObj;348 int rc = AudioTestSetObjCreateAndRegister(&pTstEnv->Set, "guest-tone-rec.pcm", &pObj);349 AssertRCReturn(rc, rc);350 351 if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream))352 {353 const uint32_t cbPerSched = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint);354 AssertStmt(cbPerSched, rc = VERR_INVALID_PARAMETER);355 uint32_t cbToRead = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration);356 AssertStmt(cbToRead, rc = VERR_INVALID_PARAMETER);357 358 if (RT_SUCCESS(rc))359 {360 AudioTestSetObjAddMetadataStr(pObj, "buffer_size_ms=%RU32\n", pTstEnv->cMsBufferSize);361 AudioTestSetObjAddMetadataStr(pObj, "prebuf_size_ms=%RU32\n", pTstEnv->cMsPreBuffer);362 AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint);363 364 363 uint8_t abBuf[_4K]; 365 364 … … 444 443 const PAUDIOTESTSTREAM pTstStream = &pTstEnv->aStreams[0]; /** @todo Make this dynamic. */ 445 444 446 int rc = audioTestCreateStreamDefaultOut(pTstEnv, pTstStream, &pToneParms->Props); 445 int rc = audioTestStreamInit(&pTstEnv->DrvStack, pTstStream, PDMAUDIODIR_OUT, &pTstEnv->Props, false /* fWithMixer */, 446 pTstEnv->cMsBufferSize, pTstEnv->cMsPreBuffer, pTstEnv->cMsSchedulingHint); 447 447 if (RT_SUCCESS(rc)) 448 448 { … … 484 484 const PAUDIOTESTSTREAM pTstStream = &pTstEnv->aStreams[0]; /** @todo Make this dynamic. */ 485 485 486 int rc = audioTestCreateStreamDefaultIn(pTstEnv, pTstStream, &pToneParms->Props); 486 int rc = audioTestStreamInit(&pTstEnv->DrvStack, pTstStream, PDMAUDIODIR_IN, &pTstEnv->Props, false /* fWithMixer */, 487 pTstEnv->cMsBufferSize, pTstEnv->cMsPreBuffer, pTstEnv->cMsSchedulingHint); 487 488 if (RT_SUCCESS(rc)) 488 489 { … … 666 667 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Temp directory is '%s'\n", pTstEnv->szPathTemp); 667 668 669 if (!pTstEnv->cMsBufferSize) 670 pTstEnv->cMsBufferSize = UINT32_MAX; 671 if (!pTstEnv->cMsPreBuffer) 672 pTstEnv->cMsPreBuffer = UINT32_MAX; 673 if (!pTstEnv->cMsSchedulingHint) 674 pTstEnv->cMsSchedulingHint = UINT32_MAX; 675 668 676 PDMAudioHostEnumInit(&pTstEnv->DevEnum); 669 670 pTstEnv->cMsBufferSize = 300; /* ms */ /** @todo Randomize this also? */671 pTstEnv->cMsPreBuffer = 150; /* ms */ /** @todo Ditto. */672 pTstEnv->cMsSchedulingHint = RTRandU32Ex(10, 80); /* Choose a random scheduling (in ms). */673 677 674 678 bool fUseDriverStack = false; /* Whether to init + use the audio driver stack or not. */ … … 691 695 692 696 PPDMAUDIOHOSTDEV pDev; 693 rc = audioTestDevicesEnumerateAndCheck(pTstEnv, NULL /* pszDevice */, &pDev); /** @todo Implement device checking. */697 rc = audioTestDevicesEnumerateAndCheck(pTstEnv, pTstEnv->szDev, &pDev); 694 698 if (RT_FAILURE(rc)) 695 699 return rc; -
trunk/src/VBox/ValidationKit/utils/audio/vkatInternal.h
r89837 r89890 165 165 /** The stream config. */ 166 166 PDMAUDIOSTREAMCFG Cfg; 167 /** Associated mixing stream. Optional. */ 168 AUDIOTESTDRVMIXSTREAM Mix; 167 169 } AUDIOTESTSTREAM; 168 170 /** Pointer to audio test stream. */ … … 184 186 /** Whether skip the actual verification or not. */ 185 187 bool fSkipVerify; 188 /** The PCM properties to use. */ 189 PDMAUDIOPCMPROPS Props; 190 /** Name of the audio device to use. 191 * If empty the default audio device will be used. */ 192 char szDev[128]; 193 /** Audio volume to use (in percent). 194 * Might not be available on all systems. */ 195 uint8_t uVolumePercent; 186 196 /** Output path for storing the test environment's final test files. */ 187 197 char szTag[AUDIOTEST_TAG_MAX]; … … 427 437 /** @} */ 428 438 429 int audioTestWorker(PAUDIOTESTENV pTstEnv , PAUDIOTESTPARMS pOverrideParms);439 int audioTestWorker(PAUDIOTESTENV pTstEnv); 430 440 431 441 /** @name Command handlers
Note:
See TracChangeset
for help on using the changeset viewer.