- Timestamp:
- May 31, 2021 7:26:13 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 144734
- Location:
- trunk/src/VBox
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/VBox/Devices/Audio/AudioTest.cpp ¶
r89316 r89383 27 27 #include <iprt/buildconfig.h> 28 28 #include <iprt/dir.h> 29 #include <iprt/env.h> 29 30 #include <iprt/file.h> 30 31 #include <iprt/formats/riff.h> … … 606 607 AssertReturn(pszTag && strlen(pszTag) <= AUDIOTEST_TAG_MAX, VERR_INVALID_PARAMETER); 607 608 608 char szPath[RTPATH_MAX]; 609 610 int rc = RTPathTemp(szPath, sizeof(szPath)); 611 AssertRCReturn(rc, rc); 612 rc = AudioTestPathCreate(szPath, sizeof(szPath), pszTag); 613 AssertRCReturn(rc, rc); 614 615 return RTStrCopy(pszPath, cbPath, szPath); 609 char szTemp[RTPATH_MAX]; 610 int rc = RTEnvGetEx(RTENV_DEFAULT, "TESTBOX_PATH_SCRATCH", szTemp, sizeof(szTemp), NULL); 611 if (RT_FAILURE(rc)) 612 { 613 rc = RTPathTemp(szTemp, sizeof(szTemp)); 614 AssertRCReturn(rc, rc); 615 } 616 617 rc = AudioTestPathCreate(szTemp, sizeof(szTemp), pszTag); 618 AssertRCReturn(rc, rc); 619 620 return RTStrCopy(pszPath, cbPath, szTemp); 616 621 } 617 622 … … 1224 1229 } 1225 1230 1231 static int audioTestVerifyIniValue(PAUDIOTESTSET pSetA, PAUDIOTESTSET pSetB, 1232 const char *pszSec, const char *pszKey, const char *pszVal) 1233 { 1234 char szValA[_1K]; 1235 int rc = RTIniFileQueryValue(pSetA->f.hIniFile, pszSec, pszKey, szValA, sizeof(szValA), NULL); 1236 if (RT_FAILURE(rc)) 1237 return rc; 1238 char szValB[_1K]; 1239 rc = RTIniFileQueryValue(pSetB->f.hIniFile, pszSec, pszKey, szValB, sizeof(szValB), NULL); 1240 if (RT_FAILURE(rc)) 1241 return rc; 1242 1243 if (RTStrCmp(szValA, szValB)) 1244 return VERR_WRONG_TYPE; /** @todo Fudge! */ 1245 1246 if (pszVal) 1247 { 1248 if (RTStrCmp(szValA, pszVal)) 1249 return VERR_WRONG_TYPE; /** @todo Fudge! */ 1250 } 1251 1252 return rc; 1253 } 1254 1226 1255 /** 1227 1256 * Verifies an opened audio test set. 1228 1257 * 1229 1258 * @returns VBox status code. 1230 * @param pSet Test setto verify.1231 * @param p szTag Tag to use for verification purpose.1259 * @param pSetA Test set A to verify. 1260 * @param pSetB Test set to verify test set A with. 1232 1261 * @param pErrDesc Where to return the test verification errors. 1233 1262 * … … 1235 1264 * actual return code. 1236 1265 */ 1237 int AudioTestSetVerify(PAUDIOTESTSET pSet, const char *pszTag, PAUDIOTESTERRORDESC pErrDesc) 1238 { 1239 AssertReturn(audioTestManifestIsOpen(pSet), VERR_WRONG_ORDER); 1266 int AudioTestSetVerify(PAUDIOTESTSET pSetA, PAUDIOTESTSET pSetB, PAUDIOTESTERRORDESC pErrDesc) 1267 { 1268 AssertReturn(audioTestManifestIsOpen(pSetA), VERR_WRONG_ORDER); 1269 AssertReturn(audioTestManifestIsOpen(pSetB), VERR_WRONG_ORDER); 1240 1270 1241 1271 /* We ASSUME the caller has not init'd pErrDesc. */ 1242 1272 audioTestErrorDescInit(pErrDesc); 1243 1273 1244 char szVal[_1K]; /** @todo Enough, too much? */ 1245 1246 int rc2 = RTIniFileQueryValue(pSet->f.hIniFile, AUDIOTEST_INI_SEC_HDR_STR, "tag", szVal, sizeof(szVal), NULL); 1247 if ( RT_FAILURE(rc2) 1248 || RTStrICmp(pszTag, szVal)) 1249 audioTestErrorDescAdd(pErrDesc, "Tag '%s' does not match with manifest's tag '%s'", pszTag, szVal); 1274 int rc; 1275 1276 #define VERIFY_VALUE(a_Sec, a_Key, a_Val, ...) \ 1277 rc = audioTestVerifyIniValue(pSetA, pSetB, a_Sec, a_Key, a_Val); \ 1278 if (RT_FAILURE(rc)) \ 1279 return audioTestErrorDescAdd(pErrDesc, (__VA_ARGS__)); 1280 1281 /* 1282 * Compare obvious values first. 1283 */ 1284 VERIFY_VALUE("header", "magic", "vkat_ini", "Manifest magic wrong"); 1285 VERIFY_VALUE("header", "ver", "1" , "Manifest version wrong"); 1286 VERIFY_VALUE("header", "tag", NULL, "Manifest tags don't match"); 1287 VERIFY_VALUE("header", "test_count", NULL, "Test counts don't match"); 1288 VERIFY_VALUE("header", "obj_count", NULL, "Object counts don't match"); 1289 1290 #undef VERIFY_VALUE 1250 1291 1251 1292 /* Only return critical stuff not related to actual testing here. */ -
TabularUnified trunk/src/VBox/Devices/Audio/AudioTest.h ¶
r89316 r89383 337 337 int AudioTestSetPack(PAUDIOTESTSET pSet, const char *pszOutDir, char *pszFileName, size_t cbFileName); 338 338 int AudioTestSetUnpack(const char *pszFile, const char *pszOutDir); 339 int AudioTestSetVerify(PAUDIOTESTSET pSet , const char *pszTag, PAUDIOTESTERRORDESC pErrDesc);339 int AudioTestSetVerify(PAUDIOTESTSET pSetA, PAUDIOTESTSET pSetB, PAUDIOTESTERRORDESC pErrDesc); 340 340 341 341 bool AudioTestErrorDescFailed(PAUDIOTESTERRORDESC pErr); -
TabularUnified trunk/src/VBox/Devices/Audio/DrvHostAudioValidationKit.cpp ¶
r89308 r89383 49 49 /** The stream's acquired configuration. */ 50 50 PDMAUDIOSTREAMCFG Cfg; 51 /** Audio file to dump output to or read input from. */52 PAUDIOHLPFILE pFile;53 /** Text file to store timing of audio buffers submittions. */54 PRTSTREAM pFileTiming;55 /** Timestamp of the first play or record request. */56 uint64_t tsStarted;57 /** Total number of frames played or recorded so far. */58 uint32_t cFramesSinceStarted;59 union60 {61 struct62 {63 /** Timestamp of last captured samples. */64 uint64_t tsLastCaptured;65 } In;66 struct67 {68 /** Timestamp of last played samples. */69 uint64_t tsLastPlayed;70 uint8_t *pbPlayBuffer;71 uint32_t cbPlayBuffer;72 } Out;73 };74 51 } VALKITAUDIOSTREAM; 75 52 /** Pointer to a Validation Kit stream. */ … … 212 189 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 213 190 { 214 RT_NOREF(pThis, pCfgAcq); 215 216 /* Use the test box scratch dir if we're running in such an 217 environment, otherwise just dump the output in the temp 218 directory. */ 219 char szTemp[RTPATH_MAX]; 220 int rc = RTEnvGetEx(RTENV_DEFAULT, "TESTBOX_PATH_SCRATCH", szTemp, sizeof(szTemp), NULL); 221 if (RT_FAILURE(rc)) 222 { 223 rc = RTPathTemp(szTemp, sizeof(szTemp)); 224 if (RT_SUCCESS(rc)) 225 rc = RTPathAppend(szTemp, sizeof(szTemp), "VBoxAudioValKit"); 226 AssertRCReturn(rc, rc); 227 } 228 229 /* Get down to things that may fail and need cleanup. */ 230 pStreamDbg->tsStarted = 0; 231 pStreamDbg->cFramesSinceStarted = 0; 232 pStreamDbg->Out.tsLastPlayed = 0; 233 pStreamDbg->Out.cbPlayBuffer = PDMAudioPropsFramesToBytes(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize); 234 pStreamDbg->Out.pbPlayBuffer = (uint8_t *)RTMemAlloc(pStreamDbg->Out.cbPlayBuffer); 235 AssertReturn(pStreamDbg->Out.pbPlayBuffer, VERR_NO_MEMORY); 236 237 rc = AudioHlpFileCreateAndOpenEx(&pStreamDbg->pFile, AUDIOHLPFILETYPE_WAV, szTemp, "ValKit", 238 pThis->pDrvIns->iInstance, AUDIOHLPFILENAME_FLAGS_NONE, AUDIOHLPFILE_FLAGS_NONE, 239 &pCfgReq->Props, AUDIOHLPFILE_DEFAULT_OPEN_FLAGS); 240 if (RT_SUCCESS(rc)) 241 { 242 rc = RTPathAppend(szTemp, sizeof(szTemp), "ValKitTimings.txt"); 243 if (RT_SUCCESS(rc)) 244 { 245 rc = RTStrmOpen(szTemp, "w", &pStreamDbg->pFileTiming); 246 if (RT_SUCCESS(rc)) 247 { 248 RTStrmPrintf(pStreamDbg->pFileTiming, "# %uHz %uch %ubit\n", 249 PDMAudioPropsHz(&pCfgReq->Props), 250 PDMAudioPropsChannels(&pCfgReq->Props), 251 PDMAudioPropsSampleBits(&pCfgReq->Props)); 252 return VINF_SUCCESS; 253 } 254 255 LogRel(("ValKitAudio: Opening output file '%s' failed: %Rrc\n", szTemp, rc)); 256 } 257 else 258 LogRel(("ValKitAudio: Constructing timing file path: %Rrc\n", rc)); 259 260 AudioHlpFileDestroy(pStreamDbg->pFile); 261 pStreamDbg->pFile = NULL; 262 } 263 else 264 LogRel(("ValKitAudio: Creating output file 'ValKit' in '%s' failed: %Rrc\n", szTemp, rc)); 265 266 RTMemFree(pStreamDbg->Out.pbPlayBuffer); 267 pStreamDbg->Out.pbPlayBuffer = NULL; 268 return rc; 191 RT_NOREF(pThis, pStreamDbg, pCfgReq, pCfgAcq); 192 193 return VINF_SUCCESS; 269 194 } 270 195 … … 276 201 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 277 202 { 278 PDRVHOSTVALKITAUDIO pThis 203 PDRVHOSTVALKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio); 279 204 PVALKITAUDIOSTREAM pStreamDbg = (PVALKITAUDIOSTREAM)pStream; 280 205 AssertPtrReturn(pStreamDbg, VERR_INVALID_POINTER); … … 302 227 AssertPtrReturn(pStreamDbg, VERR_INVALID_POINTER); 303 228 304 if ( pStreamDbg->Cfg.enmDir == PDMAUDIODIR_OUT305 && pStreamDbg->Out.pbPlayBuffer)306 {307 RTMemFree(pStreamDbg->Out.pbPlayBuffer);308 pStreamDbg->Out.pbPlayBuffer = NULL;309 }310 311 if (pStreamDbg->pFile)312 {313 size_t cbDataSize = AudioHlpFileGetDataSize(pStreamDbg->pFile);314 if (cbDataSize)315 LogRel(("ValKitAudio: Created output file '%s' (%zu bytes)\n", pStreamDbg->pFile->szName, cbDataSize));316 317 AudioHlpFileDestroy(pStreamDbg->pFile);318 pStreamDbg->pFile = NULL;319 }320 321 if (pStreamDbg->pFileTiming)322 {323 RTStrmClose(pStreamDbg->pFileTiming);324 pStreamDbg->pFileTiming = NULL;325 }326 327 229 return VINF_SUCCESS; 328 230 } … … 348 250 PVALKITAUDIOSTREAM pStreamDbg = (PVALKITAUDIOSTREAM)pStream; 349 251 AssertPtrReturn(pStreamDbg, VERR_INVALID_POINTER); 350 351 if (pStreamDbg->pFileTiming)352 RTStrmFlush(pStreamDbg->pFileTiming);353 252 354 253 return VINF_SUCCESS; … … 429 328 PDRVHOSTVALKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVALKITAUDIO, IHostAudio); 430 329 PVALKITAUDIOSTREAM pStreamDbg = (PVALKITAUDIOSTREAM)pStream; 431 RT_NOREF(pThis); 432 433 uint64_t cNsSinceStart; 434 if (pStreamDbg->tsStarted != 0) 435 cNsSinceStart = RTTimeNanoTS() - pStreamDbg->tsStarted; 436 else 437 { 438 pStreamDbg->tsStarted = RTTimeNanoTS(); 439 cNsSinceStart = 0; 440 } 441 442 // Microseconds are used everythere below 443 uint32_t const cFrames = PDMAudioPropsBytesToFrames(&pStreamDbg->Cfg.Props, cbBuf); 444 RTStrmPrintf(pStreamDbg->pFileTiming, "%d %d %d %d\n", 445 // Host time elapsed since Guest submitted the first buffer for playback: 446 (uint32_t)(cNsSinceStart / 1000), 447 // how long all the samples submitted previously were played: 448 (uint32_t)(pStreamDbg->cFramesSinceStarted * 1.0E6 / pStreamDbg->Cfg.Props.uHz), 449 // how long a new uSamplesReady samples should/will be played: 450 (uint32_t)(cFrames * 1.0E6 / pStreamDbg->Cfg.Props.uHz), 451 cFrames); 452 453 pStreamDbg->cFramesSinceStarted += cFrames; 454 455 /* Remember when samples were consumed. */ 456 // pStreamDbg->Out.tsLastPlayed = PDMDrvHlpTMGetVirtualTime(pThis->pDrvIns); 457 458 int rc2 = AudioHlpFileWrite(pStreamDbg->pFile, pvBuf, cbBuf, 0 /* fFlags */); 459 if (RT_FAILURE(rc2)) 460 LogRel(("ValKitAudio: Writing output failed with %Rrc\n", rc2)); 461 462 *pcbWritten = cbBuf; 330 RT_NOREF(pThis, pStreamDbg, pvBuf, cbBuf); 331 332 *pcbWritten = 0; 463 333 return VINF_SUCCESS; 464 334 } -
TabularUnified trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp ¶
r89380 r89383 2216 2216 *********************************************************************************************************************************/ 2217 2217 2218 /** 2219 * Verifies one single test set. 2220 * 2221 * @returns VBox status code. 2222 * @param pszPath Absolute path to test set. 2223 * @param pszTag Tag of test set to verify. Optional and can be NULL. 2224 */ 2225 static int audioVerifyOne(const char *pszPath, const char *pszTag) 2226 { 2227 RTTestSubF(g_hTest, "Verifying test set ..."); 2228 2229 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Using tag '%s'\n", pszTag ? pszTag : "default"); 2230 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Opening archive '%s'\n", pszPath); 2231 2232 int rc = VINF_SUCCESS; 2218 static int audioVerifyOpenTestSet(const char *pszPathSet, PAUDIOTESTSET pSet) 2219 { 2220 int rc; 2233 2221 2234 2222 char szPathExtracted[RTPATH_MAX]; 2235 const bool fPacked = AudioTestSetIsPacked(pszPath); 2223 2224 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Opening test set '%s'\n", pszPathSet); 2225 2226 const bool fPacked = AudioTestSetIsPacked(pszPathSet); 2236 2227 if (fPacked) 2237 2228 { 2229 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test set is an archive and needs to be unpacked\n"); 2230 2238 2231 char szPathTemp[RTPATH_MAX]; 2239 2232 rc = RTPathTemp(szPathTemp, sizeof(szPathTemp)); … … 2249 2242 { 2250 2243 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Unpacking archive to '%s'\n", szPathExtracted); 2251 rc = AudioTestSetUnpack(pszPath , szPathExtracted);2244 rc = AudioTestSetUnpack(pszPathSet, szPathExtracted); 2252 2245 if (RT_SUCCESS(rc)) 2253 2246 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Archive successfully unpacked\n"); … … 2256 2249 } 2257 2250 } 2251 else 2252 rc = VINF_SUCCESS; 2253 2254 if (RT_SUCCESS(rc)) 2255 rc = AudioTestSetOpen(pSet, fPacked ? szPathExtracted : pszPathSet); 2258 2256 2259 2257 if (RT_FAILURE(rc)) 2260 {2261 2258 RTTestFailed(g_hTest, "Unable to open / unpack test set archive: %Rrc", rc); 2262 return rc; 2263 } 2264 2265 AUDIOTESTSET tstSet; 2266 rc = AudioTestSetOpen(&tstSet, fPacked ? szPathExtracted : pszPath); 2259 2260 return rc; 2261 } 2262 2263 /** 2264 * Verifies one single test set. 2265 * 2266 * @returns VBox status code. 2267 * @param pszPathSetA Absolute path to test set A. 2268 * @param pszPathSetB Absolute path to test set B. 2269 */ 2270 static int audioVerifyOne(const char *pszPathSetA, const char *pszPathSetB) 2271 { 2272 RTTestSubF(g_hTest, "Verifying"); 2273 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Verifying test set '%s' with test set '%s'\n", pszPathSetA, pszPathSetB); 2274 2275 AUDIOTESTSET SetA, SetB; 2276 int rc = audioVerifyOpenTestSet(pszPathSetA, &SetA); 2267 2277 if (RT_SUCCESS(rc)) 2278 rc = audioVerifyOpenTestSet(pszPathSetB, &SetB); 2279 2280 if (RT_SUCCESS(rc)) 2268 2281 { 2269 2282 AUDIOTESTERRORDESC errDesc; 2270 rc = AudioTestSetVerify(& tstSet, pszTag ? pszTag : "default", &errDesc);2283 rc = AudioTestSetVerify(&SetA, &SetB, &errDesc); 2271 2284 if (RT_SUCCESS(rc)) 2272 2285 { … … 2276 2289 PAUDIOTESTERRORENTRY pErrEntry; 2277 2290 RTListForEach(&errDesc.List, pErrEntry, AUDIOTESTERRORENTRY, Node) 2278 {2279 2291 RTTestFailed(g_hTest, pErrEntry->szDesc); 2280 }2281 2292 } 2282 2293 else 2283 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Verification successful ");2294 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Verification successful\n"); 2284 2295 2285 2296 AudioTestErrorDescDestroy(&errDesc); … … 2287 2298 else 2288 2299 RTTestFailed(g_hTest, "Verification failed with %Rrc", rc); 2289 2290 AudioTestSetClose(&tstSet); 2291 } 2292 else 2293 RTTestFailed(g_hTest, "Opening test set '%s' (tag '%s') failed, rc=%Rrc\n", pszPath, pszTag, rc); 2300 } 2301 2302 AudioTestSetClose(&SetA); 2303 AudioTestSetClose(&SetB); 2294 2304 2295 2305 RTTestSubDone(g_hTest); … … 2309 2319 * Parse options and process arguments. 2310 2320 */ 2311 const char *pszTag = NULL; /* Custom tag to use. Can be NULL if not being used. */ 2312 unsigned iTestSet = 0; 2321 char *pszSetA = NULL; 2322 char *pszSetB = NULL; 2323 unsigned iTestSet = 0; 2313 2324 2314 2325 int rc; … … 2319 2330 { 2320 2331 case VKAT_VERIFY_OPT_TAG: 2321 pszTag = ValueUnion.psz;2322 if (g_uVerbosity > 0)2323 RTMsgInfo("Using tag '%s'\n", pszTag);2324 2332 break; 2325 2333 2326 2334 case VINF_GETOPT_NOT_OPTION: 2335 { 2336 char **ppszSet = iTestSet == 0 ? &pszSetA : &pszSetB; 2337 2327 2338 if (iTestSet == 0) 2328 2339 RTTestBanner(g_hTest); 2329 audioVerifyOne(ValueUnion.psz, pszTag); 2340 2341 *ppszSet = RTStrDup(ValueUnion.psz); 2342 AssertPtrReturn(*ppszSet, RTEXITCODE_FAILURE); 2343 2330 2344 iTestSet++; 2331 2345 break; 2346 } 2332 2347 2333 2348 AUDIO_TEST_COMMON_OPTION_CASES(ValueUnion); … … 2338 2353 } 2339 2354 2355 if (!iTestSet) 2356 return RTMsgErrorExitFailure("At least one test set must be specified"); 2357 2358 if (iTestSet > 2) 2359 return RTMsgErrorExitFailure("Only two test sets can be verified at one time"); 2360 2340 2361 /* 2341 * If no paths given, default to the current directory. 2362 * If only test set A is given, default to the current directory 2363 * for test set B. 2342 2364 */ 2343 if (iTestSet == 0) 2344 { 2345 if (iTestSet == 0) 2346 RTTestBanner(g_hTest); 2365 if (iTestSet == 1) 2366 { 2347 2367 char szDirCur[RTPATH_MAX]; 2348 int rc2 = RTPathGetCurrent(szDirCur, sizeof(szDirCur)); 2349 if (RT_FAILURE(rc2)) 2350 RTTestFailed(g_hTest, "Failed to retrieve current directory: %Rrc", rc2); 2351 rc = audioVerifyOne(RT_SUCCESS(rc2) ? szDirCur : ".", pszTag); 2352 } 2368 rc = RTPathGetCurrent(szDirCur, sizeof(szDirCur)); 2369 if (RT_SUCCESS(rc)) 2370 { 2371 Assert(pszSetB == NULL); 2372 pszSetB = RTStrDup(szDirCur); 2373 AssertPtrReturn(pszSetB, RTEXITCODE_FAILURE); 2374 } 2375 else 2376 RTTestFailed(g_hTest, "Failed to retrieve current directory: %Rrc", rc); 2377 } 2378 2379 if (RT_SUCCESS(rc)) 2380 rc = audioVerifyOne(pszSetA, pszSetB); 2381 2382 RTStrFree(pszSetA); 2383 RTStrFree(pszSetB); 2353 2384 2354 2385 /*
Note:
See TracChangeset
for help on using the changeset viewer.