Changeset 89466 in vbox for trunk/src/VBox/ValidationKit
- Timestamp:
- Jun 2, 2021 1:03:44 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 144821
- Location:
- trunk/src/VBox/ValidationKit/utils/audio
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp
r89460 r89466 53 53 # include <iprt/win/windows.h> /* for CoInitializeEx */ 54 54 #endif 55 #include <signal.h> 55 56 56 57 /** … … 391 392 AssertCompile(sizeof(g_aBackends) > 0 /* port me */); 392 393 393 static volatile bool g_fTerminated = false; 394 395 /** Terminate ASAP if set. Set on Ctrl-C. */ 396 static bool volatile g_fTerminate = false; 394 397 /** The release logger. */ 395 static PRTLOGGER g_pRelLogger = NULL;398 static PRTLOGGER g_pRelLogger = NULL; 396 399 397 400 … … 404 407 /** DrvAudio: The debug output path. */ 405 408 const char *g_pszDrvAudioDebug = NULL; 406 407 409 408 410 … … 1292 1294 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "ATS running\n"); 1293 1295 1294 while (!g_fTerminate d) /** @todo Implement signal handling. */1296 while (!g_fTerminate) /** @todo Implement signal handling. */ 1295 1297 { 1296 1298 RTThreadSleep(100); … … 1821 1823 uint32_t const cbSamplesAligned = PDMAudioPropsFloorBytesToFrame(pMix->pProps, sizeof(abSamples)); 1822 1824 uint64_t offStream = 0; 1823 for (;;)1825 while (!g_fTerminate) 1824 1826 { 1825 1827 /* Read a chunk from the wave file. */ … … 1854 1856 } 1855 1857 else 1856 return RTMsgErrorExitFailure("Played zero out of %#x bytes - %#x bytes reported playable!\n", 1857 cbToPlay, cbCanWrite); 1858 return RTMsgErrorExitFailure("Played zero bytes - %#x bytes reported playable!\n", cbCanWrite); 1858 1859 } 1859 1860 else … … 1959 1960 { 1960 1961 if (g_uVerbosity > 0) 1961 RTMsgInfo("Stream: %s cbBacke d=%#RX32%s\n", PDMAudioPropsToString(&pStream->Props, szTmp, sizeof(szTmp)),1962 RTMsgInfo("Stream: %s cbBackend=%#RX32%s\n", PDMAudioPropsToString(&pStream->Props, szTmp, sizeof(szTmp)), 1962 1963 pStream->cbBackend, fWithMixer ? " mixed" : ""); 1963 1964 … … 1965 1966 * Enable the stream and start playing. 1966 1967 */ 1967 rc = audioTestDriverStackStreamEnable(&DrvStack, pStream);1968 rc = AudioTestMixStreamEnable(&Mix); 1968 1969 if (RT_SUCCESS(rc)) 1969 1970 rcExit = audioTestPlayOneInner(&Mix, &WaveFile, &CfgAcq, pszFile); … … 2099 2100 2100 2101 /********************************************************************************************************************************* 2102 * Command: rec * 2103 *********************************************************************************************************************************/ 2104 2105 /** 2106 * Worker for audioTestRecOne implementing the recording loop. 2107 */ 2108 static RTEXITCODE audioTestRecOneInner(PAUDIOTESTDRVMIXSTREAM pMix, PAUDIOTESTWAVEFILE pWaveFile, 2109 PCPDMAUDIOSTREAMCFG pCfgAcq, uint64_t cMaxFrames, const char *pszFile) 2110 { 2111 int rc; 2112 uint32_t const cbPreBuffer = PDMAudioPropsFramesToBytes(pMix->pProps, pCfgAcq->Backend.cFramesPreBuffering); 2113 uint64_t const nsStarted = RTTimeNanoTS(); 2114 2115 /* 2116 * Transfer data as quickly as we're allowed. 2117 */ 2118 uint8_t abSamples[16384]; 2119 uint32_t const cbSamplesAligned = PDMAudioPropsFloorBytesToFrame(pMix->pProps, sizeof(abSamples)); 2120 uint64_t cFramesCapturedTotal = 0; 2121 while (!g_fTerminate && cFramesCapturedTotal < cMaxFrames) 2122 { 2123 /* 2124 * Anything we can read? 2125 */ 2126 uint32_t const cbCanRead = AudioTestMixStreamGetReadable(pMix); 2127 if (cbCanRead) 2128 { 2129 uint32_t const cbToRead = RT_MIN(cbCanRead, cbSamplesAligned); 2130 uint32_t cbCaptured = 0; 2131 rc = AudioTestMixStreamCapture(pMix, abSamples, cbToRead, &cbCaptured); 2132 if (RT_SUCCESS(rc)) 2133 { 2134 if (cbCaptured) 2135 { 2136 uint32_t cFramesCaptured = PDMAudioPropsBytesToFrames(pMix->pProps, cbCaptured); 2137 if (cFramesCaptured + cFramesCaptured < cMaxFrames) 2138 { /* likely */ } 2139 else 2140 { 2141 cFramesCaptured = cMaxFrames - cFramesCaptured; 2142 cbCaptured = PDMAudioPropsFramesToBytes(pMix->pProps, cFramesCaptured); 2143 } 2144 2145 rc = AudioTestWaveFileWrite(pWaveFile, abSamples, cbCaptured); 2146 if (RT_SUCCESS(rc)) 2147 cFramesCapturedTotal += cFramesCaptured; 2148 else 2149 return RTMsgErrorExitFailure("Error writing to '%s': %Rrc", pszFile, rc); 2150 } 2151 else 2152 return RTMsgErrorExitFailure("Captured zero bytes - %#x bytes reported readable!\n", cbCanRead); 2153 } 2154 else 2155 return RTMsgErrorExitFailure("Failed to capture %#x bytes: %Rrc (%#x available)\n", cbToRead, rc, cbCanRead); 2156 } 2157 else if (AudioTestMixStreamIsOkay(pMix)) 2158 RTThreadSleep(RT_MIN(RT_MAX(1, pCfgAcq->Device.cMsSchedulingHint), 256)); 2159 else 2160 return RTMsgErrorExitFailure("Stream is not okay!\n"); 2161 } 2162 2163 /* 2164 * Disable the stream. 2165 */ 2166 rc = AudioTestMixStreamDisable(pMix); 2167 if (RT_SUCCESS(rc) && g_uVerbosity > 0) 2168 RTMsgInfo("%'RU64 ns: Stopped after recording %RU64 frames%s\n", RTTimeNanoTS() - nsStarted, cFramesCapturedTotal, 2169 g_fTerminate ? " - Ctrl-C" : "."); 2170 else if (RT_FAILURE(rc)) 2171 return RTMsgErrorExitFailure("Disabling stream failed: %Rrc", rc); 2172 2173 return RTEXITCODE_SUCCESS; 2174 } 2175 2176 2177 /** 2178 * Worker for audioTestCmdRecHandler that recs one file. 2179 */ 2180 static RTEXITCODE audioTestRecOne(const char *pszFile, uint8_t cWaveChannels, uint8_t cbWaveSample, uint32_t uWaveHz, 2181 PCPDMDRVREG pDrvReg, const char *pszDevId, uint32_t cMsBufferSize, 2182 uint32_t cMsPreBuffer, uint32_t cMsSchedulingHint, 2183 uint8_t cChannels, uint8_t cbSample, uint32_t uHz, bool fWithDrvAudio, bool fWithMixer, 2184 uint64_t cMaxFrames, uint64_t cNsMaxDuration) 2185 { 2186 /* 2187 * Construct the driver stack. 2188 */ 2189 RTEXITCODE rcExit = RTEXITCODE_FAILURE; 2190 AUDIOTESTDRVSTACK DrvStack; 2191 int rc = audioTestDriverStackInit(&DrvStack, pDrvReg, fWithDrvAudio); 2192 if (RT_SUCCESS(rc)) 2193 { 2194 /* 2195 * Set the input device if one is specified. 2196 */ 2197 rc = audioTestDriverStackSetDevice(&DrvStack, PDMAUDIODIR_IN, pszDevId); 2198 if (RT_SUCCESS(rc)) 2199 { 2200 /* 2201 * Create an input stream. 2202 */ 2203 PDMAUDIOPCMPROPS ReqProps; 2204 PDMAudioPropsInit(&ReqProps, 2205 cbSample ? cbSample : cbWaveSample ? cbWaveSample : 2, 2206 true /*fSigned*/, 2207 cChannels ? cChannels : cWaveChannels ? cWaveChannels : 2, 2208 uHz ? uHz : uWaveHz ? uWaveHz : 44100); 2209 PDMAUDIOSTREAMCFG CfgAcq; 2210 PPDMAUDIOSTREAM pStream = NULL; 2211 rc = audioTestDriverStackStreamCreateInput(&DrvStack, &ReqProps, cMsBufferSize, 2212 cMsPreBuffer, cMsSchedulingHint, &pStream, &CfgAcq); 2213 if (RT_SUCCESS(rc)) 2214 { 2215 /* 2216 * Determine the wave file properties. If it differs from the stream 2217 * properties, make sure the mixer is enabled. 2218 */ 2219 PDMAUDIOPCMPROPS WaveProps; 2220 PDMAudioPropsInit(&WaveProps, 2221 cbWaveSample ? cbWaveSample : PDMAudioPropsSampleSize(&CfgAcq.Props), 2222 true /*fSigned*/, 2223 cWaveChannels ? cWaveChannels : PDMAudioPropsChannels(&CfgAcq.Props), 2224 uWaveHz ? uWaveHz : PDMAudioPropsHz(&CfgAcq.Props)); 2225 if (!fWithMixer && !PDMAudioPropsAreEqual(&WaveProps, &CfgAcq.Props)) 2226 { 2227 RTMsgInfo("Enabling the mixer buffer.\n"); 2228 fWithMixer = true; 2229 } 2230 2231 /* Console the max duration into frames now that we've got the wave file format. */ 2232 if (cMaxFrames != UINT64_MAX && cNsMaxDuration != UINT64_MAX) 2233 { 2234 uint64_t cMaxFrames2 = PDMAudioPropsNanoToBytes64(&WaveProps, cNsMaxDuration); 2235 cMaxFrames = RT_MAX(cMaxFrames, cMaxFrames2); 2236 } 2237 else if (cNsMaxDuration != UINT64_MAX) 2238 cMaxFrames = PDMAudioPropsNanoToBytes64(&WaveProps, cNsMaxDuration); 2239 2240 /* 2241 * Create a mixer wrapper. This is just a thin wrapper if fWithMixer 2242 * is false, otherwise it's doing mixing, resampling and recoding. 2243 */ 2244 AUDIOTESTDRVMIXSTREAM Mix; 2245 rc = AudioTestMixStreamInit(&Mix, &DrvStack, pStream, fWithMixer ? &WaveProps : NULL, 100 /*ms*/); 2246 if (RT_SUCCESS(rc)) 2247 { 2248 char szTmp[128]; 2249 if (g_uVerbosity > 0) 2250 RTMsgInfo("Stream: %s cbBackend=%#RX32%s\n", PDMAudioPropsToString(&pStream->Props, szTmp, sizeof(szTmp)), 2251 pStream->cbBackend, fWithMixer ? " mixed" : ""); 2252 2253 /* 2254 * Open the wave output file. 2255 */ 2256 AUDIOTESTWAVEFILE WaveFile; 2257 RTERRINFOSTATIC ErrInfo; 2258 rc = AudioTestWaveFileCreate(pszFile, &WaveProps, &WaveFile, RTErrInfoInitStatic(&ErrInfo)); 2259 if (RT_SUCCESS(rc)) 2260 { 2261 if (g_uVerbosity > 0) 2262 { 2263 RTMsgInfo("Opened '%s' for playing\n", pszFile); 2264 RTMsgInfo("Format: %s\n", PDMAudioPropsToString(&WaveFile.Props, szTmp, sizeof(szTmp))); 2265 } 2266 2267 /* 2268 * Enable the stream and start recording. 2269 */ 2270 rc = AudioTestMixStreamEnable(&Mix); 2271 if (RT_SUCCESS(rc)) 2272 rcExit = audioTestRecOneInner(&Mix, &WaveFile, &CfgAcq, cMaxFrames, pszFile); 2273 else 2274 rcExit = RTMsgErrorExitFailure("Enabling the input stream failed: %Rrc", rc); 2275 if (rcExit != RTEXITCODE_SUCCESS) 2276 AudioTestMixStreamDisable(&Mix); 2277 2278 /* 2279 * Clean up. 2280 */ 2281 rc = AudioTestWaveFileClose(&WaveFile); 2282 if (RT_FAILURE(rc)) 2283 rcExit = RTMsgErrorExitFailure("Error closing '%s': %Rrc", pszFile, rc); 2284 } 2285 else 2286 rcExit = RTMsgErrorExitFailure("Failed to open '%s': %Rrc%#RTeim", pszFile, rc, &ErrInfo.Core.pszMsg); 2287 2288 AudioTestMixStreamTerm(&Mix); 2289 } 2290 audioTestDriverStackStreamDestroy(&DrvStack, pStream); 2291 } 2292 else 2293 rcExit = RTMsgErrorExitFailure("Creating output stream failed: %Rrc", rc); 2294 } 2295 else 2296 rcExit = RTMsgErrorExitFailure("Failed to set output device to '%s': %Rrc", pszDevId, rc); 2297 audioTestDriverStackDelete(&DrvStack); 2298 } 2299 else 2300 rcExit = RTMsgErrorExitFailure("Driver stack construction failed: %Rrc", rc); 2301 return rcExit; 2302 } 2303 2304 /** 2305 * Options for 'rec'. 2306 */ 2307 static const RTGETOPTDEF g_aCmdRecOptions[] = 2308 { 2309 { "--backend", 'b', RTGETOPT_REQ_STRING }, 2310 { "--channels", 'c', RTGETOPT_REQ_UINT8 }, 2311 { "--hz", 'f', RTGETOPT_REQ_UINT32 }, 2312 { "--frequency", 'f', RTGETOPT_REQ_UINT32 }, 2313 { "--sample-size", 'z', RTGETOPT_REQ_UINT8 }, 2314 { "--input-device", 'i', RTGETOPT_REQ_STRING }, 2315 { "--wav-channels", 'C', RTGETOPT_REQ_UINT8 }, 2316 { "--wav-hz", 'F', RTGETOPT_REQ_UINT32 }, 2317 { "--wav-frequency", 'F', RTGETOPT_REQ_UINT32 }, 2318 { "--wav-sample-size", 'Z', RTGETOPT_REQ_UINT8 }, 2319 { "--with-drv-audio", 'd', RTGETOPT_REQ_NOTHING }, 2320 { "--with-mixer", 'm', RTGETOPT_REQ_NOTHING }, 2321 { "--max-frames", 'r', RTGETOPT_REQ_UINT64 }, 2322 { "--max-sec", 's', RTGETOPT_REQ_UINT64 }, 2323 { "--max-seconds", 's', RTGETOPT_REQ_UINT64 }, 2324 { "--max-ms", 't', RTGETOPT_REQ_UINT64 }, 2325 { "--max-milliseconds", 't', RTGETOPT_REQ_UINT64 }, 2326 { "--max-ns", 'T', RTGETOPT_REQ_UINT64 }, 2327 { "--max-nanoseconds", 'T', RTGETOPT_REQ_UINT64 }, 2328 }; 2329 2330 /** The 'rec' command option help. */ 2331 static DECLCALLBACK(const char *) audioTestCmdRecHelp(PCRTGETOPTDEF pOpt) 2332 { 2333 switch (pOpt->iShort) 2334 { 2335 case 'b': return "The audio backend to use."; 2336 case 'c': return "Number of backend input channels"; 2337 case 'C': return "Number of wave-file channels"; 2338 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend."; 2339 case 'f': return "Input frequency (Hz)"; 2340 case 'F': return "Wave-file frequency (Hz)"; 2341 case 'z': return "Input sample size (bits)"; 2342 case 'Z': return "Wave-file sample size (bits)"; 2343 case 'm': return "Go via the mixer."; 2344 case 'i': return "The ID of the input device to use."; 2345 case 'r': return "Max recording duration in frames."; 2346 case 's': return "Max recording duration in seconds."; 2347 case 't': return "Max recording duration in milliseconds."; 2348 case 'T': return "Max recording duration in nanoseconds."; 2349 default: return NULL; 2350 } 2351 } 2352 2353 /** 2354 * The 'play' command handler. 2355 * 2356 * @returns Program exit code. 2357 * @param pGetState RTGetOpt state. 2358 */ 2359 static DECLCALLBACK(RTEXITCODE) audioTestCmdRecHandler(PRTGETOPTSTATE pGetState) 2360 { 2361 /* Option values: */ 2362 PCPDMDRVREG pDrvReg = g_aBackends[0].pDrvReg; 2363 uint32_t cMsBufferSize = UINT32_MAX; 2364 uint32_t cMsPreBuffer = UINT32_MAX; 2365 uint32_t cMsSchedulingHint = UINT32_MAX; 2366 const char *pszDevId = NULL; 2367 bool fWithDrvAudio = false; 2368 bool fWithMixer = false; 2369 uint8_t cbSample = 0; 2370 uint8_t cChannels = 0; 2371 uint32_t uHz = 0; 2372 uint8_t cbWaveSample = 0; 2373 uint8_t cWaveChannels = 0; 2374 uint32_t uWaveHz = 0; 2375 uint64_t cMaxFrames = UINT64_MAX; 2376 uint64_t cNsMaxDuration = UINT64_MAX; 2377 2378 /* Argument processing loop: */ 2379 int rc; 2380 RTGETOPTUNION ValueUnion; 2381 while ((rc = RTGetOpt(pGetState, &ValueUnion)) != 0) 2382 { 2383 switch (rc) 2384 { 2385 case 'b': 2386 pDrvReg = audioTestFindBackendOpt(ValueUnion.psz); 2387 if (pDrvReg == NULL) 2388 return RTEXITCODE_SYNTAX; 2389 break; 2390 2391 case 'c': 2392 cChannels = ValueUnion.u8; 2393 break; 2394 2395 case 'C': 2396 cWaveChannels = ValueUnion.u8; 2397 break; 2398 2399 case 'd': 2400 fWithDrvAudio = true; 2401 break; 2402 2403 case 'f': 2404 uHz = ValueUnion.u32; 2405 break; 2406 2407 case 'F': 2408 uWaveHz = ValueUnion.u32; 2409 break; 2410 2411 case 'i': 2412 pszDevId = ValueUnion.psz; 2413 break; 2414 2415 case 'm': 2416 fWithMixer = true; 2417 break; 2418 2419 case 'r': 2420 cMaxFrames = ValueUnion.u64; 2421 break; 2422 2423 case 's': 2424 cNsMaxDuration = ValueUnion.u64 >= UINT64_MAX / RT_NS_1SEC ? UINT64_MAX : ValueUnion.u64 * RT_NS_1SEC; 2425 break; 2426 2427 case 't': 2428 cNsMaxDuration = ValueUnion.u64 >= UINT64_MAX / RT_NS_1MS ? UINT64_MAX : ValueUnion.u64 * RT_NS_1MS; 2429 break; 2430 2431 case 'T': 2432 cNsMaxDuration = ValueUnion.u64; 2433 break; 2434 2435 case 'z': 2436 cbSample = ValueUnion.u8 / 8; 2437 break; 2438 2439 case 'Z': 2440 cbWaveSample = ValueUnion.u8 / 8; 2441 break; 2442 2443 case VINF_GETOPT_NOT_OPTION: 2444 { 2445 RTEXITCODE rcExit = audioTestRecOne(ValueUnion.psz, cWaveChannels, cbWaveSample, uWaveHz, 2446 pDrvReg, pszDevId, cMsBufferSize, cMsPreBuffer, cMsSchedulingHint, 2447 cChannels, cbSample, uHz, fWithDrvAudio, fWithMixer, 2448 cMaxFrames, cNsMaxDuration); 2449 if (rcExit != RTEXITCODE_SUCCESS) 2450 return rcExit; 2451 break; 2452 } 2453 2454 AUDIO_TEST_COMMON_OPTION_CASES(ValueUnion); 2455 2456 default: 2457 return RTGetOptPrintError(rc, &ValueUnion); 2458 } 2459 } 2460 return RTEXITCODE_SUCCESS; 2461 } 2462 2463 2464 /********************************************************************************************************************************* 2101 2465 * Command: selftest * 2102 2466 *********************************************************************************************************************************/ … … 2286 2650 2287 2651 /** 2652 * Ctrl-C signal handler. 2653 * 2654 * This just sets g_fTerminate and hope it will be noticed soon. It restores 2655 * the SIGINT action to default, so that a second Ctrl-C will have the normal 2656 * effect (just in case the code doesn't respond to g_fTerminate). 2657 */ 2658 static void audioTestSignalHandler(int iSig) RT_NOEXCEPT 2659 { 2660 Assert(iSig == SIGINT); RT_NOREF(iSig); 2661 RTPrintf("Ctrl-C!\n"); 2662 ASMAtomicWriteBool(&g_fTerminate, true); 2663 signal(SIGINT, SIG_DFL); 2664 } 2665 2666 2667 /** 2288 2668 * Commands. 2289 2669 */ … … 2324 2704 "Plays one or more wave files.", 2325 2705 g_aCmdPlayOptions, RT_ELEMENTS(g_aCmdPlayOptions), audioTestCmdPlayHelp, 2706 }, 2707 { 2708 "rec", audioTestCmdRecHandler, 2709 "Records audio to a wave file.", 2710 g_aCmdRecOptions, RT_ELEMENTS(g_aCmdRecOptions), audioTestCmdRecHelp, 2326 2711 }, 2327 2712 { … … 2430 2815 2431 2816 /* 2817 * Install a Ctrl-C signal handler. 2818 */ 2819 #ifdef RT_OS_WINDOWS 2820 signal(SIGINT, audioTestSignalHandler); 2821 #else 2822 struct sigaction sa; 2823 RT_ZERO(sa); 2824 sa.sa_handler = audioTestSignalHandler; 2825 sigaction(SIGINT, &sa, NULL); 2826 #endif 2827 2828 /* 2432 2829 * Process common options. 2433 2830 */ -
trunk/src/VBox/ValidationKit/utils/audio/vkatDriverStack.cpp
r89444 r89466 623 623 { 624 624 pStreamAt->Core.uMagic = PDMAUDIOSTREAM_MAGIC; 625 pStreamAt->Core.enmDir = PDMAUDIODIR_OUT;625 pStreamAt->Core.enmDir = pCfgReq->enmDir; 626 626 pStreamAt->Core.cbBackend = cbStream; 627 627 pStreamAt->Core.Props = pCfgReq->Props; … … 1044 1044 else 1045 1045 { 1046 PAUDIOTESTDRVSTACKSTREAM pStreamAt 1046 PAUDIOTESTDRVSTACKSTREAM pStreamAt = (PAUDIOTESTDRVSTACKSTREAM)pStream; 1047 1047 cbWritable = pDrvStack->pIHostAudio->pfnStreamGetWritable(pDrvStack->pIHostAudio, &pStreamAt->Backend); 1048 1048 } … … 1062 1062 rc = pDrvStack->pIAudioConnector->pfnStreamPlay(pDrvStack->pIAudioConnector, pStream, pvBuf, cbBuf, pcbPlayed); 1063 1063 if (RT_FAILURE(rc)) 1064 RTTestFailed(g_hTest, "pfnStreamPlay(,,,%#x ) failed: %Rrc", cbBuf, rc);1064 RTTestFailed(g_hTest, "pfnStreamPlay(,,,%#x,) failed: %Rrc", cbBuf, rc); 1065 1065 } 1066 1066 else … … 1069 1069 rc = pDrvStack->pIHostAudio->pfnStreamPlay(pDrvStack->pIHostAudio, &pStreamAt->Backend, pvBuf, cbBuf, pcbPlayed); 1070 1070 if (RT_FAILURE(rc)) 1071 RTTestFailed(g_hTest, "PDMIHOSTAUDIO::pfnStreamPlay(,,,%#x ) failed: %Rrc", cbBuf, rc);1071 RTTestFailed(g_hTest, "PDMIHOSTAUDIO::pfnStreamPlay(,,,%#x,) failed: %Rrc", cbBuf, rc); 1072 1072 } 1073 1073 return rc; 1074 } 1075 1076 1077 /** 1078 * Gets the number of bytes it's currently possible to write to the stream. 1079 */ 1080 uint32_t audioTestDriverStackStreamGetReadable(PAUDIOTESTDRVSTACK pDrvStack, PPDMAUDIOSTREAM pStream) 1081 { 1082 uint32_t cbReadable; 1083 if (pDrvStack->pIAudioConnector) 1084 cbReadable = pDrvStack->pIAudioConnector->pfnStreamGetReadable(pDrvStack->pIAudioConnector, pStream); 1085 else 1086 { 1087 PAUDIOTESTDRVSTACKSTREAM pStreamAt = (PAUDIOTESTDRVSTACKSTREAM)pStream; 1088 cbReadable = pDrvStack->pIHostAudio->pfnStreamGetReadable(pDrvStack->pIHostAudio, &pStreamAt->Backend); 1089 } 1090 return cbReadable; 1074 1091 } 1075 1092 … … 1086 1103 rc = pDrvStack->pIAudioConnector->pfnStreamCapture(pDrvStack->pIAudioConnector, pStream, pvBuf, cbBuf, pcbCaptured); 1087 1104 if (RT_FAILURE(rc)) 1088 RTTestFailed(g_hTest, "pfnStreamCapture(,,,%#x ) failed: %Rrc", cbBuf, rc);1105 RTTestFailed(g_hTest, "pfnStreamCapture(,,,%#x,) failed: %Rrc", cbBuf, rc); 1089 1106 } 1090 1107 else … … 1093 1110 rc = pDrvStack->pIHostAudio->pfnStreamCapture(pDrvStack->pIHostAudio, &pStreamAt->Backend, pvBuf, cbBuf, pcbCaptured); 1094 1111 if (RT_FAILURE(rc)) 1095 RTTestFailed(g_hTest, "PDMIHOSTAUDIO::pfnStreamCapture(,,,%#x ) failed: %Rrc", cbBuf, rc);1112 RTTestFailed(g_hTest, "PDMIHOSTAUDIO::pfnStreamCapture(,,,%#x,) failed: %Rrc", cbBuf, rc); 1096 1113 } 1097 1114 return rc; … … 1249 1266 1250 1267 /** 1268 * Same as audioTestDriverStackStreamEnable. 1269 */ 1270 int AudioTestMixStreamEnable(PAUDIOTESTDRVMIXSTREAM pMix) 1271 { 1272 return audioTestDriverStackStreamEnable(pMix->pDrvStack, pMix->pStream); 1273 } 1274 1275 1276 /** 1251 1277 * Same as audioTestDriverStackStreamDrain. 1252 1278 */ … … 1272 1298 } 1273 1299 1274 1275 /** 1276 * Same as audioTestDriverStackStreamEnable. 1277 */ 1278 int AudioTestMixStreamEnable(PAUDIOTESTDRVMIXSTREAM pMix) 1279 { 1280 return audioTestDriverStackStreamEnable(pMix->pDrvStack, pMix->pStream); 1300 /** 1301 * Same as audioTestDriverStackStreamDisable. 1302 */ 1303 int AudioTestMixStreamDisable(PAUDIOTESTDRVMIXSTREAM pMix) 1304 { 1305 return AudioTestDriverStackStreamDisable(pMix->pDrvStack, pMix->pStream); 1306 } 1307 1308 1309 /** 1310 * Same as audioTestDriverStackStreamIsOkay. 1311 */ 1312 bool AudioTestMixStreamIsOkay(PAUDIOTESTDRVMIXSTREAM pMix) 1313 { 1314 return audioTestDriverStackStreamIsOkay(pMix->pDrvStack, pMix->pStream); 1281 1315 } 1282 1316 … … 1299 1333 1300 1334 1301 /**1302 * Same as audioTestDriverStackStreamIsOkay.1303 */1304 bool AudioTestMixStreamIsOkay(PAUDIOTESTDRVMIXSTREAM pMix)1305 {1306 return audioTestDriverStackStreamIsOkay(pMix->pDrvStack, pMix->pStream);1307 }1308 1335 1309 1336 … … 1349 1376 } 1350 1377 1378 1379 /** 1380 * Same as audioTestDriverStackStreamGetReadable 1381 */ 1382 uint32_t AudioTestMixStreamGetReadable(PAUDIOTESTDRVMIXSTREAM pMix) 1383 { 1384 if (!pMix->fDoMixing) 1385 return audioTestDriverStackStreamGetReadable(pMix->pDrvStack, pMix->pStream); 1386 1387 audioTestMixStreamTransfer(pMix); 1388 uint32_t cbRet = AudioMixBufUsedBytes(&pMix->MixBuf); 1389 return cbRet; 1390 } 1391 1392 1393 1394 1395 /** 1396 * Same as audioTestDriverStackStreamCapture. 1397 */ 1398 int AudioTestMixStreamCapture(PAUDIOTESTDRVMIXSTREAM pMix, void *pvBuf, uint32_t cbBuf, uint32_t *pcbCaptured) 1399 { 1400 if (!pMix->fDoMixing) 1401 return audioTestDriverStackStreamCapture(pMix->pDrvStack, pMix->pStream, pvBuf, cbBuf, pcbCaptured); 1402 1403 *pcbCaptured = 0; 1404 1405 int rc = audioTestMixStreamTransfer(pMix); 1406 if (RT_FAILURE(rc)) 1407 return rc; 1408 1409 uint32_t const cbFrame = PDMAudioPropsFrameSize(&pMix->MixBuf.Props); 1410 while (cbBuf >= cbFrame) 1411 { 1412 uint32_t const cFrames = AudioMixBufUsed(&pMix->MixBuf); 1413 if (!cFrames) 1414 break; 1415 uint32_t cbToRead = PDMAudioPropsFramesToBytes(&pMix->MixBuf.Props, cFrames); 1416 cbToRead = RT_MIN(cbToRead, cbBuf); 1417 cbToRead = PDMAudioPropsFloorBytesToFrame(&pMix->MixBuf.Props, cbToRead); 1418 1419 uint32_t cFramesPeeked = 0; 1420 uint32_t cbPeeked = 0; 1421 AudioMixBufPeek(&pMix->MixBuf, 0 /*offSrcFrame*/, cFrames, &cFramesPeeked, &pMix->PeekState, pvBuf, cbToRead, &cbPeeked); 1422 Assert(cFramesPeeked == PDMAudioPropsBytesToFrames(&pMix->MixBuf.Props, cbPeeked)); 1423 AudioMixBufAdvance(&pMix->MixBuf, cFramesPeeked); 1424 1425 *pcbCaptured += cbToRead; 1426 cbBuf -= cbToRead; 1427 pvBuf = (uint8_t *)pvBuf + cbToRead; 1428 1429 rc = audioTestMixStreamTransfer(pMix); 1430 if (RT_FAILURE(rc)) 1431 return *pcbCaptured ? VINF_SUCCESS : rc; 1432 } 1433 1434 return VINF_SUCCESS; 1435 } 1436 -
trunk/src/VBox/ValidationKit/utils/audio/vkatInternal.h
r89439 r89466 130 130 int audioTestDriverStackStreamDrain(PAUDIOTESTDRVSTACK pDrvStack, PPDMAUDIOSTREAM pStream, bool fSync); 131 131 int audioTestDriverStackStreamEnable(PAUDIOTESTDRVSTACK pDrvStack, PPDMAUDIOSTREAM pStream); 132 int audioTestDriverStackStreamDisable(PAUDIOTESTDRVSTACK pDrvStack, PPDMAUDIOSTREAM pStream); 132 int AudioTestDriverStackStreamDisable(PAUDIOTESTDRVSTACK pDrvStack, PPDMAUDIOSTREAM pStream); 133 bool audioTestDriverStackStreamIsOkay(PAUDIOTESTDRVSTACK pDrvStack, PPDMAUDIOSTREAM pStream); 133 134 uint32_t audioTestDriverStackStreamGetWritable(PAUDIOTESTDRVSTACK pDrvStack, PPDMAUDIOSTREAM pStream); 134 bool audioTestDriverStackStreamIsOkay(PAUDIOTESTDRVSTACK pDrvStack, PPDMAUDIOSTREAM pStream);135 135 int audioTestDriverStackStreamPlay(PAUDIOTESTDRVSTACK pDrvStack, PPDMAUDIOSTREAM pStream, void const *pvBuf, 136 136 uint32_t cbBuf, uint32_t *pcbPlayed); 137 uint32_t audioTestDriverStackStreamGetReadable(PAUDIOTESTDRVSTACK pDrvStack, PPDMAUDIOSTREAM pStream); 137 138 int audioTestDriverStackStreamCapture(PAUDIOTESTDRVSTACK pDrvStack, PPDMAUDIOSTREAM pStream, 138 139 void *pvBuf, uint32_t cbBuf, uint32_t *pcbCaptured); … … 145 146 PCPDMAUDIOPCMPROPS pProps, uint32_t cMsBuffer); 146 147 void AudioTestMixStreamTerm(PAUDIOTESTDRVMIXSTREAM pMix); 148 int AudioTestMixStreamEnable(PAUDIOTESTDRVMIXSTREAM pMix); 147 149 int AudioTestMixStreamDrain(PAUDIOTESTDRVMIXSTREAM pMix, bool fSync); 148 int AudioTestMixStreamEnable(PAUDIOTESTDRVMIXSTREAM pMix); 150 int AudioTestMixStreamDisable(PAUDIOTESTDRVMIXSTREAM pMix); 151 bool AudioTestMixStreamIsOkay(PAUDIOTESTDRVMIXSTREAM pMix); 149 152 uint32_t AudioTestMixStreamGetWritable(PAUDIOTESTDRVMIXSTREAM pMix); 150 bool AudioTestMixStreamIsOkay(PAUDIOTESTDRVMIXSTREAM pMix);151 153 int AudioTestMixStreamPlay(PAUDIOTESTDRVMIXSTREAM pMix, void const *pvBuf, uint32_t cbBuf, uint32_t *pcbPlayed); 154 uint32_t AudioTestMixStreamGetReadable(PAUDIOTESTDRVMIXSTREAM pMix); 152 155 int AudioTestMixStreamCapture(PAUDIOTESTDRVMIXSTREAM pMix, void *pvBuf, uint32_t cbBuf, uint32_t *pcbCaptured); 153 156 /** @} */
Note:
See TracChangeset
for help on using the changeset viewer.