Changeset 89617 in vbox
- Timestamp:
- Jun 11, 2021 7:14:34 AM (3 years ago)
- Location:
- trunk/src/VBox/ValidationKit/utils/audio
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp
r89614 r89617 82 82 * Defined Constants And Macros * 83 83 *********************************************************************************************************************************/ 84 /** For use in the option switch to handle common options. */85 #define AUDIO_TEST_COMMON_OPTION_CASES(a_ValueUnion) \86 case 'q': \87 g_uVerbosity = 0; \88 if (g_pRelLogger) \89 RTLogGroupSettings(g_pRelLogger, "all=0 all.e"); \90 break; \91 \92 case 'v': \93 g_uVerbosity++; \94 if (g_pRelLogger) \95 RTLogGroupSettings(g_pRelLogger, g_uVerbosity == 1 ? "all.e.l" : g_uVerbosity == 2 ? "all.e.l.f" : "all=~0"); \96 break; \97 \98 case 'V': \99 return audioTestVersion(); \100 \101 case 'h': \102 return audioTestUsage(g_pStdOut); \103 \104 case AUDIO_TEST_OPT_CMN_DEBUG_AUDIO_ENABLE: \105 g_fDrvAudioDebug = true; \106 break; \107 \108 case AUDIO_TEST_OPT_CMN_DEBUG_AUDIO_PATH: \109 g_pszDrvAudioDebug = (a_ValueUnion).psz; \110 break111 84 112 85 … … 116 89 *********************************************************************************************************************************/ 117 90 static int audioTestCombineParms(PAUDIOTESTPARMS pBaseParms, PAUDIOTESTPARMS pOverrideParms); 118 static RTEXITCODE audioTestUsage(PRTSTREAM pStrm);119 static RTEXITCODE audioTestVersion(void);120 91 121 92 … … 123 94 * Global Variables * 124 95 *********************************************************************************************************************************/ 125 /**126 * Common long options values.127 */128 enum129 {130 AUDIO_TEST_OPT_CMN_DEBUG_AUDIO_ENABLE = 256,131 AUDIO_TEST_OPT_CMN_DEBUG_AUDIO_PATH132 };133 96 134 97 /** … … 161 124 { 162 125 VKAT_VERIFY_OPT_TAG = 900 163 };164 165 /**166 * Long option values for the 'selftest' command.167 */168 enum169 {170 VKAT_SELFTEST_OPT_ATS_GUEST_ADDR = 900,171 VKAT_SELFTEST_OPT_ATS_GUEST_PORT,172 VKAT_SELFTEST_OPT_ATS_VALKIT_ADDR,173 VKAT_SELFTEST_OPT_ATS_VALKIT_PORT174 126 }; 175 127 … … 405 357 *********************************************************************************************************************************/ 406 358 407 static AUDIOTESTDESC g_aTests[] = 359 /** Test definition table. */ 360 AUDIOTESTDESC g_aTests[] = 408 361 { 409 362 /* pszTest fExcluded pfnSetup */ … … 411 364 { "RecordTone", false, audioTestRecordToneSetup, audioTestRecordToneExec, audioTestRecordToneDestroy } 412 365 }; 366 /** Number of tests defined. */ 367 unsigned g_cTests = RT_ELEMENTS(g_aTests); 413 368 414 369 /** … … 1048 1003 1049 1004 /** 1050 * Options for 'play'.1051 */1052 static const RTGETOPTDEF g_aCmdPlayOptions[] =1053 {1054 { "--backend", 'b', RTGETOPT_REQ_STRING },1055 { "--channels", 'c', RTGETOPT_REQ_UINT8 },1056 { "--hz", 'f', RTGETOPT_REQ_UINT32 },1057 { "--frequency", 'f', RTGETOPT_REQ_UINT32 },1058 { "--sample-size", 'z', RTGETOPT_REQ_UINT8 },1059 { "--output-device", 'o', RTGETOPT_REQ_STRING },1060 { "--with-drv-audio", 'd', RTGETOPT_REQ_NOTHING },1061 { "--with-mixer", 'm', RTGETOPT_REQ_NOTHING },1062 };1063 1064 /** The 'play' command option help. */1065 static DECLCALLBACK(const char *) audioTestCmdPlayHelp(PCRTGETOPTDEF pOpt)1066 {1067 switch (pOpt->iShort)1068 {1069 case 'b': return "The audio backend to use.";1070 case 'c': return "Number of backend output channels";1071 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend.";1072 case 'f': return "Output frequency (Hz)";1073 case 'z': return "Output sample size (bits)";1074 case 'm': return "Go via the mixer.";1075 case 'o': return "The ID of the output device to use.";1076 default: return NULL;1077 }1078 }1079 1080 /**1081 * The 'play' command handler.1082 *1083 * @returns Program exit code.1084 * @param pGetState RTGetOpt state.1085 */1086 static DECLCALLBACK(RTEXITCODE) audioTestCmdPlayHandler(PRTGETOPTSTATE pGetState)1087 {1088 /* Option values: */1089 PCPDMDRVREG pDrvReg = g_aBackends[0].pDrvReg;1090 uint32_t cMsBufferSize = UINT32_MAX;1091 uint32_t cMsPreBuffer = UINT32_MAX;1092 uint32_t cMsSchedulingHint = UINT32_MAX;1093 const char *pszDevId = NULL;1094 bool fWithDrvAudio = false;1095 bool fWithMixer = false;1096 uint8_t cbSample = 0;1097 uint8_t cChannels = 0;1098 uint32_t uHz = 0;1099 1100 /* Argument processing loop: */1101 int rc;1102 RTGETOPTUNION ValueUnion;1103 while ((rc = RTGetOpt(pGetState, &ValueUnion)) != 0)1104 {1105 switch (rc)1106 {1107 case 'b':1108 pDrvReg = audioTestFindBackendOpt(ValueUnion.psz);1109 if (pDrvReg == NULL)1110 return RTEXITCODE_SYNTAX;1111 break;1112 1113 case 'c':1114 cChannels = ValueUnion.u8;1115 break;1116 1117 case 'd':1118 fWithDrvAudio = true;1119 break;1120 1121 case 'f':1122 uHz = ValueUnion.u32;1123 break;1124 1125 case 'm':1126 fWithMixer = true;1127 break;1128 1129 case 'o':1130 pszDevId = ValueUnion.psz;1131 break;1132 1133 case 'z':1134 cbSample = ValueUnion.u8 / 8;1135 break;1136 1137 case VINF_GETOPT_NOT_OPTION:1138 {1139 RTEXITCODE rcExit = audioTestPlayOne(ValueUnion.psz, pDrvReg, pszDevId, cMsBufferSize, cMsPreBuffer,1140 cMsSchedulingHint, cChannels, cbSample, uHz, fWithDrvAudio, fWithMixer);1141 if (rcExit != RTEXITCODE_SUCCESS)1142 return rcExit;1143 break;1144 }1145 1146 AUDIO_TEST_COMMON_OPTION_CASES(ValueUnion);1147 1148 default:1149 return RTGetOptPrintError(rc, &ValueUnion);1150 }1151 }1152 return RTEXITCODE_SUCCESS;1153 }1154 1155 1156 /*********************************************************************************************************************************1157 * Command: rec *1158 *********************************************************************************************************************************/1159 1160 /**1161 * Options for 'rec'.1162 */1163 static const RTGETOPTDEF g_aCmdRecOptions[] =1164 {1165 { "--backend", 'b', RTGETOPT_REQ_STRING },1166 { "--channels", 'c', RTGETOPT_REQ_UINT8 },1167 { "--hz", 'f', RTGETOPT_REQ_UINT32 },1168 { "--frequency", 'f', RTGETOPT_REQ_UINT32 },1169 { "--sample-size", 'z', RTGETOPT_REQ_UINT8 },1170 { "--input-device", 'i', RTGETOPT_REQ_STRING },1171 { "--wav-channels", 'C', RTGETOPT_REQ_UINT8 },1172 { "--wav-hz", 'F', RTGETOPT_REQ_UINT32 },1173 { "--wav-frequency", 'F', RTGETOPT_REQ_UINT32 },1174 { "--wav-sample-size", 'Z', RTGETOPT_REQ_UINT8 },1175 { "--with-drv-audio", 'd', RTGETOPT_REQ_NOTHING },1176 { "--with-mixer", 'm', RTGETOPT_REQ_NOTHING },1177 { "--max-frames", 'r', RTGETOPT_REQ_UINT64 },1178 { "--max-sec", 's', RTGETOPT_REQ_UINT64 },1179 { "--max-seconds", 's', RTGETOPT_REQ_UINT64 },1180 { "--max-ms", 't', RTGETOPT_REQ_UINT64 },1181 { "--max-milliseconds", 't', RTGETOPT_REQ_UINT64 },1182 { "--max-ns", 'T', RTGETOPT_REQ_UINT64 },1183 { "--max-nanoseconds", 'T', RTGETOPT_REQ_UINT64 },1184 };1185 1186 /** The 'rec' command option help. */1187 static DECLCALLBACK(const char *) audioTestCmdRecHelp(PCRTGETOPTDEF pOpt)1188 {1189 switch (pOpt->iShort)1190 {1191 case 'b': return "The audio backend to use.";1192 case 'c': return "Number of backend input channels";1193 case 'C': return "Number of wave-file channels";1194 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend.";1195 case 'f': return "Input frequency (Hz)";1196 case 'F': return "Wave-file frequency (Hz)";1197 case 'z': return "Input sample size (bits)";1198 case 'Z': return "Wave-file sample size (bits)";1199 case 'm': return "Go via the mixer.";1200 case 'i': return "The ID of the input device to use.";1201 case 'r': return "Max recording duration in frames.";1202 case 's': return "Max recording duration in seconds.";1203 case 't': return "Max recording duration in milliseconds.";1204 case 'T': return "Max recording duration in nanoseconds.";1205 default: return NULL;1206 }1207 }1208 1209 /**1210 * The 'play' command handler.1211 *1212 * @returns Program exit code.1213 * @param pGetState RTGetOpt state.1214 */1215 static DECLCALLBACK(RTEXITCODE) audioTestCmdRecHandler(PRTGETOPTSTATE pGetState)1216 {1217 /* Option values: */1218 PCPDMDRVREG pDrvReg = g_aBackends[0].pDrvReg;1219 uint32_t cMsBufferSize = UINT32_MAX;1220 uint32_t cMsPreBuffer = UINT32_MAX;1221 uint32_t cMsSchedulingHint = UINT32_MAX;1222 const char *pszDevId = NULL;1223 bool fWithDrvAudio = false;1224 bool fWithMixer = false;1225 uint8_t cbSample = 0;1226 uint8_t cChannels = 0;1227 uint32_t uHz = 0;1228 uint8_t cbWaveSample = 0;1229 uint8_t cWaveChannels = 0;1230 uint32_t uWaveHz = 0;1231 uint64_t cMaxFrames = UINT64_MAX;1232 uint64_t cNsMaxDuration = UINT64_MAX;1233 1234 /* Argument processing loop: */1235 int rc;1236 RTGETOPTUNION ValueUnion;1237 while ((rc = RTGetOpt(pGetState, &ValueUnion)) != 0)1238 {1239 switch (rc)1240 {1241 case 'b':1242 pDrvReg = audioTestFindBackendOpt(ValueUnion.psz);1243 if (pDrvReg == NULL)1244 return RTEXITCODE_SYNTAX;1245 break;1246 1247 case 'c':1248 cChannels = ValueUnion.u8;1249 break;1250 1251 case 'C':1252 cWaveChannels = ValueUnion.u8;1253 break;1254 1255 case 'd':1256 fWithDrvAudio = true;1257 break;1258 1259 case 'f':1260 uHz = ValueUnion.u32;1261 break;1262 1263 case 'F':1264 uWaveHz = ValueUnion.u32;1265 break;1266 1267 case 'i':1268 pszDevId = ValueUnion.psz;1269 break;1270 1271 case 'm':1272 fWithMixer = true;1273 break;1274 1275 case 'r':1276 cMaxFrames = ValueUnion.u64;1277 break;1278 1279 case 's':1280 cNsMaxDuration = ValueUnion.u64 >= UINT64_MAX / RT_NS_1SEC ? UINT64_MAX : ValueUnion.u64 * RT_NS_1SEC;1281 break;1282 1283 case 't':1284 cNsMaxDuration = ValueUnion.u64 >= UINT64_MAX / RT_NS_1MS ? UINT64_MAX : ValueUnion.u64 * RT_NS_1MS;1285 break;1286 1287 case 'T':1288 cNsMaxDuration = ValueUnion.u64;1289 break;1290 1291 case 'z':1292 cbSample = ValueUnion.u8 / 8;1293 break;1294 1295 case 'Z':1296 cbWaveSample = ValueUnion.u8 / 8;1297 break;1298 1299 case VINF_GETOPT_NOT_OPTION:1300 {1301 RTEXITCODE rcExit = audioTestRecOne(ValueUnion.psz, cWaveChannels, cbWaveSample, uWaveHz,1302 pDrvReg, pszDevId, cMsBufferSize, cMsPreBuffer, cMsSchedulingHint,1303 cChannels, cbSample, uHz, fWithDrvAudio, fWithMixer,1304 cMaxFrames, cNsMaxDuration);1305 if (rcExit != RTEXITCODE_SUCCESS)1306 return rcExit;1307 break;1308 }1309 1310 AUDIO_TEST_COMMON_OPTION_CASES(ValueUnion);1311 1312 default:1313 return RTGetOptPrintError(rc, &ValueUnion);1314 }1315 }1316 return RTEXITCODE_SUCCESS;1317 }1318 1319 1320 /*********************************************************************************************************************************1321 * Command: selftest *1322 *********************************************************************************************************************************/1323 1324 /**1325 * Command line parameters for self-test mode.1326 */1327 static const RTGETOPTDEF g_aCmdSelftestOptions[] =1328 {1329 { "--ats-guest-addr", VKAT_SELFTEST_OPT_ATS_GUEST_ADDR, RTGETOPT_REQ_STRING },1330 { "--ats-guest-port", VKAT_SELFTEST_OPT_ATS_GUEST_PORT, RTGETOPT_REQ_UINT32 },1331 { "--ats-valkit-addr", VKAT_SELFTEST_OPT_ATS_GUEST_ADDR, RTGETOPT_REQ_STRING },1332 { "--ats-valkit-port", VKAT_SELFTEST_OPT_ATS_GUEST_PORT, RTGETOPT_REQ_UINT32 },1333 { "--exclude-all", 'a', RTGETOPT_REQ_NOTHING },1334 { "--backend", 'b', RTGETOPT_REQ_STRING },1335 { "--with-drv-audio", 'd', RTGETOPT_REQ_NOTHING },1336 { "--exclude", 'e', RTGETOPT_REQ_UINT32 },1337 { "--include", 'i', RTGETOPT_REQ_UINT32 }1338 };1339 1340 /** the 'selftest' command option help. */1341 static DECLCALLBACK(const char *) audioTestCmdSelftestHelp(PCRTGETOPTDEF pOpt)1342 {1343 switch (pOpt->iShort)1344 {1345 case 'b': return "The audio backend to use.";1346 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend.";1347 default: return NULL;1348 }1349 }1350 1351 /**1352 * The 'selftest' command handler.1353 *1354 * @returns Program exit code.1355 * @param pGetState RTGetOpt state.1356 */1357 DECLCALLBACK(RTEXITCODE) audioTestCmdSelftestHandler(PRTGETOPTSTATE pGetState)1358 {1359 SELFTESTCTX Ctx;1360 RT_ZERO(Ctx);1361 1362 /* Go with the platform's default bakcend if nothing else is specified. */1363 Ctx.Guest.pDrvReg = g_aBackends[0].pDrvReg;1364 1365 /* Argument processing loop: */1366 int rc;1367 RTGETOPTUNION ValueUnion;1368 while ((rc = RTGetOpt(pGetState, &ValueUnion)) != 0)1369 {1370 switch (rc)1371 {1372 case VKAT_SELFTEST_OPT_ATS_GUEST_ADDR:1373 rc = RTStrCopy(Ctx.Host.szGuestAtsAddr, sizeof(Ctx.Host.szGuestAtsAddr), ValueUnion.psz);1374 break;1375 1376 case VKAT_SELFTEST_OPT_ATS_GUEST_PORT:1377 Ctx.Host.uGuestAtsPort = ValueUnion.u32;1378 break;1379 1380 case VKAT_SELFTEST_OPT_ATS_VALKIT_ADDR:1381 rc = RTStrCopy(Ctx.Host.szValKitAtsAddr, sizeof(Ctx.Host.szValKitAtsAddr), ValueUnion.psz);1382 break;1383 1384 case VKAT_SELFTEST_OPT_ATS_VALKIT_PORT:1385 Ctx.Host.uValKitAtsPort = ValueUnion.u32;1386 break;1387 1388 case 'a':1389 for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++)1390 g_aTests[i].fExcluded = true;1391 break;1392 1393 case 'b':1394 Ctx.Guest.pDrvReg = audioTestFindBackendOpt(ValueUnion.psz);1395 if (Ctx.Guest.pDrvReg == NULL)1396 return RTEXITCODE_SYNTAX;1397 break;1398 1399 case 'd':1400 Ctx.fWithDrvAudio = true;1401 break;1402 1403 case 'e':1404 if (ValueUnion.u32 >= RT_ELEMENTS(g_aTests))1405 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid test number %u passed to --exclude", ValueUnion.u32);1406 g_aTests[ValueUnion.u32].fExcluded = true;1407 break;1408 1409 case 'i':1410 if (ValueUnion.u32 >= RT_ELEMENTS(g_aTests))1411 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid test number %u passed to --include", ValueUnion.u32);1412 g_aTests[ValueUnion.u32].fExcluded = false;1413 break;1414 1415 AUDIO_TEST_COMMON_OPTION_CASES(ValueUnion);1416 1417 default:1418 return RTGetOptPrintError(rc, &ValueUnion);1419 }1420 }1421 1422 /*1423 * Start testing.1424 */1425 RTTestBanner(g_hTest);1426 1427 int rc2 = audioTestDoSelftest(&Ctx);1428 if (RT_FAILURE(rc2))1429 RTTestFailed(g_hTest, "Self test failed with rc=%Rrc", rc2);1430 1431 /*1432 * Print summary and exit.1433 */1434 return RTTestSummaryAndDestroy(g_hTest);1435 }1436 1437 1438 /**1439 1005 * Ctrl-C signal handler. 1440 1006 * … … 1451 1017 } 1452 1018 1453 1454 /** 1455 * Commands. 1456 */ 1457 static struct 1458 { 1459 /** The command name. */ 1460 const char *pszCommand; 1461 /** The command handler. */ 1462 DECLCALLBACKMEMBER(RTEXITCODE, pfnHandler,(PRTGETOPTSTATE pGetState)); 1463 1464 /** Command description. */ 1465 const char *pszDesc; 1466 /** Options array. */ 1467 PCRTGETOPTDEF paOptions; 1468 /** Number of options in the option array. */ 1469 size_t cOptions; 1470 /** Gets help for an option. */ 1471 DECLCALLBACKMEMBER(const char *, pfnOptionHelp,(PCRTGETOPTDEF pOpt)); 1472 } const g_aCommands[] = 1019 const VKATCMD g_aCommands[] = 1473 1020 { 1474 1021 { … … 1487 1034 g_aCmdEnumOptions, RT_ELEMENTS(g_aCmdEnumOptions), audioTestCmdEnumHelp, 1488 1035 }, 1489 { 1490 "play", audioTestCmdPlayHandler, 1491 "Plays one or more wave files.", 1492 g_aCmdPlayOptions, RT_ELEMENTS(g_aCmdPlayOptions), audioTestCmdPlayHelp, 1493 }, 1494 { 1495 "rec", audioTestCmdRecHandler, 1496 "Records audio to a wave file.", 1497 g_aCmdRecOptions, RT_ELEMENTS(g_aCmdRecOptions), audioTestCmdRecHelp, 1498 }, 1499 { 1500 "selftest", audioTestCmdSelftestHandler, 1501 "Performs self-tests.", 1502 g_aCmdSelftestOptions, RT_ELEMENTS(g_aCmdSelftestOptions), audioTestCmdSelftestHelp, 1503 } 1036 g_cmdPlay, 1037 g_cmdRec, 1038 g_cmdSelfTest 1504 1039 }; 1505 1040 … … 1507 1042 * Shows tool usage text. 1508 1043 */ 1509 staticRTEXITCODE audioTestUsage(PRTSTREAM pStrm)1044 RTEXITCODE audioTestUsage(PRTSTREAM pStrm) 1510 1045 { 1511 1046 RTStrmPrintf(pStrm, "usage: %s [global options] <command> [command-options]\n", … … 1557 1092 * Shows tool version. 1558 1093 */ 1559 staticRTEXITCODE audioTestVersion(void)1560 { 1561 RTPrintf(" v0.0.1\n");1094 RTEXITCODE audioTestVersion(void) 1095 { 1096 RTPrintf("%s\n", RTBldCfgRevisionStr()); 1562 1097 return RTEXITCODE_SUCCESS; 1563 1098 } -
trunk/src/VBox/ValidationKit/utils/audio/vkatCmdPlayRec.cpp
r89545 r89617 43 43 #include "vkatInternal.h" 44 44 45 46 /*********************************************************************************************************************************47 * Command: play *48 *********************************************************************************************************************************/49 45 50 46 /** … … 451 447 } 452 448 449 450 /********************************************************************************************************************************* 451 * Command: play * 452 *********************************************************************************************************************************/ 453 454 /** 455 * Options for 'play'. 456 */ 457 static const RTGETOPTDEF g_aCmdPlayOptions[] = 458 { 459 { "--backend", 'b', RTGETOPT_REQ_STRING }, 460 { "--channels", 'c', RTGETOPT_REQ_UINT8 }, 461 { "--hz", 'f', RTGETOPT_REQ_UINT32 }, 462 { "--frequency", 'f', RTGETOPT_REQ_UINT32 }, 463 { "--sample-size", 'z', RTGETOPT_REQ_UINT8 }, 464 { "--output-device", 'o', RTGETOPT_REQ_STRING }, 465 { "--with-drv-audio", 'd', RTGETOPT_REQ_NOTHING }, 466 { "--with-mixer", 'm', RTGETOPT_REQ_NOTHING }, 467 }; 468 469 /** The 'play' command option help. */ 470 static DECLCALLBACK(const char *) audioTestCmdPlayHelp(PCRTGETOPTDEF pOpt) 471 { 472 switch (pOpt->iShort) 473 { 474 case 'b': return "The audio backend to use."; 475 case 'c': return "Number of backend output channels"; 476 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend."; 477 case 'f': return "Output frequency (Hz)"; 478 case 'z': return "Output sample size (bits)"; 479 case 'm': return "Go via the mixer."; 480 case 'o': return "The ID of the output device to use."; 481 default: return NULL; 482 } 483 } 484 485 /** 486 * The 'play' command handler. 487 * 488 * @returns Program exit code. 489 * @param pGetState RTGetOpt state. 490 */ 491 static DECLCALLBACK(RTEXITCODE) audioTestCmdPlayHandler(PRTGETOPTSTATE pGetState) 492 { 493 /* Option values: */ 494 PCPDMDRVREG pDrvReg = g_aBackends[0].pDrvReg; 495 uint32_t cMsBufferSize = UINT32_MAX; 496 uint32_t cMsPreBuffer = UINT32_MAX; 497 uint32_t cMsSchedulingHint = UINT32_MAX; 498 const char *pszDevId = NULL; 499 bool fWithDrvAudio = false; 500 bool fWithMixer = false; 501 uint8_t cbSample = 0; 502 uint8_t cChannels = 0; 503 uint32_t uHz = 0; 504 505 /* Argument processing loop: */ 506 int rc; 507 RTGETOPTUNION ValueUnion; 508 while ((rc = RTGetOpt(pGetState, &ValueUnion)) != 0) 509 { 510 switch (rc) 511 { 512 case 'b': 513 pDrvReg = audioTestFindBackendOpt(ValueUnion.psz); 514 if (pDrvReg == NULL) 515 return RTEXITCODE_SYNTAX; 516 break; 517 518 case 'c': 519 cChannels = ValueUnion.u8; 520 break; 521 522 case 'd': 523 fWithDrvAudio = true; 524 break; 525 526 case 'f': 527 uHz = ValueUnion.u32; 528 break; 529 530 case 'm': 531 fWithMixer = true; 532 break; 533 534 case 'o': 535 pszDevId = ValueUnion.psz; 536 break; 537 538 case 'z': 539 cbSample = ValueUnion.u8 / 8; 540 break; 541 542 case VINF_GETOPT_NOT_OPTION: 543 { 544 RTEXITCODE rcExit = audioTestPlayOne(ValueUnion.psz, pDrvReg, pszDevId, cMsBufferSize, cMsPreBuffer, 545 cMsSchedulingHint, cChannels, cbSample, uHz, fWithDrvAudio, fWithMixer); 546 if (rcExit != RTEXITCODE_SUCCESS) 547 return rcExit; 548 break; 549 } 550 551 AUDIO_TEST_COMMON_OPTION_CASES(ValueUnion); 552 553 default: 554 return RTGetOptPrintError(rc, &ValueUnion); 555 } 556 } 557 return RTEXITCODE_SUCCESS; 558 } 559 560 const VKATCMD g_cmdPlay = 561 { 562 "play", audioTestCmdPlayHandler, 563 "Plays one or more wave files.", 564 g_aCmdPlayOptions, RT_ELEMENTS(g_aCmdPlayOptions), audioTestCmdPlayHelp, 565 }; 566 567 568 /********************************************************************************************************************************* 569 * Command: rec * 570 *********************************************************************************************************************************/ 571 572 /** 573 * Options for 'rec'. 574 */ 575 static const RTGETOPTDEF g_aCmdRecOptions[] = 576 { 577 { "--backend", 'b', RTGETOPT_REQ_STRING }, 578 { "--channels", 'c', RTGETOPT_REQ_UINT8 }, 579 { "--hz", 'f', RTGETOPT_REQ_UINT32 }, 580 { "--frequency", 'f', RTGETOPT_REQ_UINT32 }, 581 { "--sample-size", 'z', RTGETOPT_REQ_UINT8 }, 582 { "--input-device", 'i', RTGETOPT_REQ_STRING }, 583 { "--wav-channels", 'C', RTGETOPT_REQ_UINT8 }, 584 { "--wav-hz", 'F', RTGETOPT_REQ_UINT32 }, 585 { "--wav-frequency", 'F', RTGETOPT_REQ_UINT32 }, 586 { "--wav-sample-size", 'Z', RTGETOPT_REQ_UINT8 }, 587 { "--with-drv-audio", 'd', RTGETOPT_REQ_NOTHING }, 588 { "--with-mixer", 'm', RTGETOPT_REQ_NOTHING }, 589 { "--max-frames", 'r', RTGETOPT_REQ_UINT64 }, 590 { "--max-sec", 's', RTGETOPT_REQ_UINT64 }, 591 { "--max-seconds", 's', RTGETOPT_REQ_UINT64 }, 592 { "--max-ms", 't', RTGETOPT_REQ_UINT64 }, 593 { "--max-milliseconds", 't', RTGETOPT_REQ_UINT64 }, 594 { "--max-ns", 'T', RTGETOPT_REQ_UINT64 }, 595 { "--max-nanoseconds", 'T', RTGETOPT_REQ_UINT64 }, 596 }; 597 598 /** The 'rec' command option help. */ 599 static DECLCALLBACK(const char *) audioTestCmdRecHelp(PCRTGETOPTDEF pOpt) 600 { 601 switch (pOpt->iShort) 602 { 603 case 'b': return "The audio backend to use."; 604 case 'c': return "Number of backend input channels"; 605 case 'C': return "Number of wave-file channels"; 606 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend."; 607 case 'f': return "Input frequency (Hz)"; 608 case 'F': return "Wave-file frequency (Hz)"; 609 case 'z': return "Input sample size (bits)"; 610 case 'Z': return "Wave-file sample size (bits)"; 611 case 'm': return "Go via the mixer."; 612 case 'i': return "The ID of the input device to use."; 613 case 'r': return "Max recording duration in frames."; 614 case 's': return "Max recording duration in seconds."; 615 case 't': return "Max recording duration in milliseconds."; 616 case 'T': return "Max recording duration in nanoseconds."; 617 default: return NULL; 618 } 619 } 620 621 /** 622 * The 'play' command handler. 623 * 624 * @returns Program exit code. 625 * @param pGetState RTGetOpt state. 626 */ 627 static DECLCALLBACK(RTEXITCODE) audioTestCmdRecHandler(PRTGETOPTSTATE pGetState) 628 { 629 /* Option values: */ 630 PCPDMDRVREG pDrvReg = g_aBackends[0].pDrvReg; 631 uint32_t cMsBufferSize = UINT32_MAX; 632 uint32_t cMsPreBuffer = UINT32_MAX; 633 uint32_t cMsSchedulingHint = UINT32_MAX; 634 const char *pszDevId = NULL; 635 bool fWithDrvAudio = false; 636 bool fWithMixer = false; 637 uint8_t cbSample = 0; 638 uint8_t cChannels = 0; 639 uint32_t uHz = 0; 640 uint8_t cbWaveSample = 0; 641 uint8_t cWaveChannels = 0; 642 uint32_t uWaveHz = 0; 643 uint64_t cMaxFrames = UINT64_MAX; 644 uint64_t cNsMaxDuration = UINT64_MAX; 645 646 /* Argument processing loop: */ 647 int rc; 648 RTGETOPTUNION ValueUnion; 649 while ((rc = RTGetOpt(pGetState, &ValueUnion)) != 0) 650 { 651 switch (rc) 652 { 653 case 'b': 654 pDrvReg = audioTestFindBackendOpt(ValueUnion.psz); 655 if (pDrvReg == NULL) 656 return RTEXITCODE_SYNTAX; 657 break; 658 659 case 'c': 660 cChannels = ValueUnion.u8; 661 break; 662 663 case 'C': 664 cWaveChannels = ValueUnion.u8; 665 break; 666 667 case 'd': 668 fWithDrvAudio = true; 669 break; 670 671 case 'f': 672 uHz = ValueUnion.u32; 673 break; 674 675 case 'F': 676 uWaveHz = ValueUnion.u32; 677 break; 678 679 case 'i': 680 pszDevId = ValueUnion.psz; 681 break; 682 683 case 'm': 684 fWithMixer = true; 685 break; 686 687 case 'r': 688 cMaxFrames = ValueUnion.u64; 689 break; 690 691 case 's': 692 cNsMaxDuration = ValueUnion.u64 >= UINT64_MAX / RT_NS_1SEC ? UINT64_MAX : ValueUnion.u64 * RT_NS_1SEC; 693 break; 694 695 case 't': 696 cNsMaxDuration = ValueUnion.u64 >= UINT64_MAX / RT_NS_1MS ? UINT64_MAX : ValueUnion.u64 * RT_NS_1MS; 697 break; 698 699 case 'T': 700 cNsMaxDuration = ValueUnion.u64; 701 break; 702 703 case 'z': 704 cbSample = ValueUnion.u8 / 8; 705 break; 706 707 case 'Z': 708 cbWaveSample = ValueUnion.u8 / 8; 709 break; 710 711 case VINF_GETOPT_NOT_OPTION: 712 { 713 RTEXITCODE rcExit = audioTestRecOne(ValueUnion.psz, cWaveChannels, cbWaveSample, uWaveHz, 714 pDrvReg, pszDevId, cMsBufferSize, cMsPreBuffer, cMsSchedulingHint, 715 cChannels, cbSample, uHz, fWithDrvAudio, fWithMixer, 716 cMaxFrames, cNsMaxDuration); 717 if (rcExit != RTEXITCODE_SUCCESS) 718 return rcExit; 719 break; 720 } 721 722 AUDIO_TEST_COMMON_OPTION_CASES(ValueUnion); 723 724 default: 725 return RTGetOptPrintError(rc, &ValueUnion); 726 } 727 } 728 return RTEXITCODE_SUCCESS; 729 } 730 731 const VKATCMD g_cmdRec = 732 { 733 "rec", audioTestCmdRecHandler, 734 "Records audio to a wave file.", 735 g_aCmdRecOptions, RT_ELEMENTS(g_aCmdRecOptions), audioTestCmdRecHelp, 736 }; 737 -
trunk/src/VBox/ValidationKit/utils/audio/vkatCmdSelfTest.cpp
r89575 r89617 200 200 } 201 201 202 203 /********************************************************************************************************************************* 204 * Command: selftest * 205 *********************************************************************************************************************************/ 206 207 /** 208 * Long option values for the 'selftest' command. 209 */ 210 enum 211 { 212 VKAT_SELFTEST_OPT_ATS_GUEST_ADDR = 900, 213 VKAT_SELFTEST_OPT_ATS_GUEST_PORT, 214 VKAT_SELFTEST_OPT_ATS_VALKIT_ADDR, 215 VKAT_SELFTEST_OPT_ATS_VALKIT_PORT 216 }; 217 218 /** 219 * Command line parameters for self-test mode. 220 */ 221 static const RTGETOPTDEF s_aCmdSelftestOptions[] = 222 { 223 { "--ats-guest-addr", VKAT_SELFTEST_OPT_ATS_GUEST_ADDR, RTGETOPT_REQ_STRING }, 224 { "--ats-guest-port", VKAT_SELFTEST_OPT_ATS_GUEST_PORT, RTGETOPT_REQ_UINT32 }, 225 { "--ats-valkit-addr", VKAT_SELFTEST_OPT_ATS_GUEST_ADDR, RTGETOPT_REQ_STRING }, 226 { "--ats-valkit-port", VKAT_SELFTEST_OPT_ATS_GUEST_PORT, RTGETOPT_REQ_UINT32 }, 227 { "--exclude-all", 'a', RTGETOPT_REQ_NOTHING }, 228 { "--backend", 'b', RTGETOPT_REQ_STRING }, 229 { "--with-drv-audio", 'd', RTGETOPT_REQ_NOTHING }, 230 { "--exclude", 'e', RTGETOPT_REQ_UINT32 }, 231 { "--include", 'i', RTGETOPT_REQ_UINT32 } 232 }; 233 234 /** the 'selftest' command option help. */ 235 static DECLCALLBACK(const char *) audioTestCmdSelftestHelp(PCRTGETOPTDEF pOpt) 236 { 237 switch (pOpt->iShort) 238 { 239 case 'b': return "The audio backend to use."; 240 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend."; 241 default: return NULL; 242 } 243 } 244 245 /** 246 * The 'selftest' command handler. 247 * 248 * @returns Program exit code. 249 * @param pGetState RTGetOpt state. 250 */ 251 DECLCALLBACK(RTEXITCODE) audioTestCmdSelftestHandler(PRTGETOPTSTATE pGetState) 252 { 253 SELFTESTCTX Ctx; 254 RT_ZERO(Ctx); 255 256 /* Go with the platform's default bakcend if nothing else is specified. */ 257 Ctx.Guest.pDrvReg = g_aBackends[0].pDrvReg; 258 259 /* Argument processing loop: */ 260 int rc; 261 RTGETOPTUNION ValueUnion; 262 while ((rc = RTGetOpt(pGetState, &ValueUnion)) != 0) 263 { 264 switch (rc) 265 { 266 case VKAT_SELFTEST_OPT_ATS_GUEST_ADDR: 267 rc = RTStrCopy(Ctx.Host.szGuestAtsAddr, sizeof(Ctx.Host.szGuestAtsAddr), ValueUnion.psz); 268 break; 269 270 case VKAT_SELFTEST_OPT_ATS_GUEST_PORT: 271 Ctx.Host.uGuestAtsPort = ValueUnion.u32; 272 break; 273 274 case VKAT_SELFTEST_OPT_ATS_VALKIT_ADDR: 275 rc = RTStrCopy(Ctx.Host.szValKitAtsAddr, sizeof(Ctx.Host.szValKitAtsAddr), ValueUnion.psz); 276 break; 277 278 case VKAT_SELFTEST_OPT_ATS_VALKIT_PORT: 279 Ctx.Host.uValKitAtsPort = ValueUnion.u32; 280 break; 281 282 case 'a': 283 for (unsigned i = 0; i < g_cTests; i++) 284 g_aTests[i].fExcluded = true; 285 break; 286 287 case 'b': 288 Ctx.Guest.pDrvReg = audioTestFindBackendOpt(ValueUnion.psz); 289 if (Ctx.Guest.pDrvReg == NULL) 290 return RTEXITCODE_SYNTAX; 291 break; 292 293 case 'd': 294 Ctx.fWithDrvAudio = true; 295 break; 296 297 case 'e': 298 if (ValueUnion.u32 >= g_cTests) 299 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid test number %u passed to --exclude", ValueUnion.u32); 300 g_aTests[ValueUnion.u32].fExcluded = true; 301 break; 302 303 case 'i': 304 if (ValueUnion.u32 >= g_cTests) 305 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid test number %u passed to --include", ValueUnion.u32); 306 g_aTests[ValueUnion.u32].fExcluded = false; 307 break; 308 309 AUDIO_TEST_COMMON_OPTION_CASES(ValueUnion); 310 311 default: 312 return RTGetOptPrintError(rc, &ValueUnion); 313 } 314 } 315 316 /* 317 * Start testing. 318 */ 319 RTTestBanner(g_hTest); 320 321 int rc2 = audioTestDoSelftest(&Ctx); 322 if (RT_FAILURE(rc2)) 323 RTTestFailed(g_hTest, "Self test failed with rc=%Rrc", rc2); 324 325 /* 326 * Print summary and exit. 327 */ 328 return RTTestSummaryAndDestroy(g_hTest); 329 } 330 331 const VKATCMD g_cmdSelfTest = 332 { 333 "selftest", audioTestCmdSelftestHandler, 334 "Performs self-tests.", 335 s_aCmdSelftestOptions, RT_ELEMENTS(s_aCmdSelftestOptions), audioTestCmdSelftestHelp, 336 }; 337 -
trunk/src/VBox/ValidationKit/utils/audio/vkatInternal.h
r89615 r89617 177 177 }; 178 178 AssertCompile(sizeof(g_aBackends) > 0 /* port me */); 179 180 181 179 182 180 /** … … 346 344 typedef SELFTESTCTX *PSELFTESTCTX; 347 345 346 /** 347 * Structure for defining a single VKAT command. 348 */ 349 typedef struct VKATCMD 350 { 351 /** The command name. */ 352 const char *pszCommand; 353 /** The command handler. */ 354 DECLCALLBACKMEMBER(RTEXITCODE, pfnHandler,(PRTGETOPTSTATE pGetState)); 355 356 /** Command description. */ 357 const char *pszDesc; 358 /** Options array. */ 359 PCRTGETOPTDEF paOptions; 360 /** Number of options in the option array. */ 361 size_t cOptions; 362 /** Gets help for an option. */ 363 DECLCALLBACKMEMBER(const char *, pfnOptionHelp,(PCRTGETOPTDEF pOpt)); 364 } VKATCMD; 365 typedef VKATCMD *PVKATCMD; 366 /** Pointer to a single VKAT command. */ 367 typedef VKATCMD *PVKATCMD; 368 369 extern const VKATCMD g_cmdPlay; 370 extern const VKATCMD g_cmdRec; 371 extern const VKATCMD g_cmdSelfTest; 372 373 extern AUDIOTESTDESC g_aTests[]; 374 extern unsigned g_cTests; 375 348 376 /********************************************************************************************************************************* 349 377 * Prototypes * 350 378 *********************************************************************************************************************************/ 379 380 /** @name Command line handlers 381 * @{ */ 382 RTEXITCODE audioTestUsage(PRTSTREAM pStrm); 383 RTEXITCODE audioTestVersion(void); 384 /** @} */ 351 385 352 386 /** @name Driver stack … … 442 476 /** @} */ 443 477 478 479 /********************************************************************************************************************************* 480 * Common command line stuff * 481 *********************************************************************************************************************************/ 482 483 /** 484 * Common long options values. 485 */ 486 enum 487 { 488 AUDIO_TEST_OPT_CMN_DEBUG_AUDIO_ENABLE = 256, 489 AUDIO_TEST_OPT_CMN_DEBUG_AUDIO_PATH 490 }; 491 492 /** For use in the option switch to handle common options. */ 493 #define AUDIO_TEST_COMMON_OPTION_CASES(a_ValueUnion) \ 494 case 'q': \ 495 g_uVerbosity = 0; \ 496 if (g_pRelLogger) \ 497 RTLogGroupSettings(g_pRelLogger, "all=0 all.e"); \ 498 break; \ 499 \ 500 case 'v': \ 501 g_uVerbosity++; \ 502 if (g_pRelLogger) \ 503 RTLogGroupSettings(g_pRelLogger, g_uVerbosity == 1 ? "all.e.l" : g_uVerbosity == 2 ? "all.e.l.f" : "all=~0"); \ 504 break; \ 505 \ 506 case 'V': \ 507 return audioTestVersion(); \ 508 \ 509 case 'h': \ 510 return audioTestUsage(g_pStdOut); \ 511 \ 512 case AUDIO_TEST_OPT_CMN_DEBUG_AUDIO_ENABLE: \ 513 g_fDrvAudioDebug = true; \ 514 break; \ 515 \ 516 case AUDIO_TEST_OPT_CMN_DEBUG_AUDIO_PATH: \ 517 g_pszDrvAudioDebug = (a_ValueUnion).psz; \ 518 break 519 444 520 #endif /* !VBOX_INCLUDED_SRC_audio_vkatInternal_h */ 445 521
Note:
See TracChangeset
for help on using the changeset viewer.