Changeset 89431 in vbox for trunk/src/VBox
- Timestamp:
- Jun 1, 2021 12:57:36 PM (4 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioTest.cpp
r89389 r89431 546 546 { 547 547 PAUDIOTESTERRORENTRY pEntry = (PAUDIOTESTERRORENTRY)RTMemAlloc(sizeof(AUDIOTESTERRORENTRY)); 548 Assert Return(pEntry, VERR_NO_MEMORY);548 AssertPtrReturn(pEntry, VERR_NO_MEMORY); 549 549 550 550 if (RTStrPrintf2V(pEntry->szDesc, sizeof(pEntry->szDesc), pszDesc, args) < 0) … … 633 633 { 634 634 return RTPathJoin(pszPathAbs, cbPathAbs, pSet->szPathAbs, pszObjName); 635 } 636 637 /** 638 * Returns the tag of a test set. 639 * 640 * @returns Test set tag. 641 * @param pSet Test set to return tag for. 642 */ 643 const char *AudioTestSetGetTag(PAUDIOTESTSET pSet) 644 { 645 return pSet->szTag; 635 646 } 636 647 … … 746 757 if (RT_SUCCESS(rc)) 747 758 { 759 PAUDIOTESTOBJMETA pMeta, pMetaNext; 760 RTListForEachSafe(&pObj->lstMeta, pMeta, pMetaNext, AUDIOTESTOBJMETA, Node) 761 { 762 switch (pMeta->enmType) 763 { 764 case AUDIOTESTOBJMETADATATYPE_STRING: 765 { 766 RTStrFree((char *)pMeta->pvMeta); 767 break; 768 } 769 770 default: 771 AssertFailed(); 772 break; 773 } 774 775 RTListNodeRemove(&pMeta->Node); 776 RTMemFree(pMeta); 777 } 778 748 779 RTListNodeRemove(&pObj->Node); 749 780 RTMemFree(pObj); … … 870 901 rc = audioTestManifestWrite(pSet, "obj_name=%s\n", pObj->szName); 871 902 AssertRCReturn(rc, rc); 903 904 switch (pObj->enmType) 905 { 906 case AUDIOTESTOBJTYPE_FILE: 907 { 908 rc = audioTestManifestWrite(pSet, "obj_size=%RU64\n", pObj->File.cbSize); 909 AssertRCReturn(rc, rc); 910 break; 911 } 912 913 default: 914 AssertFailed(); 915 break; 916 } 917 918 /* 919 * Write all meta data. 920 */ 921 PAUDIOTESTOBJMETA pMeta; 922 RTListForEach(&pObj->lstMeta, pMeta, AUDIOTESTOBJMETA, Node) 923 { 924 switch (pMeta->enmType) 925 { 926 case AUDIOTESTOBJMETADATATYPE_STRING: 927 { 928 rc = audioTestManifestWrite(pSet, (const char *)pMeta->pvMeta); 929 AssertRCReturn(rc, rc); 930 break; 931 } 932 933 default: 934 AssertFailed(); 935 break; 936 } 937 } 872 938 } 873 939 … … 938 1004 AssertPtrReturn(pObj, VERR_NO_MEMORY); 939 1005 1006 RTListInit(&pObj->lstMeta); 1007 940 1008 if (RTStrPrintf2(pObj->szName, sizeof(pObj->szName), "%04RU32-%s", pSet->cObj, pszName) <= 0) 941 1009 AssertFailedReturn(VERR_BUFFER_OVERFLOW); … … 996 1064 997 1065 /** 1066 * Adds meta data to a test object as a string, va_list version. 1067 * 1068 * @returns VBox status code. 1069 * @param pObj Test object to add meta data for. 1070 * @param pszFormat Format string to add. 1071 * @param va_list Variable arguments list to use for the format string. 1072 */ 1073 static int audioTestSetObjAddMetadataStrV(PAUDIOTESTOBJ pObj, const char *pszFormat, va_list va) 1074 { 1075 PAUDIOTESTOBJMETA pMeta = (PAUDIOTESTOBJMETA)RTMemAlloc(sizeof(AUDIOTESTOBJMETA)); 1076 AssertPtrReturn(pMeta, VERR_NO_MEMORY); 1077 1078 pMeta->pvMeta = RTStrAPrintf2V(pszFormat, va); 1079 AssertPtrReturn(pMeta->pvMeta, VERR_BUFFER_OVERFLOW); 1080 pMeta->cbMeta = RTStrNLen((const char *)pMeta->pvMeta, RTSTR_MAX); 1081 1082 pMeta->enmType = AUDIOTESTOBJMETADATATYPE_STRING; 1083 1084 RTListAppend(&pObj->lstMeta, &pMeta->Node); 1085 1086 return VINF_SUCCESS; 1087 } 1088 1089 /** 1090 * Adds meta data to a test object as a string. 1091 * 1092 * @returns VBox status code. 1093 * @param pObj Test object to add meta data for. 1094 * @param pszFormat Format string to add. 1095 * @param ... Variable arguments for the format string. 1096 */ 1097 int AudioTestSetObjAddMetadataStr(PAUDIOTESTOBJ pObj, const char *pszFormat, ...) 1098 { 1099 va_list va; 1100 1101 va_start(va, pszFormat); 1102 int rc = audioTestSetObjAddMetadataStrV(pObj, pszFormat, va); 1103 va_end(va); 1104 1105 return rc; 1106 } 1107 1108 /** 998 1109 * Closes an opened audio test object. 999 1110 * … … 1013 1124 if (RTFileIsValid(pObj->File.hFile)) 1014 1125 { 1126 pObj->File.cbSize = RTFileTell(pObj->File.hFile); 1127 1015 1128 rc = RTFileClose(pObj->File.hFile); 1016 1129 pObj->File.hFile = NIL_RTFILE; … … 1020 1133 } 1021 1134 1135 /** 1136 * Begins a new test of a test set. 1137 * 1138 * @returns VBox status code. 1139 * @param pSet Test set to begin new test for. 1140 * @param pszDesc Test description. 1141 * @param pParms Test parameters to use. 1142 * @param ppEntry Where to return the new test handle. 1143 */ 1022 1144 int AudioTestSetTestBegin(PAUDIOTESTSET pSet, const char *pszDesc, PAUDIOTESTPARMS pParms, PAUDIOTESTENTRY *ppEntry) 1023 1145 { … … 1095 1217 } 1096 1218 1219 /** 1220 * Marks a running test as failed. 1221 * 1222 * @returns VBox status code. 1223 * @param pEntry Test to mark. 1224 * @param rc Error code. 1225 * @param pszErr Error description. 1226 */ 1097 1227 int AudioTestSetTestFailed(PAUDIOTESTENTRY pEntry, int rc, const char *pszErr) 1098 1228 { … … 1113 1243 } 1114 1244 1245 /** 1246 * Marks a running test as successfully done. 1247 * 1248 * @returns VBox status code. 1249 * @param pEntry Test to mark. 1250 */ 1115 1251 int AudioTestSetTestDone(PAUDIOTESTENTRY pEntry) 1116 1252 { … … 1143 1279 /** @todo Check and deny if \a pszOutDir is part of the set's path. */ 1144 1280 1281 int rc = RTDirCreateFullPath(pszOutDir, 0755); 1282 if (RT_FAILURE(rc)) 1283 return rc; 1284 1145 1285 char szOutName[RT_ELEMENTS(AUDIOTEST_PATH_PREFIX_STR) + AUDIOTEST_TAG_MAX + 16]; 1146 1286 if (RTStrPrintf2(szOutName, sizeof(szOutName), "%s-%s%s", … … 1149 1289 1150 1290 char szOutPath[RTPATH_MAX]; 1151 intrc = RTPathJoin(szOutPath, sizeof(szOutPath), pszOutDir, szOutName);1291 rc = RTPathJoin(szOutPath, sizeof(szOutPath), pszOutDir, szOutName); 1152 1292 AssertRCReturn(rc, rc); 1153 1293 … … 1155 1295 unsigned cArgs = 0; 1156 1296 1157 apszArgs[cArgs++] = " AudioTest";1297 apszArgs[cArgs++] = "vkat"; 1158 1298 apszArgs[cArgs++] = "--create"; 1159 1299 apszArgs[cArgs++] = "--gzip"; … … 1214 1354 unsigned cArgs = 0; 1215 1355 1216 apszArgs[cArgs++] = " AudioTest";1356 apszArgs[cArgs++] = "vkat"; 1217 1357 apszArgs[cArgs++] = "--extract"; 1218 1358 apszArgs[cArgs++] = "--gunzip"; -
trunk/src/VBox/Devices/Audio/AudioTest.h
r89387 r89431 170 170 typedef struct AUDIOTESTOBJFILE 171 171 { 172 RTFILE hFile; 172 /** File handle. */ 173 RTFILE hFile; 174 /** Total size (in bytes). */ 175 size_t cbSize; 173 176 } AUDIOTESTOBJFILE; 174 177 /** Pointer to an audio test object file. */ 175 178 typedef AUDIOTESTOBJFILE *PAUDIOTESTOBJFILE; 179 180 /** 181 * Enumeration for an audio test object meta data type. 182 */ 183 typedef enum AUDIOTESTOBJMETADATATYPE 184 { 185 /** Unknown / invalid, do not use. */ 186 AUDIOTESTOBJMETADATATYPE_INVALID = 0, 187 /** Meta data is an UTF-8 string. */ 188 AUDIOTESTOBJMETADATATYPE_STRING, 189 /** The usual 32-bit hack. */ 190 AUDIOTESTOBJMETADATATYPE_32BIT_HACK = 0x7fffffff 191 } AUDIOTESTOBJMETADATATYPE; 192 193 /** 194 * Structure for keeping a meta data block. 195 */ 196 typedef struct AUDIOTESTOBJMETA 197 { 198 /** List node. */ 199 RTLISTNODE Node; 200 /** Meta data type. */ 201 AUDIOTESTOBJMETADATATYPE enmType; 202 /** Meta data block. */ 203 void *pvMeta; 204 /** Size (in bytes) of \a pvMeta. */ 205 size_t cbMeta; 206 } AUDIOTESTOBJMETA; 207 /** Pointer to an audio test object file. */ 208 typedef AUDIOTESTOBJMETA *PAUDIOTESTOBJMETA; 176 209 177 210 /** … … 193 226 /** The object type. */ 194 227 AUDIOTESTOBJTYPE enmType; 228 /** Meta data list. */ 229 RTLISTANCHOR lstMeta; 195 230 /** Union for holding the object type-specific data. */ 196 231 union … … 323 358 int AudioTestSetObjCreateAndRegister(PAUDIOTESTSET pSet, const char *pszName, PAUDIOTESTOBJ *ppObj); 324 359 int AudioTestSetObjWrite(PAUDIOTESTOBJ pObj, void *pvBuf, size_t cbBuf); 360 int AudioTestSetObjAddMetadataStr(PAUDIOTESTOBJ pObj, const char *pszFormat, ...); 325 361 int AudioTestSetObjClose(PAUDIOTESTOBJ pObj); 326 362 … … 334 370 int AudioTestSetClose(PAUDIOTESTSET pSet); 335 371 int AudioTestSetWipe(PAUDIOTESTSET pSet); 372 const char *AudioTestSetGetTag(PAUDIOTESTSET pSet); 336 373 bool AudioTestSetIsPacked(const char *pszPath); 337 374 int AudioTestSetPack(PAUDIOTESTSET pSet, const char *pszOutDir, char *pszFileName, size_t cbFileName); -
trunk/src/VBox/Devices/Audio/AudioTestService.cpp
r89228 r89431 474 474 int rc; 475 475 if (pPktHdr->cb == sizeof(ATSPKTHDR)) 476 { 476 477 rc = atsReplyAck(pThis, pClient, pPktHdr); 478 } 477 479 else 478 480 rc = atsReplyBadSize(pThis, pClient, pPktHdr, sizeof(ATSPKTHDR)); … … 514 516 pClient->enmState = ATSCLIENTSTATE_READY; 515 517 } 518 519 return rc; 520 } 521 522 /** 523 * Verifies and acknowledges a "TSET BEG" request. 524 * 525 * @returns IPRT status code. 526 * @param pThis The ATS instance. 527 * @param pClient The ATS client structure. 528 * @param pPktHdr The test set begin packet. 529 */ 530 static int atsDoTestSetBegin(PATSSERVER pThis, PATSCLIENTINST pClient, PCATSPKTHDR pPktHdr) 531 { 532 if (pPktHdr->cb != sizeof(ATSPKTREQTSETBEG)) 533 return atsReplyBadSize(pThis, pClient, pPktHdr, sizeof(ATSPKTREQTSETBEG)); 534 535 PATSPKTREQTSETBEG pReq = (PATSPKTREQTSETBEG)pPktHdr; 536 537 int rc = VINF_SUCCESS; 538 539 if (pThis->Callbacks.pfnTestSetBegin) 540 { 541 rc = pThis->Callbacks.pfnTestSetBegin(pThis->Callbacks.pvUser, pReq->szTag); 542 if (RT_FAILURE(rc)) 543 return atsReplyRC(pThis, pClient, pPktHdr, rc, "Beginning test set '%s' failed", pReq->szTag); 544 } 545 546 if (RT_SUCCESS(rc)) 547 { 548 rc = atsReplyAck(pThis, pClient, pPktHdr); 549 } 550 else 551 rc = atsReplyRC(pThis, pClient, pPktHdr, rc, "Beginning test set failed"); 552 553 return rc; 554 } 555 556 /** 557 * Verifies and acknowledges a "TSET END" request. 558 * 559 * @returns IPRT status code. 560 * @param pThis The ATS instance. 561 * @param pClient The ATS client structure. 562 * @param pPktHdr The test set end packet. 563 */ 564 static int atsDoTestSetEnd(PATSSERVER pThis, PATSCLIENTINST pClient, PCATSPKTHDR pPktHdr) 565 { 566 if (pPktHdr->cb != sizeof(ATSPKTREQTSETEND)) 567 return atsReplyBadSize(pThis, pClient, pPktHdr, sizeof(ATSPKTREQTSETEND)); 568 569 PATSPKTREQTSETEND pReq = (PATSPKTREQTSETEND)pPktHdr; 570 571 int rc = VINF_SUCCESS; 572 573 if (pThis->Callbacks.pfnTestSetEnd) 574 { 575 rc = pThis->Callbacks.pfnTestSetEnd(pThis->Callbacks.pvUser, pReq->szTag); 576 if (RT_FAILURE(rc)) 577 return atsReplyRC(pThis, pClient, pPktHdr, rc, "Ending test set '%s' failed", pReq->szTag); 578 } 579 if (RT_SUCCESS(rc)) 580 { 581 rc = atsReplyAck(pThis, pClient, pPktHdr); 582 } 583 else 584 rc = atsReplyRC(pThis, pClient, pPktHdr, rc, "Ending test set failed"); 516 585 517 586 return rc; … … 574 643 else if (atsIsSameOpcode(pPktHdr, ATSPKT_OPCODE_BYE)) 575 644 rc = atsDoBye(pThis, pClient, pPktHdr); 645 /* Test set handling: */ 646 else if (atsIsSameOpcode(pPktHdr, ATSPKT_OPCODE_TESTSET_BEGIN)) 647 rc = atsDoTestSetBegin(pThis, pClient, pPktHdr); 648 else if (atsIsSameOpcode(pPktHdr, ATSPKT_OPCODE_TESTSET_END)) 649 rc = atsDoTestSetEnd(pThis, pClient, pPktHdr); 576 650 /* Audio testing: */ 577 651 else if (atsIsSameOpcode(pPktHdr, ATSPKT_OPCODE_TONE_PLAY)) -
trunk/src/VBox/Devices/Audio/AudioTestService.h
r89399 r89431 33 33 typedef struct ATSCALLBACKS 34 34 { 35 /** 36 * Begins a test set. Optional. 37 * 38 * @returns VBox status code. 39 * @param pvUser User-supplied pointer to context data. Optional. 40 * @param pszTag Tag of test set to begin. 41 */ 42 DECLR3CALLBACKMEMBER(int, pfnTestSetBegin, (void const *pvUser, const char *pszTag)); 43 44 /** 45 * Ends the current test set. Optional. 46 * 47 * @returns VBox status code. 48 * @param pvUser User-supplied pointer to context data. Optional. 49 * @param pszTag Tag of test set to end. 50 */ 51 DECLR3CALLBACKMEMBER(int, pfnTestSetEnd, (void const *pvUser, const char *pszTag)); 52 35 53 /** 36 54 * Plays a test tone. … … 79 97 typedef ATSSERVER *PATSSERVER; 80 98 81 82 99 int AudioTestSvcInit(PATSSERVER pThis, PCATSCALLBACKS pCallbacks); 83 100 int AudioTestSvcDestroy(PATSSERVER pThis); -
trunk/src/VBox/Devices/Audio/AudioTestServiceClient.cpp
r89399 r89431 305 305 306 306 /** 307 * Tells the server to begin a new test set. 308 * 309 * @returns VBox status code. 310 * @param pClient Client to issue command for. 311 * @param pszTag Tag to use for the test set to begin. 312 */ 313 int AudioTestSvcClientTestSetBegin(PATSCLIENT pClient, const char *pszTag) 314 { 315 ATSPKTREQTSETBEG Req; 316 317 int rc = RTStrCopy(Req.szTag, sizeof(Req.szTag), pszTag); 318 AssertRCReturn(rc, rc); 319 320 audioTestSvcClientReqHdrInit(&Req.Hdr, sizeof(Req), ATSPKT_OPCODE_TESTSET_BEGIN, 0); 321 322 rc = audioTestSvcClientSendMsg(pClient, &Req, sizeof(Req), NULL, 0); 323 if (RT_SUCCESS(rc)) 324 rc = audioTestSvcClientRecvAck(pClient); 325 326 return rc; 327 } 328 329 /** 330 * Tells the server to end a runing test set. 331 * 332 * @returns VBox status code. 333 * @param pClient Client to issue command for. 334 * @param pszTag Tag of test set to end. 335 */ 336 int AudioTestSvcClientTestSetEnd(PATSCLIENT pClient, const char *pszTag) 337 { 338 ATSPKTREQTSETEND Req; 339 340 int rc = RTStrCopy(Req.szTag, sizeof(Req.szTag), pszTag); 341 AssertRCReturn(rc, rc); 342 343 audioTestSvcClientReqHdrInit(&Req.Hdr, sizeof(Req), ATSPKT_OPCODE_TESTSET_END, 0); 344 345 rc = audioTestSvcClientSendMsg(pClient, &Req, sizeof(Req), NULL, 0); 346 if (RT_SUCCESS(rc)) 347 rc = audioTestSvcClientRecvAck(pClient); 348 349 return rc; 350 } 351 352 /** 307 353 * Tells the server to play a (test) tone. 308 354 * -
trunk/src/VBox/Devices/Audio/AudioTestServiceClient.h
r89399 r89431 31 31 32 32 int AudioTestSvcClientConnect(PATSCLIENT pClient, const char *pszAddr, uint32_t uPort); 33 int AudioTestSvcClientTestSetBegin(PATSCLIENT pClient, const char *pszTag); 34 int AudioTestSvcClientTestSetEnd(PATSCLIENT pClient, const char *pszTag); 33 35 int AudioTestSvcClientTonePlay(PATSCLIENT pClient, PPDMAUDIOSTREAMCFG pStreamCfg, PAUDIOTESTTONEPARMS pToneParms); 34 36 int AudioTestSvcClientClose(PATSCLIENT pClient); -
trunk/src/VBox/Devices/Audio/AudioTestServiceProtocol.h
r89380 r89431 121 121 /* No additional structures for BYE. */ 122 122 123 #define ATSPKT_OPCODE_TESTSET_BEGIN "TSET BEG" 124 125 /** 126 * The TSET BEG request structure. 127 */ 128 typedef struct ATSPKTREQTSETBEG 129 { 130 /** Embedded packet header. */ 131 ATSPKTHDR Hdr; 132 /** Audio test set tag to use. */ 133 char szTag[AUDIOTEST_TAG_MAX]; 134 } ATSPKTREQTSETBEG; 135 AssertCompileSizeAlignment(ATSPKTREQTSETBEG, ATSPKT_ALIGNMENT); 136 /** Pointer to a TSET BEG reply structure. */ 137 typedef ATSPKTREQTSETBEG *PATSPKTREQTSETBEG; 138 139 #define ATSPKT_OPCODE_TESTSET_END "TSET END" 140 141 /** 142 * The TSET END request structure. 143 */ 144 typedef struct ATSPKTREQTSETEND 145 { 146 /** Embedded packet header. */ 147 ATSPKTHDR Hdr; 148 /** Audio test set tag to use. */ 149 char szTag[AUDIOTEST_TAG_MAX]; 150 } ATSPKTREQTSETEND; 151 AssertCompileSizeAlignment(ATSPKTREQTSETEND, ATSPKT_ALIGNMENT); 152 /** Pointer to a TSET STA reply structure. */ 153 typedef ATSPKTREQTSETEND *PATSPKTREQTSETEND; 154 123 155 #define ATSPKT_OPCODE_TONE_PLAY "TNPLY " 124 156 -
trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp
r89417 r89431 179 179 AUDIOTESTMODE enmMode; 180 180 /** Output path for storing the test environment's final test files. */ 181 char szTag[AUDIOTEST_TAG_MAX]; 182 /** Output path for storing the test environment's final test files. */ 181 183 char szPathOut[RTPATH_MAX]; 182 184 /** Temporary path for this test environment. */ … … 235 237 *********************************************************************************************************************************/ 236 238 static int audioTestCombineParms(PAUDIOTESTPARMS pBaseParms, PAUDIOTESTPARMS pOverrideParms); 237 static int audioTest PlayTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms);239 static int audioTestCreateStreamDefaultOut(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps); 238 240 static int audioTestStreamDestroy(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream); 241 static int audioTestDevicesEnumerateAndCheck(PAUDIOTESTENV pTstEnv, const char *pszDev, PPDMAUDIOHOSTDEV *ppDev); 242 static int audioTestEnvPrologue(PAUDIOTESTENV pTstEnv); 239 243 240 244 static RTEXITCODE audioTestUsage(PRTSTREAM pStrm); … … 393 397 394 398 /********************************************************************************************************************************* 399 * Test Primitives * 400 *********************************************************************************************************************************/ 401 402 /** 403 * Plays a test tone on a specific audio test stream. 404 * 405 * @returns VBox status code. 406 * @param pTstEnv Test environment to use for running the test. 407 * @param pStream Stream to use for playing the tone. 408 * @param pParms Tone parameters to use. 409 * 410 * @note Blocking function. 411 */ 412 static int audioTestPlayTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms) 413 { 414 AUDIOTESTTONE TstTone; 415 AudioTestToneInit(&TstTone, &pParms->Props, pParms->dbFreqHz); 416 417 const char *pcszPathOut = pTstEnv->Set.szPathAbs; 418 419 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Playing test tone (tone frequency is %RU16Hz, %RU32ms)\n", (uint16_t)pParms->dbFreqHz, pParms->msDuration); 420 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Writing to '%s'\n", pcszPathOut); 421 422 /** @todo Use .WAV here? */ 423 PAUDIOTESTOBJ pObj; 424 int rc = AudioTestSetObjCreateAndRegister(&pTstEnv->Set, "tone-play.pcm", &pObj); 425 AssertRCReturn(rc, rc); 426 427 if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream)) 428 { 429 uint32_t cbBuf; 430 uint8_t abBuf[_4K]; 431 432 const uint16_t cSchedulingMs = RTRandU32Ex(10, 80); /* Choose a random scheduling (in ms). */ 433 const uint32_t cbPerMs = PDMAudioPropsMilliToBytes(&pParms->Props, cSchedulingMs); 434 size_t cbToWrite = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration); 435 436 AudioTestSetObjAddMetadataStr(pObj, "schedule_ms=%RU16", cSchedulingMs); 437 438 while (cbToWrite) 439 { 440 uint32_t cbWritten = 0; 441 uint32_t cbToGenerate = RT_MIN(cbToWrite, RT_MIN(cbPerMs, sizeof(abBuf))); 442 Assert(cbToGenerate); 443 444 rc = AudioTestToneGenerate(&TstTone, abBuf, cbToGenerate, &cbBuf); 445 if (RT_SUCCESS(rc)) 446 { 447 /* Write stuff to disk before trying to play it. Help analysis later. */ 448 rc = AudioTestSetObjWrite(pObj, abBuf, cbBuf); 449 if (RT_SUCCESS(rc)) 450 rc = audioTestDriverStackStreamPlay(&pTstEnv->DrvStack, pStream->pStream, 451 abBuf, cbBuf, &cbWritten); 452 } 453 454 if (RT_FAILURE(rc)) 455 break; 456 457 RTThreadSleep(cSchedulingMs); 458 459 Assert(cbToWrite >= cbWritten); 460 cbToWrite -= cbWritten; 461 } 462 } 463 else 464 rc = VERR_AUDIO_STREAM_NOT_READY; 465 466 int rc2 = AudioTestSetObjClose(pObj); 467 if (RT_SUCCESS(rc)) 468 rc = rc2; 469 470 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Play tone done\n"); 471 472 return rc; 473 } 474 475 /********************************************************************************************************************************* 395 476 * ATS Callback Implementations * 396 477 *********************************************************************************************************************************/ 397 478 398 /** 399 * Note: Called within server (client serving) thread. 400 */ 401 static DECLCALLBACK(int) audioTestSvcTonePlayCallback(void const *pvUser, PPDMAUDIOSTREAMCFG pStreamCfg, PAUDIOTESTTONEPARMS pToneParms) 479 /** @copydoc ATSCALLBACKS::pfnTestSetBegin */ 480 static DECLCALLBACK(int) audioTestSvcTestSetBeginCallback(void const *pvUser, const char *pszTag) 402 481 { 403 482 PATSCALLBACKCTX pCtx = (PATSCALLBACKCTX)pvUser; 404 483 PAUDIOTESTENV pTstEnv = pCtx->pTstEnv; 405 484 485 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Beginning test set '%s'\n", pszTag); 486 487 return AudioTestSetCreate(&pTstEnv->Set, pTstEnv->szPathTemp, pszTag); 488 } 489 490 /** @copydoc ATSCALLBACKS::pfnTestSetEnd */ 491 static DECLCALLBACK(int) audioTestSvcTestSetEndCallback(void const *pvUser, const char *pszTag) 492 { 493 RT_NOREF(pszTag); 494 495 PATSCALLBACKCTX pCtx = (PATSCALLBACKCTX)pvUser; 496 PAUDIOTESTENV pTstEnv = pCtx->pTstEnv; 497 498 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Ending test set '%s'\n", pszTag); 499 500 return audioTestEnvPrologue(pTstEnv); 501 } 502 503 /** @copydoc ATSCALLBACKS::pfnTonePlay */ 504 static DECLCALLBACK(int) audioTestSvcTonePlayCallback(void const *pvUser, PPDMAUDIOSTREAMCFG pStreamCfg, PAUDIOTESTTONEPARMS pToneParms) 505 { 506 PATSCALLBACKCTX pCtx = (PATSCALLBACKCTX)pvUser; 507 PAUDIOTESTENV pTstEnv = pCtx->pTstEnv; 508 406 509 AUDIOTESTTONE TstTone; 407 510 AudioTestToneInitRandom(&TstTone, &pStreamCfg->Props); 408 511 409 int rc;410 411 const PPDMAUDIOSTREAM pStream = pTstEnv->aStreams[0].pStream; /** @todo Make this dynamic. */412 413 if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream))414 {415 uint32_t cbBuf;416 uint8_t abBuf[_4K];417 418 const uint64_t tsStartMs = RTTimeMilliTS();419 const uint16_t cSchedulingMs = RTRandU32Ex(10, 80); /* Chose a random scheduling (in ms). */ 420 const uint32_t cbPerMs = PDMAudioPropsMilliToBytes(&pStream->Props, cSchedulingMs);421 422 do423 { 424 rc = AudioTestToneGenerate(&TstTone, abBuf, RT_MIN(cbPerMs, sizeof(abBuf)), &cbBuf);512 const PAUDIOTESTSTREAM pTstStream = &pTstEnv->aStreams[0]; /** @todo Make this dynamic. */ 513 514 int rc = audioTestCreateStreamDefaultOut(pTstEnv, pTstStream, &pStreamCfg->Props); 515 if (RT_SUCCESS(rc)) 516 { 517 AUDIOTESTPARMS TstParms; 518 RT_ZERO(TstParms); 519 TstParms.enmType = AUDIOTESTTYPE_TESTTONE_PLAY; 520 TstParms.enmDir = PDMAUDIODIR_OUT; 521 TstParms.TestTone = *pToneParms; 522 523 PAUDIOTESTENTRY pTst; 524 rc = AudioTestSetTestBegin(&pTstEnv->Set, "Playing test tone", &TstParms, &pTst); 525 if (RT_SUCCESS(rc)) 526 { 527 rc = audioTestPlayTone(pTstEnv, pTstStream, pToneParms); 425 528 if (RT_SUCCESS(rc)) 426 529 { 427 uint32_t cbWritten; 428 rc = audioTestDriverStackStreamPlay(&pTstEnv->DrvStack, pStream, abBuf, cbBuf, &cbWritten); 530 AudioTestSetTestDone(pTst); 429 531 } 430 431 if (RTTimeMilliTS() - tsStartMs >= pToneParms->msDuration) 432 break; 433 434 if (RT_FAILURE(rc)) 435 break; 436 437 RTThreadSleep(cSchedulingMs); 438 439 } while (RT_SUCCESS(rc)); 532 else 533 AudioTestSetTestFailed(pTst, rc, "Playing tone failed"); 534 } 535 536 int rc2 = audioTestStreamDestroy(pTstEnv, pTstStream); 537 if (RT_SUCCESS(rc)) 538 rc = rc2; 440 539 } 441 540 else 442 rc = VERR_AUDIO_STREAM_NOT_READY;541 RTTestFailed(g_hTest, "Error creating output stream, rc=%Rrc\n", rc); 443 542 444 543 return rc; … … 464 563 const char *pszTcpAddr, uint32_t uTcpPort) 465 564 { 466 PDMAudioHostEnumInit(&pTstEnv->DevEnum);467 468 int rc = audioTestDriverStackInit(&pTstEnv->DrvStack, pDrvReg, fWithDrvAudio);469 if (RT_FAILURE(rc))470 return rc;471 472 565 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test mode is '%s'\n", pTstEnv->enmMode == AUDIOTESTMODE_HOST ? "host" : "guest"); 473 566 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Using tag '%s'\n", pszTag); … … 475 568 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Temp directory is '%s'\n", pTstEnv->szPathTemp); 476 569 570 int rc = VINF_SUCCESS; 571 572 PDMAudioHostEnumInit(&pTstEnv->DevEnum); 573 574 /* Only the guest mode needs initializing the driver stack. */ 575 const bool fUseDriverStack = pTstEnv->enmMode == AUDIOTESTMODE_GUEST; 576 if (fUseDriverStack) 577 { 578 rc = audioTestDriverStackInit(&pTstEnv->DrvStack, pDrvReg, fWithDrvAudio); 579 if (RT_FAILURE(rc)) 580 return rc; 581 582 PPDMAUDIOHOSTDEV pDev; 583 rc = audioTestDevicesEnumerateAndCheck(pTstEnv, NULL /* pszDevice */, &pDev); /** @todo Implement device checking. */ 584 if (RT_FAILURE(rc)) 585 return rc; 586 } 587 477 588 char szPathTemp[RTPATH_MAX]; 478 589 if ( !strlen(pTstEnv->szPathTemp) … … 488 599 rc = RTPathJoin(pTstEnv->szPathOut, sizeof(pTstEnv->szPathOut), szPathTemp, "vkat"); 489 600 490 if (RT_SUCCESS(rc))491 rc = AudioTestSetCreate(&pTstEnv->Set, pTstEnv->szPathTemp, pszTag);492 493 601 if (RT_FAILURE(rc)) 494 602 return rc; … … 501 609 502 610 ATSCALLBACKS Callbacks; 503 Callbacks.pfnTonePlay = audioTestSvcTonePlayCallback; 504 Callbacks.pvUser = &Ctx; 611 Callbacks.pfnTestSetBegin = audioTestSvcTestSetBeginCallback; 612 Callbacks.pfnTestSetEnd = audioTestSvcTestSetEndCallback; 613 Callbacks.pfnTonePlay = audioTestSvcTonePlayCallback; 614 Callbacks.pvUser = &Ctx; 505 615 506 616 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Starting ATS ...\n"); … … 511 621 if (RT_FAILURE(rc)) 512 622 { 513 RTTestFailed(g_hTest, " Initializing ATS failed with %Rrc\n", rc);623 RTTestFailed(g_hTest, "Starting ATS failed with %Rrc\n", rc); 514 624 return rc; 515 625 } 516 517 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "ATS running\n"); 518 519 while (!g_fTerminated) /** @todo Implement signal handling. */ 520 { 521 RTThreadSleep(100); 522 } 523 524 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Shutting down ATS ...\n"); 525 526 int rc2 = AudioTestSvcShutdown(&pTstEnv->u.Guest.Srv); 527 if (RT_SUCCESS(rc)) 528 rc = rc2; 529 } 530 else 626 } 627 else /* Host mode */ 531 628 { 532 629 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Connecting to ATS at %s:%RU32 ...\n", pszTcpAddr, uTcpPort); 630 533 631 rc = AudioTestSvcClientConnect(&pTstEnv->u.Host.Client, pszTcpAddr, uTcpPort); 534 632 if (RT_FAILURE(rc)) … … 537 635 return rc; 538 636 } 539 } 540 541 audioTestDriverStackDelete(&pTstEnv->DrvStack); 637 638 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Connected to ATS\n"); 639 } 640 641 if ( RT_FAILURE(rc) 642 && fUseDriverStack) 643 audioTestDriverStackDelete(&pTstEnv->DrvStack); 542 644 543 645 return rc; … … 563 665 } 564 666 667 audioTestDriverStackDelete(&pTstEnv->DrvStack); 668 } 669 670 /** 671 * Closes, packs up and destroys a test environment. 672 * 673 * @returns VBox status code. 674 * @param pTstEnv Test environment to handle. 675 */ 676 static int audioTestEnvPrologue(PAUDIOTESTENV pTstEnv) 677 { 678 /* Before destroying the test environment, pack up the test set so 679 * that it's ready for transmission. */ 680 char szFileOut[RTPATH_MAX]; 681 int rc = AudioTestSetPack(&pTstEnv->Set, pTstEnv->szPathOut, szFileOut, sizeof(szFileOut)); 682 if (RT_SUCCESS(rc)) 683 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test set packed up to '%s'\n", szFileOut); 684 685 /* Clean up. */ 686 AudioTestSetClose(&pTstEnv->Set); 687 688 int rc2 = AudioTestSetWipe(&pTstEnv->Set); 689 if (RT_SUCCESS(rc)) 690 rc = rc2; 691 565 692 AudioTestSetDestroy(&pTstEnv->Set); 566 audioTestDriverStackDelete(&pTstEnv->DrvStack); 693 694 return rc; 567 695 } 568 696 … … 812 940 813 941 /** 814 * Plays a test tone on a specific audio test stream.815 *816 * @returns VBox status code.817 * @param pTstEnv Test environment to use for running the test.818 * @param pStream Stream to use for playing the tone.819 * @param pParms Tone parameters to use.820 *821 * @note Blocking function.822 */823 static int audioTestPlayTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms)824 {825 AUDIOTESTTONE TstTone;826 AudioTestToneInit(&TstTone, &pParms->Props, pParms->dbFreqHz);827 828 const char *pcszPathOut = pTstEnv->Set.szPathAbs;829 830 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Playing test tone (tone frequency is %RU16Hz, %RU32ms)\n", (uint16_t)pParms->dbFreqHz, pParms->msDuration);831 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Writing to '%s'\n", pcszPathOut);832 833 /** @todo Use .WAV here? */834 PAUDIOTESTOBJ pObj;835 int rc = AudioTestSetObjCreateAndRegister(&pTstEnv->Set, "tone-play.pcm", &pObj);836 AssertRCReturn(rc, rc);837 838 if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream))839 {840 uint32_t cbBuf;841 uint8_t abBuf[_4K];842 843 const uint64_t tsStartMs = RTTimeMilliTS();844 const uint16_t cSchedulingMs = RTRandU32Ex(10, 80); /* Choose a random scheduling (in ms). */845 const uint32_t cbPerMs = PDMAudioPropsMilliToBytes(&pParms->Props, cSchedulingMs);846 847 do848 {849 rc = AudioTestToneGenerate(&TstTone, abBuf, RT_MIN(cbPerMs, sizeof(abBuf)), &cbBuf);850 if (RT_SUCCESS(rc))851 {852 /* Write stuff to disk before trying to play it. Help analysis later. */853 rc = AudioTestSetObjWrite(pObj, abBuf, cbBuf);854 if (RT_SUCCESS(rc))855 {856 uint32_t cbWritten;857 rc = audioTestDriverStackStreamPlay(&pTstEnv->DrvStack, pStream->pStream,858 abBuf, cbBuf, &cbWritten);859 }860 }861 862 if (RTTimeMilliTS() - tsStartMs >= pParms->msDuration)863 break;864 865 if (RT_FAILURE(rc))866 break;867 868 RTThreadSleep(cSchedulingMs);869 870 } while (RT_SUCCESS(rc));871 }872 else873 rc = VERR_AUDIO_STREAM_NOT_READY;874 875 int rc2 = AudioTestSetObjClose(pObj);876 if (RT_SUCCESS(rc))877 rc = rc2;878 879 return rc;880 }881 882 /**883 942 * Overrides audio test base parameters with another set. 884 943 * … … 933 992 int rc = VINF_SUCCESS; 934 993 935 PAUDIOTESTSTREAM pStream = &pTstEnv->aStreams[0];936 937 994 for (uint32_t i = 0; i < pTstParms->cIterations; i++) 938 995 { … … 943 1000 if (RT_SUCCESS(rc)) 944 1001 { 945 rc = audioTestCreateStreamDefaultOut(pTstEnv, pStream, &pTstParms->TestTone.Props); 946 if (RT_SUCCESS(rc)) 947 { 948 rc = audioTestPlayTone(pTstEnv, pStream, &pTstParms->TestTone); 949 } 950 951 int rc2 = audioTestStreamDestroy(pTstEnv, pStream); 952 if (RT_SUCCESS(rc)) 953 rc = rc2; 954 1002 PDMAUDIOSTREAMCFG Cfg; 1003 RT_ZERO(Cfg); 1004 /** @todo Add more parameters here? */ 1005 Cfg.Props = pTstParms->Props; 1006 1007 rc = AudioTestSvcClientTonePlay(&pTstEnv->u.Host.Client, &Cfg, &pTstParms->TestTone); 955 1008 if (RT_SUCCESS(rc)) 956 1009 { … … 1145 1198 int rc = VINF_SUCCESS; 1146 1199 1147 unsigned uSeq = 0; 1148 for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++) 1149 { 1150 int rc2 = audioTestOne(pTstEnv, &g_aTests[i], uSeq, pOverrideParms); 1200 if (pTstEnv->enmMode == AUDIOTESTMODE_GUEST) 1201 { 1202 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "ATS running\n"); 1203 1204 while (!g_fTerminated) /** @todo Implement signal handling. */ 1205 { 1206 RTThreadSleep(100); 1207 } 1208 1209 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Shutting down ATS ...\n"); 1210 1211 int rc2 = AudioTestSvcShutdown(&pTstEnv->u.Guest.Srv); 1151 1212 if (RT_SUCCESS(rc)) 1152 1213 rc = rc2; 1153 1154 if (!g_aTests[i].fExcluded) 1155 uSeq++; 1156 } 1214 } 1215 else if (pTstEnv->enmMode == AUDIOTESTMODE_HOST) 1216 { 1217 /* We have one single test set for all executed tests for now. */ 1218 rc = AudioTestSetCreate(&pTstEnv->Set, pTstEnv->szPathTemp, pTstEnv->szTag); 1219 if (RT_SUCCESS(rc)) 1220 { 1221 /* Copy back the (eventually generated) tag to the test environment. */ 1222 rc = RTStrCopy(pTstEnv->szTag, sizeof(pTstEnv->szTag), AudioTestSetGetTag(&pTstEnv->Set)); 1223 AssertRC(rc); 1224 1225 rc = AudioTestSvcClientTestSetBegin(&pTstEnv->u.Host.Client, pTstEnv->szTag); 1226 if (RT_SUCCESS(rc)) 1227 { 1228 unsigned uSeq = 0; 1229 for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++) 1230 { 1231 int rc2 = audioTestOne(pTstEnv, &g_aTests[i], uSeq, pOverrideParms); 1232 if (RT_SUCCESS(rc)) 1233 rc = rc2; 1234 1235 if (!g_aTests[i].fExcluded) 1236 uSeq++; 1237 } 1238 1239 int rc2 = AudioTestSvcClientTestSetEnd(&pTstEnv->u.Host.Client, pTstEnv->szTag); 1240 if (RT_SUCCESS(rc)) 1241 rc = rc2; 1242 } 1243 1244 audioTestEnvPrologue(pTstEnv); 1245 } 1246 } 1247 else 1248 AssertFailed(); 1249 1250 if (RT_FAILURE(rc)) 1251 RTTestFailed(g_hTest, "Test worker failed with %Rrc", rc); 1157 1252 1158 1253 return rc; … … 1164 1259 switch (pOpt->iShort) 1165 1260 { 1166 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend."; 1167 case VKAT_TEST_OPT_DEV: return "Use the specified audio device"; 1168 case 'e': return "Exclude the given test id from the list"; 1169 case 'a': return "Exclude all tests from the list (useful to enable single tests later with --include)"; 1170 case 'i': return "Include the given test id in the list"; 1261 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend"; 1262 case VKAT_TEST_OPT_DEV: return "Use the specified audio device"; 1263 case VKAT_TEST_OPT_ATS_ADDR: return "ATS address (hostname or IP) to connect to"; 1264 case VKAT_TEST_OPT_ATS_PORT: return "ATS port to connect to. Defaults to 6052 if not set"; 1265 case VKAT_TEST_OPT_MODE: return "Specifies the mode this program runs at"; 1266 case 'e': return "Exclude the given test id from the list"; 1267 case 'a': return "Exclude all tests from the list (useful to enable single tests later with --include)"; 1268 case 'i': return "Include the given test id in the list"; 1171 1269 } 1172 1270 return NULL; … … 1336 1434 if (RT_SUCCESS(rc)) 1337 1435 { 1338 PPDMAUDIOHOSTDEV pDev; 1339 rc = audioTestDevicesEnumerateAndCheck(&TstEnv, pszDevice, &pDev); 1340 if (RT_SUCCESS(rc)) 1341 audioTestWorker(&TstEnv, &TstCust); 1342 1343 /* Before destroying the test environment, pack up the test set so 1344 * that it's ready for transmission. */ 1345 char szFileOut[RTPATH_MAX]; 1346 rc = AudioTestSetPack(&TstEnv.Set, TstEnv.szPathOut, szFileOut, sizeof(szFileOut)); 1347 if (RT_SUCCESS(rc)) 1348 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test set packed up to '%s'\n", szFileOut); 1349 1350 #ifndef DEBUG_andy 1351 /* Clean up. */ 1352 AudioTestSetClose(&TstEnv.Set); /* wipe fails on windows if the manifest file is open*/ 1353 1354 int rc2 = AudioTestSetWipe(&TstEnv.Set); 1355 AssertRC(rc2); /* Annoying, but not test-critical. */ 1356 #endif 1436 audioTestWorker(&TstEnv, &TstCust); 1357 1437 audioTestEnvDestroy(&TstEnv); 1358 1438 } … … 1863 1943 rc = AudioTestSvcInit(&Srv, &Callbacks); 1864 1944 if (RT_SUCCESS(rc)) 1865 {1866 1945 rc = AudioTestSvcStart(&Srv); 1867 if (RT_SUCCESS(rc))1868 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "ATS running\n");1869 }1870 1946 } 1871 1947 else
Note:
See TracChangeset
for help on using the changeset viewer.