Changeset 89399 in vbox for trunk/src/VBox/ValidationKit/utils/audio
- Timestamp:
- May 31, 2021 12:43:16 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp
r89387 r89399 110 110 * Structures and Typedefs * 111 111 *********************************************************************************************************************************/ 112 /** 113 * Enumeration specifying the current audio test mode. 114 */ 115 typedef enum AUDIOTESTMODE 116 { 117 /** Unknown mode. */ 118 AUDIOTESTMODE_UNKNOWN = 0, 119 /** VKAT is running on the guest side. */ 120 AUDIOTESTMODE_GUEST, 121 /** VKAT is running on the host side. */ 122 AUDIOTESTMODE_HOST 123 } AUDIOTESTMODE; 124 112 125 struct AUDIOTESTENV; 113 126 /** Pointer a audio test environment. */ … … 202 215 typedef struct AUDIOTESTENV 203 216 { 217 /** Audio testing mode. */ 218 AUDIOTESTMODE enmMode; 204 219 /** Output path for storing the test environment's final test files. */ 205 220 char szPathOut[RTPATH_MAX]; … … 214 229 /** The audio test set to use. */ 215 230 AUDIOTESTSET Set; 231 union 232 { 233 struct 234 { 235 /** ATS instance to use. */ 236 ATSSERVER Srv; 237 } Guest; 238 struct 239 { 240 ATSCLIENT Client; 241 } Host; 242 } u; 216 243 } AUDIOTESTENV; 217 244 … … 233 260 } AUDIOTESTDESC; 234 261 262 /** 263 * Structure for keeping a user context for the test service callbacks. 264 */ 265 typedef struct ATSCALLBACKCTX 266 { 267 PAUDIOTESTENV pTstEnv; 268 } ATSCALLBACKCTX; 269 typedef ATSCALLBACKCTX *PATSCALLBACKCTX; 270 235 271 236 272 /********************************************************************************************************************************* … … 267 303 VKAT_TEST_OPT_COUNT = 900, 268 304 VKAT_TEST_OPT_DEV, 305 VKAT_TEST_OPT_ATS_ADDR, 306 VKAT_TEST_OPT_ATS_PORT, 307 VKAT_TEST_OPT_MODE, 269 308 VKAT_TEST_OPT_OUTDIR, 270 309 VKAT_TEST_OPT_PAUSE, … … 314 353 { "--exclude", 'e', RTGETOPT_REQ_UINT32 }, 315 354 { "--exclude-all", 'a', RTGETOPT_REQ_NOTHING }, 355 { "--mode", VKAT_TEST_OPT_MODE, RTGETOPT_REQ_STRING }, 356 { "--ats-address", VKAT_TEST_OPT_ATS_ADDR, RTGETOPT_REQ_STRING }, 357 { "--ats-port", VKAT_TEST_OPT_ATS_PORT, RTGETOPT_REQ_UINT32 }, 316 358 { "--include", 'i', RTGETOPT_REQ_UINT32 }, 317 359 { "--outdir", VKAT_TEST_OPT_OUTDIR, RTGETOPT_REQ_STRING }, … … 377 419 AssertCompile(sizeof(g_aBackends) > 0 /* port me */); 378 420 421 static volatile bool g_fTerminated = false; 379 422 /** The test handle. */ 380 static RTTEST g_hTest;423 static RTTEST g_hTest; 381 424 /** The release logger. */ 382 425 static PRTLOGGER g_pRelLogger = NULL; 383 426 /** The current verbosity level. */ 384 static unsigned g_uVerbosity = 0;427 static unsigned g_uVerbosity = 0; 385 428 /** DrvAudio: Enable debug (or not). */ 386 static bool g_fDrvAudioDebug = 0;429 static bool g_fDrvAudioDebug = 0; 387 430 /** DrvAudio: The debug output path. */ 388 static const char *g_pszDrvAudioDebug = NULL;431 static const char *g_pszDrvAudioDebug = NULL; 389 432 390 433 … … 1378 1421 1379 1422 /********************************************************************************************************************************* 1423 * ATS Callback Implementations * 1424 *********************************************************************************************************************************/ 1425 1426 /** 1427 * Note: Called within server (client serving) thread. 1428 */ 1429 static DECLCALLBACK(int) audioTestSvcTonePlayCallback(void const *pvUser, PPDMAUDIOSTREAMCFG pStreamCfg, PAUDIOTESTTONEPARMS pToneParms) 1430 { 1431 PATSCALLBACKCTX pCtx = (PATSCALLBACKCTX)pvUser; 1432 PAUDIOTESTENV pTstEnv = pCtx->pTstEnv; 1433 1434 AUDIOTESTTONE TstTone; 1435 AudioTestToneInitRandom(&TstTone, &pStreamCfg->Props); 1436 1437 int rc; 1438 1439 const PPDMAUDIOSTREAM pStream = pTstEnv->aStreams[0].pStream; /** @todo Make this dynamic. */ 1440 1441 if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream)) 1442 { 1443 uint32_t cbBuf; 1444 uint8_t abBuf[_4K]; 1445 1446 const uint64_t tsStartMs = RTTimeMilliTS(); 1447 const uint16_t cSchedulingMs = RTRandU32Ex(10, 80); /* Chose a random scheduling (in ms). */ 1448 const uint32_t cbPerMs = PDMAudioPropsMilliToBytes(&pStream->Props, cSchedulingMs); 1449 1450 do 1451 { 1452 rc = AudioTestToneGenerate(&TstTone, abBuf, RT_MIN(cbPerMs, sizeof(abBuf)), &cbBuf); 1453 if (RT_SUCCESS(rc)) 1454 { 1455 uint32_t cbWritten; 1456 rc = audioTestDriverStackStreamPlay(&pTstEnv->DrvStack, pStream, abBuf, cbBuf, &cbWritten); 1457 } 1458 1459 if (RTTimeMilliTS() - tsStartMs >= pToneParms->msDuration) 1460 break; 1461 1462 if (RT_FAILURE(rc)) 1463 break; 1464 1465 RTThreadSleep(cSchedulingMs); 1466 1467 } while (RT_SUCCESS(rc)); 1468 } 1469 else 1470 rc = VERR_AUDIO_STREAM_NOT_READY; 1471 1472 return rc; 1473 } 1474 1475 1476 /********************************************************************************************************************************* 1380 1477 * Implementation of audio test environment handling * 1381 1478 *********************************************************************************************************************************/ … … 1388 1485 * @param fWithDrvAudio Whether to include DrvAudio in the stack or not. 1389 1486 * @param pszTag Tag name to use. If NULL, a generated UUID will be used. 1390 */ 1391 static int audioTestEnvInit(PAUDIOTESTENV pTstEnv, PCPDMDRVREG pDrvReg, bool fWithDrvAudio, const char *pszTag) 1487 * @param pszTcpAddr TCP/IP address to connect to. 1488 * @param uTcpPort TCP/IP port to connect to. 1489 */ 1490 static int audioTestEnvInit(PAUDIOTESTENV pTstEnv, 1491 PCPDMDRVREG pDrvReg, bool fWithDrvAudio, const char *pszTag, 1492 const char *pszTcpAddr, uint32_t uTcpPort) 1392 1493 { 1393 1494 PDMAudioHostEnumInit(&pTstEnv->DevEnum); … … 1396 1497 if (RT_FAILURE(rc)) 1397 1498 return rc; 1499 1500 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test mode is '%s'\n", pTstEnv->enmMode == AUDIOTESTMODE_HOST ? "host" : "guest"); 1501 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Using tag '%s'\n", pszTag); 1502 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Output directory is '%s'\n", pTstEnv->szPathOut); 1503 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Temp directory is '%s'\n", pTstEnv->szPathTemp); 1398 1504 1399 1505 char szPathTemp[RTPATH_MAX]; … … 1413 1519 rc = AudioTestSetCreate(&pTstEnv->Set, pTstEnv->szPathTemp, pszTag); 1414 1520 1415 if (RT_SUCCESS(rc))1416 {1417 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Using tag '%s'\n", pszTag);1418 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Output directory is '%s'\n", pTstEnv->szPathOut);1419 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Temp directory is '%s'\n", pTstEnv->szPathTemp);1420 }1421 1422 1521 if (RT_FAILURE(rc)) 1423 audioTestDriverStackDelete(&pTstEnv->DrvStack); 1522 return rc; 1523 1524 /** @todo Implement NAT mode like we do for TxS later? */ 1525 if (pTstEnv->enmMode == AUDIOTESTMODE_GUEST) 1526 { 1527 ATSCALLBACKCTX Ctx; 1528 Ctx.pTstEnv = pTstEnv; 1529 1530 ATSCALLBACKS Callbacks; 1531 Callbacks.pfnTonePlay = audioTestSvcTonePlayCallback; 1532 Callbacks.pvUser = &Ctx; 1533 1534 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Starting ATS ...\n"); 1535 rc = AudioTestSvcInit(&pTstEnv->u.Guest.Srv, &Callbacks); 1536 if (RT_SUCCESS(rc)) 1537 rc = AudioTestSvcStart(&pTstEnv->u.Guest.Srv); 1538 1539 if (RT_FAILURE(rc)) 1540 { 1541 RTTestFailed(g_hTest, "Initializing ATS failed with %Rrc\n", rc); 1542 return rc; 1543 } 1544 1545 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "ATS running\n"); 1546 1547 while (!g_fTerminated) /** @todo Implement signal handling. */ 1548 { 1549 RTThreadSleep(100); 1550 } 1551 1552 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Shutting down ATS ...\n"); 1553 1554 int rc2 = AudioTestSvcShutdown(&pTstEnv->u.Guest.Srv); 1555 if (RT_SUCCESS(rc)) 1556 rc = rc2; 1557 } 1558 else 1559 { 1560 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Connecting to ATS at %s:%RU32 ...\n", pszTcpAddr, uTcpPort); 1561 rc = AudioTestSvcClientConnect(&pTstEnv->u.Host.Client, pszTcpAddr, uTcpPort); 1562 if (RT_FAILURE(rc)) 1563 { 1564 RTTestFailed(g_hTest, "Connecting to ATS failed with %Rrc\n", rc); 1565 return rc; 1566 } 1567 } 1568 1569 audioTestDriverStackDelete(&pTstEnv->DrvStack); 1424 1570 1425 1571 return rc; … … 2077 2223 uint32_t uPcmHz = 0; 2078 2224 bool fPcmSigned = true; 2225 const char *pszTcpAddr = NULL; 2226 uint16_t uTcpPort = 0; 2079 2227 2080 2228 int rc; … … 2112 2260 break; 2113 2261 2262 case VKAT_TEST_OPT_ATS_ADDR: 2263 if (TstEnv.enmMode == AUDIOTESTMODE_UNKNOWN) 2264 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Must specify a test mode first!"); 2265 pszTcpAddr = ValueUnion.psz; 2266 break; 2267 2268 case VKAT_TEST_OPT_ATS_PORT: 2269 if (TstEnv.enmMode == AUDIOTESTMODE_UNKNOWN) 2270 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Must specify a test mode first!"); 2271 uTcpPort = ValueUnion.u32; 2272 break; 2273 2274 case VKAT_TEST_OPT_MODE: 2275 if (TstEnv.enmMode != AUDIOTESTMODE_UNKNOWN) 2276 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Test mode (guest / host) already specified"); 2277 TstEnv.enmMode = RTStrICmp(ValueUnion.psz, "guest") == 0 ? AUDIOTESTMODE_GUEST : AUDIOTESTMODE_HOST; 2278 break; 2279 2114 2280 case 'i': 2115 2281 if (ValueUnion.u32 >= RT_ELEMENTS(g_aTests)) … … 2181 2347 uPcmHz ? uPcmHz : 44100); 2182 2348 2349 if (TstEnv.enmMode == AUDIOTESTMODE_UNKNOWN) 2350 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No test mode specified!\n"); 2351 2352 if (TstEnv.enmMode == AUDIOTESTMODE_HOST) 2353 { 2354 /* Use the default port is none is specified. */ 2355 if (!uTcpPort) 2356 uTcpPort = ATS_DEFAULT_PORT; 2357 2358 if (!pszTcpAddr) 2359 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--ats-address missing\n"); 2360 } 2361 2183 2362 /* For now all tests have the same test environment. */ 2184 rc = audioTestEnvInit(&TstEnv, pDrvReg, fWithDrvAudio, pszTag );2363 rc = audioTestEnvInit(&TstEnv, pDrvReg, fWithDrvAudio, pszTag, pszTcpAddr, uTcpPort); 2185 2364 if (RT_SUCCESS(rc)) 2186 2365 { … … 2654 2833 2655 2834 /** 2656 * Structure for keeping a user context for the test service callbacks.2657 */2658 typedef struct ATSCALLBACKCTX2659 {2660 /** Driver stack to use. */2661 PAUDIOTESTDRVSTACK pDrvStack;2662 /** Audio stream to use. */2663 PPDMAUDIOSTREAM pStream;2664 } ATSCALLBACKCTX;2665 typedef ATSCALLBACKCTX *PATSCALLBACKCTX;2666 2667 /**2668 * Note: Called within server (client serving) thread.2669 */2670 static DECLCALLBACK(int) audioTestSvcTonePlayCallback(void const *pvUser, PPDMAUDIOSTREAMCFG pStreamCfg, PAUDIOTESTTONEPARMS pToneParms)2671 {2672 PATSCALLBACKCTX pCtx = (PATSCALLBACKCTX)pvUser;2673 2674 AUDIOTESTTONE TstTone;2675 AudioTestToneInitRandom(&TstTone, &pStreamCfg->Props);2676 2677 int rc;2678 2679 if (audioTestDriverStackStreamIsOkay(pCtx->pDrvStack, pCtx->pStream))2680 {2681 uint32_t cbBuf;2682 uint8_t abBuf[_4K];2683 2684 const uint64_t tsStartMs = RTTimeMilliTS();2685 const uint16_t cSchedulingMs = RTRandU32Ex(10, 80); /* Chose a random scheduling (in ms). */2686 const uint32_t cbPerMs = PDMAudioPropsMilliToBytes(&pCtx->pStream->Props, cSchedulingMs);2687 2688 do2689 {2690 rc = AudioTestToneGenerate(&TstTone, abBuf, RT_MIN(cbPerMs, sizeof(abBuf)), &cbBuf);2691 if (RT_SUCCESS(rc))2692 {2693 uint32_t cbWritten;2694 rc = audioTestDriverStackStreamPlay(pCtx->pDrvStack, pCtx->pStream, abBuf, cbBuf, &cbWritten);2695 }2696 2697 if (RTTimeMilliTS() - tsStartMs >= pToneParms->msDuration)2698 break;2699 2700 if (RT_FAILURE(rc))2701 break;2702 2703 RTThreadSleep(cSchedulingMs);2704 2705 } while (RT_SUCCESS(rc));2706 }2707 else2708 rc = VERR_AUDIO_STREAM_NOT_READY;2709 2710 return rc;2711 }2712 2713 /**2714 2835 * Tests the Audio Test Service (ATS). 2715 2836 * … … 2721 2842 static int audioTestDoSelftestAts(PCPDMDRVREG pDrvReg, const char *pszAdr) 2722 2843 { 2723 AUDIOTEST DRVSTACK DrvStack;2724 int rc = audioTestDriverStackInit(& DrvStack, pDrvReg, true /* fWithDrvAudio */);2844 AUDIOTESTENV TstEnv; 2845 int rc = audioTestDriverStackInit(&TstEnv.DrvStack, pDrvReg, true /* fWithDrvAudio */); 2725 2846 if (RT_SUCCESS(rc)) 2726 2847 { … … 2731 2852 PDMAUDIOSTREAMCFG CfgAcq; 2732 2853 PPDMAUDIOSTREAM pStream = NULL; 2733 rc = audioTestDriverStackStreamCreateOutput(& DrvStack, &Props,2854 rc = audioTestDriverStackStreamCreateOutput(&TstEnv.DrvStack, &Props, 2734 2855 UINT32_MAX /* cMsBufferSize */, 2735 2856 UINT32_MAX /* cMsPreBuffer */, … … 2737 2858 if (RT_SUCCESS(rc)) 2738 2859 { 2739 rc = audioTestDriverStackStreamEnable(& DrvStack, pStream);2860 rc = audioTestDriverStackStreamEnable(&TstEnv.DrvStack, pStream); 2740 2861 if (RT_SUCCESS(rc)) 2741 2862 { 2742 2863 ATSCALLBACKCTX Ctx; 2743 Ctx.pDrvStack = &DrvStack; 2744 Ctx.pStream = pStream; 2864 Ctx.pTstEnv = &TstEnv; 2745 2865 2746 2866 ATSCALLBACKS Callbacks; … … 2768 2888 { 2769 2889 ATSCLIENT Conn; 2770 rc = AudioTestSvcClientConnect(&Conn, NULL );2890 rc = AudioTestSvcClientConnect(&Conn, NULL, 0); 2771 2891 if (RT_SUCCESS(rc)) 2772 2892 {
Note:
See TracChangeset
for help on using the changeset viewer.