Changeset 89456 in vbox for trunk/src/VBox/ValidationKit
- Timestamp:
- Jun 2, 2021 8:43:16 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp
r89442 r89456 246 246 *********************************************************************************************************************************/ 247 247 static int audioTestCombineParms(PAUDIOTESTPARMS pBaseParms, PAUDIOTESTPARMS pOverrideParms); 248 static int audioTestCreateStreamDefaultIn(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps); 248 249 static int audioTestCreateStreamDefaultOut(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps); 249 250 static int audioTestStreamDestroy(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream); … … 439 440 uint8_t abBuf[_4K]; 440 441 441 const uint32_t cbPerMs = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint); 442 uint32_t cbToWrite = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration); 443 444 AudioTestSetObjAddMetadataStr(pObj, "buffer_size_ms=%RU32\n", pTstEnv->cMsBufferSize); 445 AudioTestSetObjAddMetadataStr(pObj, "prebuf_size_ms=%RU32\n", pTstEnv->cMsPreBuffer); 446 AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint); 447 448 while (cbToWrite) 449 { 450 uint32_t cbWritten = 0; 451 uint32_t cbToGenerate = RT_MIN(cbToWrite, RT_MIN(cbPerMs, sizeof(abBuf))); 452 Assert(cbToGenerate); 453 454 rc = AudioTestToneGenerate(&TstTone, abBuf, cbToGenerate, &cbBuf); 455 if (RT_SUCCESS(rc)) 442 const uint32_t cbPerSched = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint); 443 AssertStmt(cbPerSched, rc = VERR_INVALID_PARAMETER); 444 uint32_t cbToWrite = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration); 445 AssertStmt(cbToWrite, rc = VERR_INVALID_PARAMETER); 446 447 if (RT_SUCCESS(rc)) 448 { 449 AudioTestSetObjAddMetadataStr(pObj, "buffer_size_ms=%RU32\n", pTstEnv->cMsBufferSize); 450 AudioTestSetObjAddMetadataStr(pObj, "prebuf_size_ms=%RU32\n", pTstEnv->cMsPreBuffer); 451 AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint); 452 453 while (cbToWrite) 456 454 { 457 /* Write stuff to disk before trying to play it. Help analysis later. */ 458 rc = AudioTestSetObjWrite(pObj, abBuf, cbBuf); 455 uint32_t cbWritten = 0; 456 uint32_t cbToGenerate = RT_MIN(cbToWrite, RT_MIN(cbPerSched, sizeof(abBuf))); 457 Assert(cbToGenerate); 458 459 rc = AudioTestToneGenerate(&TstTone, abBuf, cbToGenerate, &cbBuf); 459 460 if (RT_SUCCESS(rc)) 460 rc = audioTestDriverStackStreamPlay(&pTstEnv->DrvStack, pStream->pStream, 461 abBuf, cbBuf, &cbWritten); 461 { 462 /* Write stuff to disk before trying to play it. Help analysis later. */ 463 rc = AudioTestSetObjWrite(pObj, abBuf, cbBuf); 464 if (RT_SUCCESS(rc)) 465 rc = audioTestDriverStackStreamPlay(&pTstEnv->DrvStack, pStream->pStream, 466 abBuf, cbBuf, &cbWritten); 467 } 468 469 if (RT_FAILURE(rc)) 470 break; 471 472 RTThreadSleep(pTstEnv->cMsSchedulingHint); 473 474 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Written %RU32 bytes\n", cbWritten); 475 476 Assert(cbToWrite >= cbWritten); 477 cbToWrite -= cbWritten; 462 478 } 463 464 if (RT_FAILURE(rc))465 break;466 467 RTThreadSleep(pTstEnv->cMsSchedulingHint);468 469 Assert(cbToWrite >= cbWritten);470 cbToWrite -= cbWritten;471 479 } 472 480 } … … 478 486 rc = rc2; 479 487 480 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Play tone done\n"); 488 if (RT_FAILURE(rc)) 489 RTTestFailed(g_hTest, "Playing tone done failed with %Rrc\n", rc); 490 491 return rc; 492 } 493 494 /** 495 * Records a test tone from a specific audio test stream. 496 * 497 * @returns VBox status code. 498 * @param pTstEnv Test environment to use for running the test. 499 * @param pStream Stream to use for recording the tone. 500 * @param pParms Tone parameters to use. 501 * 502 * @note Blocking function. 503 */ 504 static int audioTestRecordTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms) 505 { 506 const char *pcszPathOut = pTstEnv->Set.szPathAbs; 507 508 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Recording test tone (for %RU32ms)\n", pParms->msDuration); 509 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Writing to '%s'\n", pcszPathOut); 510 511 /** @todo Use .WAV here? */ 512 PAUDIOTESTOBJ pObj; 513 int rc = AudioTestSetObjCreateAndRegister(&pTstEnv->Set, "tone-rec.pcm", &pObj); 514 AssertRCReturn(rc, rc); 515 516 if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream)) 517 { 518 const uint32_t cbPerSched = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint); 519 AssertStmt(cbPerSched, rc = VERR_INVALID_PARAMETER); 520 uint32_t cbToRead = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration); 521 AssertStmt(cbToRead, rc = VERR_INVALID_PARAMETER); 522 523 if (RT_SUCCESS(rc)) 524 { 525 AudioTestSetObjAddMetadataStr(pObj, "buffer_size_ms=%RU32\n", pTstEnv->cMsBufferSize); 526 AudioTestSetObjAddMetadataStr(pObj, "prebuf_size_ms=%RU32\n", pTstEnv->cMsPreBuffer); 527 AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint); 528 529 uint8_t abBuf[_4K]; 530 531 while (cbToRead) 532 { 533 const uint32_t cbChunk = RT_MIN(cbToRead, RT_MIN(cbPerSched, sizeof(abBuf))); 534 535 uint32_t cbRead = 0; 536 rc = audioTestDriverStackStreamCapture(&pTstEnv->DrvStack, pStream->pStream, (void *)abBuf, cbChunk, &cbRead); 537 if (RT_SUCCESS(rc)) 538 rc = AudioTestSetObjWrite(pObj, abBuf, cbRead); 539 540 if (RT_FAILURE(rc)) 541 break; 542 543 RTThreadSleep(pTstEnv->cMsSchedulingHint); 544 545 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Read %RU32 bytes\n", cbRead); 546 547 Assert(cbToRead >= cbRead); 548 cbToRead -= cbRead; 549 } 550 } 551 } 552 else 553 rc = VERR_AUDIO_STREAM_NOT_READY; 554 555 int rc2 = AudioTestSetObjClose(pObj); 556 if (RT_SUCCESS(rc)) 557 rc = rc2; 558 559 if (RT_FAILURE(rc)) 560 RTTestFailed(g_hTest, "Recording tone done failed with %Rrc\n", rc); 481 561 482 562 return rc; … … 555 635 } 556 636 637 /** @copydoc ATSCALLBACKS::pfnToneRecord */ 638 static DECLCALLBACK(int) audioTestSvcToneRecordCallback(void const *pvUser, PPDMAUDIOSTREAMCFG pStreamCfg, PAUDIOTESTTONEPARMS pToneParms) 639 { 640 PATSCALLBACKCTX pCtx = (PATSCALLBACKCTX)pvUser; 641 PAUDIOTESTENV pTstEnv = pCtx->pTstEnv; 642 643 const PAUDIOTESTSTREAM pTstStream = &pTstEnv->aStreams[0]; /** @todo Make this dynamic. */ 644 645 int rc = audioTestCreateStreamDefaultIn(pTstEnv, pTstStream, &pStreamCfg->Props); 646 if (RT_SUCCESS(rc)) 647 { 648 AUDIOTESTPARMS TstParms; 649 RT_ZERO(TstParms); 650 TstParms.enmType = AUDIOTESTTYPE_TESTTONE_RECORD; 651 TstParms.enmDir = PDMAUDIODIR_IN; 652 TstParms.Props = pStreamCfg->Props; 653 pToneParms->Props = pStreamCfg->Props; 654 TstParms.TestTone = *pToneParms; 655 656 PAUDIOTESTENTRY pTst; 657 rc = AudioTestSetTestBegin(&pTstEnv->Set, "Recording test tone", &TstParms, &pTst); 658 if (RT_SUCCESS(rc)) 659 { 660 rc = audioTestRecordTone(pTstEnv, pTstStream, pToneParms); 661 if (RT_SUCCESS(rc)) 662 { 663 AudioTestSetTestDone(pTst); 664 } 665 else 666 AudioTestSetTestFailed(pTst, rc, "Recording tone failed"); 667 } 668 669 int rc2 = audioTestStreamDestroy(pTstEnv, pTstStream); 670 if (RT_SUCCESS(rc)) 671 rc = rc2; 672 } 673 else 674 RTTestFailed(g_hTest, "Error creating input stream, rc=%Rrc\n", rc); 675 676 return rc; 677 } 557 678 558 679 /********************************************************************************************************************************* … … 627 748 Callbacks.pfnTestSetEnd = audioTestSvcTestSetEndCallback; 628 749 Callbacks.pfnTonePlay = audioTestSvcTonePlayCallback; 750 Callbacks.pfnToneRecord = audioTestSvcToneRecordCallback; 629 751 Callbacks.pvUser = &Ctx; 630 752 … … 880 1002 881 1003 /** 882 * Records a test tone from a specific audio test stream.883 *884 * @returns VBox status code.885 * @param pTstEnv Test environment to use for running the test.886 * @param pStream Stream to use for recording the tone.887 * @param pParms Tone parameters to use.888 *889 * @note Blocking function.890 */891 static int audioTestRecordTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms)892 {893 const char *pcszPathOut = pTstEnv->Set.szPathAbs;894 895 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Recording test tone (for %RU32ms)\n", pParms->msDuration);896 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Writing to '%s'\n", pcszPathOut);897 898 /** @todo Use .WAV here? */899 PAUDIOTESTOBJ pObj;900 int rc = AudioTestSetObjCreateAndRegister(&pTstEnv->Set, "tone-rec.pcm", &pObj);901 AssertRCReturn(rc, rc);902 903 if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream))904 {905 uint8_t abBuf[_4K];906 907 const uint64_t tsStartMs = RTTimeMilliTS();908 909 do910 {911 uint32_t cbRead = 0;912 rc = audioTestDriverStackStreamCapture(&pTstEnv->DrvStack, pStream->pStream, (void *)abBuf, sizeof(abBuf), &cbRead);913 if (RT_SUCCESS(rc))914 rc = AudioTestSetObjWrite(pObj, abBuf, cbRead);915 916 if (RT_FAILURE(rc))917 break;918 919 if (RTTimeMilliTS() - tsStartMs >= pParms->msDuration)920 break;921 922 RTThreadSleep(pTstEnv->cMsSchedulingHint);923 924 } while (RT_SUCCESS(rc));925 }926 else927 rc = VERR_AUDIO_STREAM_NOT_READY;928 929 int rc2 = AudioTestSetObjClose(pObj);930 if (RT_SUCCESS(rc))931 rc = rc2;932 933 return rc;934 }935 936 /**937 1004 * Creates an audio default output (playback) test stream. 938 1005 * Convenience function. … … 1022 1089 if (RT_SUCCESS(rc)) 1023 1090 { 1024 AudioTestSetTestDone(pTst);1091 AudioTestSetTestDone(pTst); 1025 1092 } 1026 1093 else … … 1054 1121 pTstParmsAcq->enmType = AUDIOTESTTYPE_TESTTONE_RECORD; 1055 1122 1056 RT_ZERO(pTstParmsAcq->TestTone); 1057 PDMAudioPropsInit(&pTstParmsAcq->TestTone.Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */); 1123 PDMAudioPropsInit(&pTstParmsAcq->Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */); 1058 1124 1059 1125 pTstParmsAcq->enmDir = PDMAUDIODIR_IN; … … 1077 1143 int rc = VINF_SUCCESS; 1078 1144 1079 PAUDIOTESTSTREAM pStream = &pTstEnv->aStreams[0];1080 1081 1145 for (uint32_t i = 0; i < pTstParms->cIterations; i++) 1082 1146 { … … 1087 1151 if (RT_SUCCESS(rc)) 1088 1152 { 1089 /** @todo For now we're (re-)creating the recording stream for each iteration. Change that to be random. */ 1090 rc = audioTestCreateStreamDefaultIn(pTstEnv, pStream, &pTstParms->TestTone.Props); 1091 if (RT_SUCCESS(rc)) 1092 rc = audioTestRecordTone(pTstEnv, pStream, &pTstParms->TestTone); 1093 1094 int rc2 = audioTestStreamDestroy(pTstEnv, pStream); 1095 if (RT_SUCCESS(rc)) 1096 rc = rc2; 1097 1153 PDMAUDIOSTREAMCFG Cfg; 1154 RT_ZERO(Cfg); 1155 /** @todo Add more parameters here? */ 1156 Cfg.Props = pTstParms->Props; 1157 1158 rc = AudioTestSvcClientToneRecord(&pTstEnv->u.Host.Client, &Cfg, &pTstParms->TestTone); 1098 1159 if (RT_SUCCESS(rc)) 1099 1160 { 1100 AudioTestSetTestDone(pTst);1161 AudioTestSetTestDone(pTst); 1101 1162 } 1102 1163 else
Note:
See TracChangeset
for help on using the changeset viewer.