Changeset 89259 in vbox for trunk/src/VBox
- Timestamp:
- May 25, 2021 9:58:10 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp
r89231 r89259 406 406 } 407 407 408 VMMR3DECL(void) MMR3HeapFree(void *pv) 409 { 410 /* counterpart to CFGMR3QueryStringAlloc */ 411 RTStrFree((char *)pv); 412 } 413 408 414 VMMR3DECL(int) CFGMR3QueryStringDef(PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString, const char *pszDef) 409 415 { … … 819 825 } 820 826 827 return rc; 828 } 829 830 /** 831 * Wrapper around PDMIHOSTAUDIO::pfnSetDevice. 832 */ 833 static int audioTestDriverStackSetDevice(PAUDIOTESTDRVSTACK pDrvStack, PDMAUDIODIR enmDir, const char *pszDevId) 834 { 835 int rc; 836 if ( pDrvStack->pIHostAudio 837 && pDrvStack->pIHostAudio->pfnSetDevice) 838 rc = pDrvStack->pIHostAudio->pfnSetDevice(pDrvStack->pIHostAudio, enmDir, pszDevId); 839 else if (!pszDevId || *pszDevId) 840 rc = VINF_SUCCESS; 841 else 842 rc = VERR_INVALID_FUNCTION; 821 843 return rc; 822 844 } … … 2255 2277 * Worker for audioTestCmdPlayHandler that plays one file. 2256 2278 */ 2257 static RTEXITCODE audioTestPlayOne(const char *pszFile, PCPDMDRVREG pDrvReg, uint32_t cMsBufferSize,2279 static RTEXITCODE audioTestPlayOne(const char *pszFile, PCPDMDRVREG pDrvReg, const char *pszDevId, uint32_t cMsBufferSize, 2258 2280 uint32_t cMsPreBuffer, uint32_t cMsSchedulingHint, bool fWithDrvAudio) 2259 2281 { … … 2286 2308 { 2287 2309 /* 2288 * Open a stream for the output.2310 * Set the output device if one is specified. 2289 2311 */ 2290 PDMAUDIOSTREAMCFG CfgAcq; 2291 PPDMAUDIOSTREAM pStream = NULL; 2292 rc = audioTestDriverStackStreamCreateOutput(&DrvStack, &WaveFile.Props, cMsBufferSize, 2293 cMsPreBuffer, cMsSchedulingHint, &pStream, &CfgAcq); 2312 rc = audioTestDriverStackSetDevice(&DrvStack, PDMAUDIODIR_OUT, pszDevId); 2294 2313 if (RT_SUCCESS(rc)) 2295 2314 { 2296 rc = audioTestDriverStackStreamEnable(&DrvStack, pStream); 2315 /* 2316 * Open a stream for the output. 2317 */ 2318 PDMAUDIOSTREAMCFG CfgAcq; 2319 PPDMAUDIOSTREAM pStream = NULL; 2320 rc = audioTestDriverStackStreamCreateOutput(&DrvStack, &WaveFile.Props, cMsBufferSize, 2321 cMsPreBuffer, cMsSchedulingHint, &pStream, &CfgAcq); 2297 2322 if (RT_SUCCESS(rc)) 2298 2323 { 2299 uint64_t const nsStarted = RTTimeNanoTS(); 2300 2301 /* 2302 * Transfer data as quickly as we're allowed. 2303 */ 2304 for (;;) 2324 rc = audioTestDriverStackStreamEnable(&DrvStack, pStream); 2325 if (RT_SUCCESS(rc)) 2305 2326 { 2306 /* Read a chunk from the wave file. */ 2307 uint8_t abSamples[16384]; 2308 size_t cbSamples = 0; 2309 rc = AudioTestWaveFileRead(&WaveFile, abSamples, sizeof(abSamples), &cbSamples); 2310 if (RT_SUCCESS(rc) && cbSamples > 0) 2327 uint64_t const nsStarted = RTTimeNanoTS(); 2328 2329 /* 2330 * Transfer data as quickly as we're allowed. 2331 */ 2332 for (;;) 2311 2333 { 2312 /* Transfer the data to the audio stream. */ 2313 for (uint32_t offSamples = 0; offSamples < cbSamples;) 2334 /* Read a chunk from the wave file. */ 2335 uint8_t abSamples[16384]; 2336 size_t cbSamples = 0; 2337 rc = AudioTestWaveFileRead(&WaveFile, abSamples, sizeof(abSamples), &cbSamples); 2338 if (RT_SUCCESS(rc) && cbSamples > 0) 2314 2339 { 2315 uint32_t const cbCanWrite = audioTestDriverStackStreamGetWritable(&DrvStack, pStream);2316 if (cbCanWrite > 0)2340 /* Transfer the data to the audio stream. */ 2341 for (uint32_t offSamples = 0; offSamples < cbSamples;) 2317 2342 { 2318 uint32_t const cbToPlay = RT_MIN(cbCanWrite, (uint32_t)cbSamples - offSamples); 2319 uint32_t cbPlayed = 0; 2320 rc = audioTestDriverStackStreamPlay(&DrvStack, pStream, &abSamples[offSamples], 2321 cbToPlay, &cbPlayed); 2322 if (RT_SUCCESS(rc)) 2343 uint32_t const cbCanWrite = audioTestDriverStackStreamGetWritable(&DrvStack, pStream); 2344 if (cbCanWrite > 0) 2323 2345 { 2324 if (cbPlayed) 2325 offSamples += cbPlayed; 2346 uint32_t const cbToPlay = RT_MIN(cbCanWrite, (uint32_t)cbSamples - offSamples); 2347 uint32_t cbPlayed = 0; 2348 rc = audioTestDriverStackStreamPlay(&DrvStack, pStream, &abSamples[offSamples], 2349 cbToPlay, &cbPlayed); 2350 if (RT_SUCCESS(rc)) 2351 { 2352 if (cbPlayed) 2353 offSamples += cbPlayed; 2354 else 2355 { 2356 rcExit = RTMsgErrorExitFailure("Played zero out of %#x bytes - %#x bytes reported playable!\n", 2357 cbToPlay, cbCanWrite); 2358 break; 2359 } 2360 } 2326 2361 else 2327 2362 { 2328 rcExit = RTMsgErrorExitFailure("Played zero out of %#x bytes - %#x bytes reported playable!\n", 2329 cbToPlay, cbCanWrite); 2363 rcExit = RTMsgErrorExitFailure("Failed to play %#x bytes: %Rrc\n", cbToPlay, rc); 2330 2364 break; 2331 2365 } 2332 2366 } 2367 else if (audioTestDriverStackStreamIsOkay(&DrvStack, pStream)) 2368 RTThreadSleep(RT_MIN(RT_MAX(1, CfgAcq.Device.cMsSchedulingHint), 256)); 2333 2369 else 2334 2370 { 2335 rcExit = RTMsgErrorExitFailure(" Failed to play %#x bytes: %Rrc\n", cbToPlay, rc);2371 rcExit = RTMsgErrorExitFailure("Stream is not okay!\n"); 2336 2372 break; 2337 2373 } 2338 2374 } 2339 else if (audioTestDriverStackStreamIsOkay(&DrvStack, pStream)) 2340 RTThreadSleep(RT_MIN(RT_MAX(1, CfgAcq.Device.cMsSchedulingHint), 256)); 2341 else 2342 { 2343 rcExit = RTMsgErrorExitFailure("Stream is not okay!\n"); 2344 break; 2345 } 2375 } 2376 else if (RT_SUCCESS(rc) && cbSamples == 0) 2377 { 2378 rcExit = RTEXITCODE_SUCCESS; 2379 break; 2380 } 2381 else 2382 { 2383 rcExit = RTMsgErrorExitFailure("Error reading wav file '%s': %Rrc", pszFile, rc); 2384 break; 2346 2385 } 2347 2386 } 2348 else if (RT_SUCCESS(rc) && cbSamples == 0) 2387 2388 /* 2389 * Drain the stream. 2390 */ 2391 if (rcExit == RTEXITCODE_SUCCESS) 2349 2392 { 2350 rcExit = RTEXITCODE_SUCCESS; 2351 break; 2352 } 2353 else 2354 { 2355 rcExit = RTMsgErrorExitFailure("Error reading wav file '%s': %Rrc", pszFile, rc); 2356 break; 2393 if (g_uVerbosity > 0) 2394 RTMsgInfo("%'RU64 ns: Draining...\n", RTTimeNanoTS() - nsStarted); 2395 rc = audioTestDriverStackStreamDrain(&DrvStack, pStream, true /*fSync*/); 2396 if (RT_SUCCESS(rc)) 2397 { 2398 if (g_uVerbosity > 0) 2399 RTMsgInfo("%'RU64 ns: Done\n", RTTimeNanoTS() - nsStarted); 2400 } 2401 else 2402 rcExit = RTMsgErrorExitFailure("Draining failed: %Rrc", rc); 2357 2403 } 2358 2404 } 2359 2360 /* 2361 * Drain the stream. 2362 */ 2363 if (rcExit == RTEXITCODE_SUCCESS) 2364 { 2365 if (g_uVerbosity > 0) 2366 RTMsgInfo("%'RU64 ns: Draining...\n", RTTimeNanoTS() - nsStarted); 2367 rc = audioTestDriverStackStreamDrain(&DrvStack, pStream, true /*fSync*/); 2368 if (RT_SUCCESS(rc)) 2369 { 2370 if (g_uVerbosity > 0) 2371 RTMsgInfo("%'RU64 ns: Done\n", RTTimeNanoTS() - nsStarted); 2372 } 2373 else 2374 rcExit = RTMsgErrorExitFailure("Draining failed: %Rrc", rc); 2375 } 2405 else 2406 rcExit = RTMsgErrorExitFailure("Enabling the output stream failed: %Rrc", rc); 2407 audioTestDriverStackStreamDestroy(&DrvStack, pStream); 2376 2408 } 2377 2409 else 2378 rcExit = RTMsgErrorExitFailure("Enabling the output stream failed: %Rrc", rc); 2379 audioTestDriverStackStreamDestroy(&DrvStack, pStream); 2410 rcExit = RTMsgErrorExitFailure("Creating output stream failed: %Rrc", rc); 2380 2411 } 2381 2412 else 2382 rcExit = RTMsgErrorExitFailure(" Creating output stream failed: %Rrc", rc);2413 rcExit = RTMsgErrorExitFailure("Failed to set output device to '%s': %Rrc", pszDevId, rc); 2383 2414 audioTestDriverStackDelete(&DrvStack); 2384 2415 } … … 2395 2426 { 2396 2427 { "--backend", 'b', RTGETOPT_REQ_STRING }, 2428 { "--output-device", 'o', RTGETOPT_REQ_STRING }, 2397 2429 { "--with-drv-audio", 'd', RTGETOPT_REQ_NOTHING }, 2398 2430 }; … … 2405 2437 case 'b': return "The audio backend to use."; 2406 2438 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend."; 2439 case 'o': return "The ID of the output device to use."; 2407 2440 default: return NULL; 2408 2441 } … … 2422 2455 uint32_t cMsPreBuffer = UINT32_MAX; 2423 2456 uint32_t cMsSchedulingHint = UINT32_MAX; 2457 const char *pszDevId = NULL; 2424 2458 bool fWithDrvAudio = false; 2425 2459 … … 2448 2482 break; 2449 2483 2484 case 'o': 2485 pszDevId = ValueUnion.psz; 2486 break; 2487 2450 2488 case VINF_GETOPT_NOT_OPTION: 2451 2489 { 2452 RTEXITCODE rcExit = audioTestPlayOne(ValueUnion.psz, pDrvReg, cMsBufferSize, cMsPreBuffer,2490 RTEXITCODE rcExit = audioTestPlayOne(ValueUnion.psz, pDrvReg, pszDevId, cMsBufferSize, cMsPreBuffer, 2453 2491 cMsSchedulingHint, fWithDrvAudio); 2454 2492 if (rcExit != RTEXITCODE_SUCCESS)
Note:
See TracChangeset
for help on using the changeset viewer.