Changeset 89890 in vbox for trunk/src/VBox/ValidationKit
- Timestamp:
- Jun 24, 2021 3:56:05 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145348
- Location:
- trunk/src/VBox/ValidationKit/utils/audio
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp
r89850 r89890 61 61 * Internal Functions * 62 62 *********************************************************************************************************************************/ 63 static int audioTestCombineParms(PAUDIOTESTPARMS pBaseParms, PAUDIOTESTPARMS pOverrideParms);64 63 static int audioVerifyOne(const char *pszPathSetA, const char *pszPathSetB); 65 64 … … 230 229 231 230 232 /**233 * Overrides audio test base parameters with another set.234 *235 * @returns VBox status code.236 * @param pBaseParms Base parameters to override.237 * @param pOverrideParms Override parameters to use for overriding the base parameters.238 *239 * @note Overriding a parameter depends on its type / default values.240 */241 static int audioTestCombineParms(PAUDIOTESTPARMS pBaseParms, PAUDIOTESTPARMS pOverrideParms)242 {243 RT_NOREF(pBaseParms, pOverrideParms);244 245 /** @todo Implement parameter overriding. */246 return VERR_NOT_IMPLEMENTED;247 }248 249 250 231 /********************************************************************************************************************************* 251 232 * Test callbacks * … … 257 238 static DECLCALLBACK(int) audioTestPlayToneSetup(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, PAUDIOTESTPARMS pTstParmsAcq, void **ppvCtx) 258 239 { 259 RT_NOREF(pTstEnv, pTstDesc, ppvCtx); 240 RT_NOREF(pTstDesc, ppvCtx); 241 242 int rc; 243 244 if (strlen(pTstEnv->szDev)) 245 { 246 rc = audioTestDriverStackSetDevice(&pTstEnv->DrvStack, PDMAUDIODIR_OUT, pTstEnv->szDev); 247 if (RT_FAILURE(rc)) 248 return rc; 249 } 260 250 261 251 pTstParmsAcq->enmType = AUDIOTESTTYPE_TESTTONE_PLAY; 262 263 PDMAudioPropsInit(&pTstParmsAcq->Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */); 264 252 pTstParmsAcq->Props = pTstEnv->Props; 265 253 pTstParmsAcq->enmDir = PDMAUDIODIR_OUT; 266 254 #ifdef DEBUG 267 pTstParmsAcq->cIterations = 2;255 pTstParmsAcq->cIterations = 1; 268 256 #else 269 257 pTstParmsAcq->cIterations = RTRandU32Ex(1, 10); … … 271 259 pTstParmsAcq->idxCurrent = 0; 272 260 273 return VINF_SUCCESS; 261 PAUDIOTESTTONEPARMS pToneParms = &pTstParmsAcq->TestTone; 262 263 pToneParms->Props = pTstParmsAcq->Props; 264 pToneParms->dbFreqHz = AudioTestToneGetRandomFreq(); 265 pToneParms->msPrequel = 0; /** @todo Implement analyzing this first! */ 266 #ifdef DEBUG_andy 267 pToneParms->msDuration = 2000; 268 #else 269 pToneParms->msDuration = RTRandU32Ex(0, RT_MS_10SEC); /** @todo Probably a bit too long, but let's see. */ 270 #endif 271 pToneParms->msSequel = 0; /** @todo Implement analyzing this first! */ 272 pToneParms->uVolumePercent = 100; /** @todo Implement analyzing this first! */ 273 274 return rc; 274 275 } 275 276 … … 285 286 for (uint32_t i = 0; i < pTstParms->cIterations; i++) 286 287 { 287 AudioTestToneParamsInitRandom(&pTstParms->TestTone, &pTstParms->Props); 288 288 /* 289 * 1. Arm the (host) ValKit ATS with the recording parameters. 290 */ 289 291 PAUDIOTESTTONEPARMS const pToneParms = &pTstParms->TestTone; 290 292 rc = AudioTestSvcClientToneRecord(&pTstEnv->u.Host.AtsClValKit, pToneParms); 291 293 if (RT_SUCCESS(rc)) 294 { 295 /* 296 * 2. Tell the guest ATS to start playback. 297 */ 292 298 rc = AudioTestSvcClientTonePlay(&pTstEnv->u.Host.AtsClGuest, pToneParms); 299 } 293 300 294 301 if (RT_FAILURE(rc)) … … 314 321 static DECLCALLBACK(int) audioTestRecordToneSetup(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, PAUDIOTESTPARMS pTstParmsAcq, void **ppvCtx) 315 322 { 316 RT_NOREF(pTstEnv, pTstDesc, ppvCtx); 323 RT_NOREF(pTstDesc, ppvCtx); 324 325 int rc; 326 327 if (strlen(pTstEnv->szDev)) 328 { 329 rc = audioTestDriverStackSetDevice(&pTstEnv->DrvStack, PDMAUDIODIR_IN, pTstEnv->szDev); 330 if (RT_FAILURE(rc)) 331 return rc; 332 } 317 333 318 334 pTstParmsAcq->enmType = AUDIOTESTTYPE_TESTTONE_RECORD; 319 320 PDMAudioPropsInit(&pTstParmsAcq->Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */); 321 335 pTstParmsAcq->Props = pTstEnv->Props; 322 336 pTstParmsAcq->enmDir = PDMAUDIODIR_IN; 323 337 #ifdef DEBUG 324 pTstParmsAcq->cIterations = 2;338 pTstParmsAcq->cIterations = 1; 325 339 #else 326 340 pTstParmsAcq->cIterations = RTRandU32Ex(1, 10); … … 328 342 pTstParmsAcq->idxCurrent = 0; 329 343 330 return VINF_SUCCESS;344 return rc; 331 345 } 332 346 … … 349 363 #endif 350 364 /* 351 * 1. Arm the ValKit ATS with the recordingparameters.365 * 1. Arm the (host) ValKit ATS with the playback parameters. 352 366 */ 353 367 rc = AudioTestSvcClientTonePlay(&pTstEnv->u.Host.AtsClValKit, &pTstParms->TestTone); … … 399 413 * @param pTstDesc Test to run. 400 414 * @param uSeq Test sequence # in case there are more tests. 401 * @param pOverrideParms Test parameters for overriding the actual test parameters. Optional. 402 */ 403 static int audioTestOne(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, 404 unsigned uSeq, PAUDIOTESTPARMS pOverrideParms) 415 */ 416 static int audioTestOne(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, unsigned uSeq) 405 417 { 406 418 RT_NOREF(uSeq); … … 431 443 } 432 444 433 audioTestCombineParms(&TstParms, pOverrideParms);434 435 445 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test #%u: %RU32 iterations\n", uSeq, TstParms.cIterations); 436 437 if (TstParms.Dev.pszName && strlen(TstParms.Dev.pszName)) /** @todo Refine this check. Use pszId for starters! */438 rc = audioTestDeviceOpen(&TstParms.Dev);439 446 440 447 AssertPtr(pTstDesc->pfnExec); … … 455 462 } 456 463 457 rc = audioTestDeviceClose(&TstParms.Dev);458 459 464 audioTestParmsDestroy(&TstParms); 460 465 … … 467 472 * @returns VBox status code. 468 473 * @param pTstEnv Test environment to use for running all tests. 469 * @param pOverrideParms Test parameters for (some / all) specific test parameters. Optional. 470 */ 471 int audioTestWorker(PAUDIOTESTENV pTstEnv, PAUDIOTESTPARMS pOverrideParms) 474 */ 475 int audioTestWorker(PAUDIOTESTENV pTstEnv) 472 476 { 473 477 int rc = VINF_SUCCESS; … … 501 505 for (unsigned i = 0; i < RT_ELEMENTS(g_aTests); i++) 502 506 { 503 int rc2 = audioTestOne(pTstEnv, &g_aTests[i], uSeq , pOverrideParms);507 int rc2 = audioTestOne(pTstEnv, &g_aTests[i], uSeq); 504 508 if (RT_SUCCESS(rc)) 505 509 rc = rc2; … … 631 635 RT_ZERO(TstEnv); 632 636 633 AUDIOTESTPARMS TstCust;634 audioTestParmsInit(&TstCust);635 636 637 const char *pszDevice = NULL; /* Custom device to use. Can be NULL if not being used. */ 637 638 const char *pszTag = NULL; /* Custom tag to use. Can be NULL if not being used. */ … … 750 751 751 752 case VKAT_TEST_OPT_VOL: 752 Tst Cust.TestTone.uVolumePercent = ValueUnion.u8;753 TstEnv.uVolumePercent = ValueUnion.u8; 753 754 break; 754 755 … … 766 767 767 768 /* Initialize the custom test parameters with sensible defaults if nothing else is given. */ 768 PDMAudioPropsInit(&Tst Cust.TestTone.Props,769 PDMAudioPropsInit(&TstEnv.Props, 769 770 cPcmSampleBit ? cPcmSampleBit / 8 : 2 /* 16-bit */, fPcmSigned, cPcmChannels ? cPcmChannels : 2, 770 771 uPcmHz ? uPcmHz : 44100); … … 784 785 pszGuestTcpAddr, uGuestTcpPort); 785 786 if (RT_SUCCESS(rc)) 786 { 787 audioTestWorker(&TstEnv, &TstCust); 788 audioTestEnvDestroy(&TstEnv); 789 } 790 791 audioTestParmsDestroy(&TstCust); 787 rc = audioTestWorker(&TstEnv); 788 789 audioTestEnvDestroy(&TstEnv); 792 790 793 791 if (RT_FAILURE(rc)) /* Let us know that something went wrong in case we forgot to mention it. */ -
trunk/src/VBox/ValidationKit/utils/audio/vkatCmdSelfTest.cpp
r89834 r89890 56 56 PSELFTESTCTX pCtx = (PSELFTESTCTX)pvUser; 57 57 58 AUDIOTESTPARMS TstCust; 59 audioTestParmsInit(&TstCust); 60 61 PAUDIOTESTENV pTstEnv = &pCtx->Guest.TstEnv; 58 PAUDIOTESTENV pTstEnvGst = &pCtx->Guest.TstEnv; 62 59 63 60 /* Flag the environment for self test mode. */ 64 pTstEnv ->fSelftest = true;61 pTstEnvGst->fSelftest = true; 65 62 66 63 /* Generate tag for guest side. */ 67 int rc = RTStrCopy(pTstEnv ->szTag, sizeof(pTstEnv->szTag), pCtx->szTag);64 int rc = RTStrCopy(pTstEnvGst->szTag, sizeof(pTstEnvGst->szTag), pCtx->szTag); 68 65 AssertRCReturn(rc, rc); 69 66 70 rc = AudioTestPathCreateTemp(pTstEnv ->szPathTemp, sizeof(pTstEnv->szPathTemp), "selftest-guest");67 rc = AudioTestPathCreateTemp(pTstEnvGst->szPathTemp, sizeof(pTstEnvGst->szPathTemp), "selftest-guest"); 71 68 AssertRCReturn(rc, rc); 72 69 73 rc = AudioTestPathCreateTemp(pTstEnv ->szPathOut, sizeof(pTstEnv->szPathOut), "selftest-out");70 rc = AudioTestPathCreateTemp(pTstEnvGst->szPathOut, sizeof(pTstEnvGst->szPathOut), "selftest-out"); 74 71 AssertRCReturn(rc, rc); 75 72 76 pTstEnv ->enmMode = AUDIOTESTMODE_GUEST;73 pTstEnvGst->enmMode = AUDIOTESTMODE_GUEST; 77 74 78 75 /** @todo Make this customizable. */ 79 PDMAudioPropsInit(& TstCust.TestTone.Props,76 PDMAudioPropsInit(&pTstEnvGst->Props, 80 77 2 /* 16-bit */, true /* fSigned */, 2 /* cChannels */, 44100 /* uHz */); 81 78 82 rc = audioTestEnvInit(pTstEnv , pTstEnv->DrvStack.pDrvReg, pCtx->fWithDrvAudio,79 rc = audioTestEnvInit(pTstEnvGst, pTstEnvGst->DrvStack.pDrvReg, pCtx->fWithDrvAudio, 83 80 pCtx->Host.szValKitAtsAddr, pCtx->Host.uValKitAtsPort, 84 81 pCtx->Guest.szAtsAddr, pCtx->Guest.uAtsPort); … … 87 84 RTThreadUserSignal(hThread); 88 85 89 audioTestWorker(pTstEnv, &TstCust); 90 audioTestEnvDestroy(pTstEnv); 91 } 92 93 audioTestParmsDestroy(&TstCust); 86 audioTestWorker(pTstEnvGst); 87 audioTestEnvDestroy(pTstEnvGst); 88 } 94 89 95 90 return rc; … … 118 113 */ 119 114 120 AUDIOTESTPARMS TstCust;121 audioTestParmsInit(&TstCust);122 123 115 /* Generate a common tag for guest and host side. */ 124 116 int rc = AudioTestGenTag(pCtx->szTag, sizeof(pCtx->szTag)); 125 117 AssertRCReturn(rc, RTEXITCODE_FAILURE); 126 118 127 PAUDIOTESTENV pTstEnv = &pCtx->Host.TstEnv;119 PAUDIOTESTENV pTstEnvHst = &pCtx->Host.TstEnv; 128 120 129 121 /* Flag the environment for self test mode. */ 130 pTstEnv ->fSelftest = true;122 pTstEnvHst->fSelftest = true; 131 123 132 124 /* Generate tag for host side. */ 133 rc = RTStrCopy(pTstEnv ->szTag, sizeof(pTstEnv->szTag), pCtx->szTag);125 rc = RTStrCopy(pTstEnvHst->szTag, sizeof(pTstEnvHst->szTag), pCtx->szTag); 134 126 AssertRCReturn(rc, RTEXITCODE_FAILURE); 135 127 136 rc = AudioTestPathCreateTemp(pTstEnv ->szPathTemp, sizeof(pTstEnv->szPathTemp), "selftest-tmp");128 rc = AudioTestPathCreateTemp(pTstEnvHst->szPathTemp, sizeof(pTstEnvHst->szPathTemp), "selftest-tmp"); 137 129 AssertRCReturn(rc, RTEXITCODE_FAILURE); 138 130 139 rc = AudioTestPathCreateTemp(pTstEnv ->szPathOut, sizeof(pTstEnv->szPathOut), "selftest-out");131 rc = AudioTestPathCreateTemp(pTstEnvHst->szPathOut, sizeof(pTstEnvHst->szPathOut), "selftest-out"); 140 132 AssertRCReturn(rc, RTEXITCODE_FAILURE); 133 134 /* Initialize the PCM properties to some sane values. */ 135 PDMAudioPropsInit(&pTstEnvHst->Props, 136 2 /* 16-bit */, true /* fPcmSigned */, 2 /* cPcmChannels */, 44100 /* uPcmHz */); 141 137 142 138 /* … … 161 157 * Steps 2 + 3. 162 158 */ 163 pTstEnv ->enmMode = AUDIOTESTMODE_HOST;164 165 rc = audioTestEnvInit(pTstEnv , &g_DrvHostValidationKitAudio, true /* fWithDrvAudio */,159 pTstEnvHst->enmMode = AUDIOTESTMODE_HOST; 160 161 rc = audioTestEnvInit(pTstEnvHst, &g_DrvHostValidationKitAudio, true /* fWithDrvAudio */, 166 162 pCtx->Host.szValKitAtsAddr, pCtx->Host.uValKitAtsPort, 167 163 pCtx->Host.szGuestAtsAddr, pCtx->Host.uGuestAtsPort); 168 164 if (RT_SUCCESS(rc)) 169 165 { 170 rc = audioTestWorker(pTstEnv , &TstCust);166 rc = audioTestWorker(pTstEnvHst); 171 167 if (RT_SUCCESS(rc)) 172 168 { … … 174 170 } 175 171 176 audioTestEnvDestroy(pTstEnv );172 audioTestEnvDestroy(pTstEnvHst); 177 173 } 178 174 } 179 180 audioTestParmsDestroy(&TstCust);181 175 182 176 /* -
trunk/src/VBox/ValidationKit/utils/audio/vkatCommon.cpp
r89837 r89890 68 68 * Internal Functions * 69 69 *********************************************************************************************************************************/ 70 static int audioTestCreateStreamDefaultIn(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps); 71 static int audioTestCreateStreamDefaultOut(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps); 70 static int audioTestStreamInit(PAUDIOTESTDRVSTACK pDrvStack, PAUDIOTESTSTREAM pStream, PDMAUDIODIR enmDir, PCPDMAUDIOPCMPROPS pProps, bool fWithMixer, uint32_t cMsBufferSize, uint32_t cMsPreBuffer, uint32_t cMsSchedulingHint); 72 71 static int audioTestStreamDestroy(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream); 73 72 static int audioTestDevicesEnumerateAndCheck(PAUDIOTESTENV pTstEnv, const char *pszDev, PPDMAUDIOHOSTDEV *ppDev); … … 144 143 } 145 144 146 /** 147 * Opens an audio device. 148 * 149 * @returns VBox status code. 150 * @param pDev Audio device to open. 151 */ 152 int audioTestDeviceOpen(PPDMAUDIOHOSTDEV pDev) 153 { 154 int rc = VINF_SUCCESS; 155 156 RTTestSubF(g_hTest, "Opening audio device '%s' ...", pDev->pszName); 157 158 /** @todo Detect + open device here. */ 159 160 RTTestSubDone(g_hTest); 161 162 return rc; 163 } 164 165 /** 166 * Closes an audio device. 167 * 168 * @returns VBox status code. 169 * @param pDev Audio device to close. 170 */ 171 int audioTestDeviceClose(PPDMAUDIOHOSTDEV pDev) 172 { 173 int rc = VINF_SUCCESS; 174 175 RTTestSubF(g_hTest, "Closing audio device '%s' ...", pDev->pszName); 176 177 /** @todo Close device here. */ 178 179 RTTestSubDone(g_hTest); 145 static int audioTestStreamInit(PAUDIOTESTDRVSTACK pDrvStack, PAUDIOTESTSTREAM pStream, 146 PDMAUDIODIR enmDir, PCPDMAUDIOPCMPROPS pProps, bool fWithMixer, 147 uint32_t cMsBufferSize, uint32_t cMsPreBuffer, uint32_t cMsSchedulingHint) 148 { 149 int rc; 150 151 if (enmDir == PDMAUDIODIR_IN) 152 rc = audioTestDriverStackStreamCreateInput(pDrvStack, pProps, cMsBufferSize, 153 cMsPreBuffer, cMsSchedulingHint, &pStream->pStream, &pStream->Cfg); 154 else if (enmDir == PDMAUDIODIR_OUT) 155 rc = audioTestDriverStackStreamCreateOutput(pDrvStack, pProps, cMsBufferSize, 156 cMsPreBuffer, cMsSchedulingHint, &pStream->pStream, &pStream->Cfg); 157 else 158 rc = VERR_NOT_SUPPORTED; 159 160 if (RT_SUCCESS(rc)) 161 { 162 if (!pDrvStack->pIAudioConnector) 163 { 164 pStream->pBackend = &((PAUDIOTESTDRVSTACKSTREAM)pStream->pStream)->Backend; 165 } 166 else 167 pStream->pBackend = NULL; 168 169 /* 170 * Automatically enable the mixer if the PCM properties don't match. 171 */ 172 if ( !fWithMixer 173 && !PDMAudioPropsAreEqual(pProps, &pStream->Cfg.Props)) 174 { 175 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Enabling stream mixer\n"); 176 fWithMixer = true; 177 } 178 179 rc = AudioTestMixStreamInit(&pStream->Mix, pDrvStack, pStream->pStream, 180 fWithMixer ? pProps : NULL, 100 /* ms */); /** @todo Configure mixer buffer? */ 181 } 182 183 if (RT_FAILURE(rc)) 184 RTTestFailed(g_hTest, "Initializing %s stream failed with %Rrc", enmDir == PDMAUDIODIR_IN ? "input" : "output", rc); 180 185 181 186 return rc; … … 201 206 } 202 207 203 return rc; 204 } 205 206 /** 207 * Creates an audio default input (recording) test stream. 208 * Convenience function. 209 * 210 * @returns VBox status code. 211 * @param pTstEnv Test environment to use for creating the stream. 212 * @param pStream Audio stream to create. 213 * @param pProps PCM properties to use for creation. 214 */ 215 static int audioTestCreateStreamDefaultIn(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps) 216 { 217 pStream->pBackend = NULL; 218 int rc = audioTestDriverStackStreamCreateInput(&pTstEnv->DrvStack, pProps, pTstEnv->cMsBufferSize, pTstEnv->cMsPreBuffer, 219 pTstEnv->cMsSchedulingHint, &pStream->pStream, &pStream->Cfg); 220 if (RT_SUCCESS(rc) && !pTstEnv->DrvStack.pIAudioConnector) 221 pStream->pBackend = &((PAUDIOTESTDRVSTACKSTREAM)pStream->pStream)->Backend; 222 return rc; 223 } 224 225 /** 226 * Creates an audio default output (playback) test stream. 227 * Convenience function. 228 * 229 * @returns VBox status code. 230 * @param pTstEnv Test environment to use for creating the stream. 231 * @param pStream Audio stream to create. 232 * @param pProps PCM properties to use for creation. 233 */ 234 static int audioTestCreateStreamDefaultOut(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps) 235 { 236 pStream->pBackend = NULL; 237 int rc = audioTestDriverStackStreamCreateOutput(&pTstEnv->DrvStack, pProps, pTstEnv->cMsBufferSize, pTstEnv->cMsPreBuffer, 238 pTstEnv->cMsSchedulingHint, &pStream->pStream, &pStream->Cfg); 239 if (RT_SUCCESS(rc) && !pTstEnv->DrvStack.pIAudioConnector) 240 pStream->pBackend = &((PAUDIOTESTDRVSTACKSTREAM)pStream->pStream)->Backend; 208 AudioTestMixStreamTerm(&pStream->Mix); 209 241 210 return rc; 242 211 } … … 246 215 * Test Primitives * 247 216 *********************************************************************************************************************************/ 217 218 /** 219 * Returns a random scheduling hint (in ms). 220 */ 221 DECLINLINE(uint32_t) audioTestEnvGetRandomSchedulingHint(void) 222 { 223 static const unsigned s_aSchedulingHintsMs[] = 224 { 225 10, 226 25, 227 50, 228 100, 229 200, 230 250 231 }; 232 233 return s_aSchedulingHintsMs[RTRandU32Ex(0, RT_ELEMENTS(s_aSchedulingHintsMs) - 1)]; 234 } 248 235 249 236 /** … … 260 247 { 261 248 AUDIOTESTTONE TstTone; 262 AudioTestToneInit(&TstTone, &p Parms->Props, pParms->dbFreqHz);249 AudioTestToneInit(&TstTone, &pStream->Cfg.Props, pParms->dbFreqHz); 263 250 264 251 const char *pcszPathOut = pTstEnv->Set.szPathAbs; 265 252 266 253 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Playing test tone (tone frequency is %RU16Hz, %RU32ms)\n", (uint16_t)pParms->dbFreqHz, pParms->msDuration); 267 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Writing to '%s'\n", pcszPathOut); 254 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Using %RU32ms stream scheduling hint\n", pStream->Cfg.Device.cMsSchedulingHint); 255 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Writing to '%s'\n", pcszPathOut); 268 256 269 257 /** @todo Use .WAV here? */ … … 272 260 AssertRCReturn(rc, rc); 273 261 262 rc = AudioTestMixStreamEnable(&pStream->Mix); 263 if ( RT_SUCCESS(rc) 264 && AudioTestMixStreamIsOkay(&pStream->Mix)) 265 { 266 uint8_t abBuf[_4K]; 267 268 uint32_t cbToPlayTotal = PDMAudioPropsMilliToBytes(&pStream->Cfg.Props, pParms->msDuration); 269 AssertStmt(cbToPlayTotal, rc = VERR_INVALID_PARAMETER); 270 271 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Playing %RU32 bytes total\n", cbToPlayTotal); 272 273 AudioTestSetObjAddMetadataStr(pObj, "stream_to_play_bytes=%RU32\n", cbToPlayTotal); 274 AudioTestSetObjAddMetadataStr(pObj, "stream_period_size_frames=%RU32\n", pStream->Cfg.Backend.cFramesPeriod); 275 AudioTestSetObjAddMetadataStr(pObj, "stream_buffer_size_frames=%RU32\n", pStream->Cfg.Backend.cFramesBufferSize); 276 AudioTestSetObjAddMetadataStr(pObj, "stream_prebuf_size_frames=%RU32\n", pStream->Cfg.Backend.cFramesPreBuffering); 277 /* Note: This mostly is provided by backend (e.g. PulseAudio / ALSA / ++) and 278 * has nothing to do with the device emulation scheduling hint. */ 279 AudioTestSetObjAddMetadataStr(pObj, "device_scheduling_hint_ms=%RU32\n", pStream->Cfg.Device.cMsSchedulingHint); 280 281 while (cbToPlayTotal) 282 { 283 uint32_t cbPlayed = 0; 284 uint32_t const cbCanWrite = AudioTestMixStreamGetWritable(&pStream->Mix); 285 if (cbCanWrite) 286 { 287 uint32_t const cbToGenerate = RT_MIN(RT_MIN(cbToPlayTotal, sizeof(abBuf)), cbCanWrite); 288 uint32_t cbToPlay; 289 rc = AudioTestToneGenerate(&TstTone, abBuf, cbToGenerate, &cbToPlay); 290 if (RT_SUCCESS(rc)) 291 { 292 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Playing %RU32 bytes ...\n", cbToPlay); 293 294 /* Write stuff to disk before trying to play it. Help analysis later. */ 295 rc = AudioTestSetObjWrite(pObj, abBuf, cbToPlay); 296 if (RT_SUCCESS(rc)) 297 rc = AudioTestMixStreamPlay(&pStream->Mix, abBuf, cbToPlay, &cbPlayed); 298 } 299 300 if (RT_FAILURE(rc)) 301 break; 302 } 303 else if (AudioTestMixStreamIsOkay(&pStream->Mix)) 304 RTThreadSleep(RT_MIN(RT_MAX(1, pStream->Cfg.Device.cMsSchedulingHint), 256)); 305 else 306 AssertFailedBreakStmt(rc = VERR_AUDIO_STREAM_NOT_READY); 307 308 Assert(cbToPlayTotal >= cbPlayed); 309 cbToPlayTotal -= cbPlayed; 310 } 311 312 if (cbToPlayTotal != 0) 313 RTTestFailed(g_hTest, "Playback ended unexpectedly (%RU32 bytes left)\n", cbToPlayTotal); 314 } 315 else 316 rc = VERR_AUDIO_STREAM_NOT_READY; 317 318 int rc2 = AudioTestSetObjClose(pObj); 319 if (RT_SUCCESS(rc)) 320 rc = rc2; 321 322 if (RT_FAILURE(rc)) 323 RTTestFailed(g_hTest, "Playing tone failed with %Rrc\n", rc); 324 325 return rc; 326 } 327 328 /** 329 * Records a test tone from a specific audio test stream. 330 * 331 * @returns VBox status code. 332 * @param pTstEnv Test environment to use for running the test. 333 * @param pStream Stream to use for recording the tone. 334 * @param pParms Tone parameters to use. 335 * 336 * @note Blocking function. 337 */ 338 static int audioTestRecordTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms) 339 { 340 const char *pcszPathOut = pTstEnv->Set.szPathAbs; 341 342 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Recording test tone (for %RU32ms)\n", pParms->msDuration); 343 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Writing to '%s'\n", pcszPathOut); 344 345 /** @todo Use .WAV here? */ 346 PAUDIOTESTOBJ pObj; 347 int rc = AudioTestSetObjCreateAndRegister(&pTstEnv->Set, "guest-tone-rec.pcm", &pObj); 348 AssertRCReturn(rc, rc); 349 274 350 if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream)) 275 351 { 276 uint32_t cbBuf;277 uint8_t abBuf[_4K];278 279 352 const uint32_t cbPerSched = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint); 280 353 AssertStmt(cbPerSched, rc = VERR_INVALID_PARAMETER); 281 uint32_t cbTo Write= PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration);282 AssertStmt(cbTo Write,rc = VERR_INVALID_PARAMETER);354 uint32_t cbToRead = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration); 355 AssertStmt(cbToRead, rc = VERR_INVALID_PARAMETER); 283 356 284 357 if (RT_SUCCESS(rc)) … … 288 361 AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint); 289 362 290 while (cbToWrite)291 {292 uint32_t cbWritten = 0;293 uint32_t cbToGenerate = RT_MIN(cbToWrite, RT_MIN(cbPerSched, sizeof(abBuf)));294 Assert(cbToGenerate);295 296 rc = AudioTestToneGenerate(&TstTone, abBuf, cbToGenerate, &cbBuf);297 if (RT_SUCCESS(rc))298 {299 /* Write stuff to disk before trying to play it. Help analysis later. */300 rc = AudioTestSetObjWrite(pObj, abBuf, cbBuf);301 if (RT_SUCCESS(rc))302 rc = audioTestDriverStackStreamPlay(&pTstEnv->DrvStack, pStream->pStream,303 abBuf, cbBuf, &cbWritten);304 }305 306 if (RT_FAILURE(rc))307 break;308 309 RTThreadSleep(pTstEnv->cMsSchedulingHint);310 311 Assert(cbToWrite >= cbWritten);312 cbToWrite -= cbWritten;313 }314 }315 }316 else317 rc = VERR_AUDIO_STREAM_NOT_READY;318 319 int rc2 = AudioTestSetObjClose(pObj);320 if (RT_SUCCESS(rc))321 rc = rc2;322 323 if (RT_FAILURE(rc))324 RTTestFailed(g_hTest, "Playing tone done failed with %Rrc\n", rc);325 326 return rc;327 }328 329 /**330 * Records a test tone from a specific audio test stream.331 *332 * @returns VBox status code.333 * @param pTstEnv Test environment to use for running the test.334 * @param pStream Stream to use for recording the tone.335 * @param pParms Tone parameters to use.336 *337 * @note Blocking function.338 */339 static int audioTestRecordTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms)340 {341 const char *pcszPathOut = pTstEnv->Set.szPathAbs;342 343 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Recording test tone (for %RU32ms)\n", pParms->msDuration);344 RTTestPrintf(g_hTest, RTTESTLVL_DEBUG, "Writing to '%s'\n", pcszPathOut);345 346 /** @todo Use .WAV here? */347 PAUDIOTESTOBJ pObj;348 int rc = AudioTestSetObjCreateAndRegister(&pTstEnv->Set, "guest-tone-rec.pcm", &pObj);349 AssertRCReturn(rc, rc);350 351 if (audioTestDriverStackStreamIsOkay(&pTstEnv->DrvStack, pStream->pStream))352 {353 const uint32_t cbPerSched = PDMAudioPropsMilliToBytes(&pParms->Props, pTstEnv->cMsSchedulingHint);354 AssertStmt(cbPerSched, rc = VERR_INVALID_PARAMETER);355 uint32_t cbToRead = PDMAudioPropsMilliToBytes(&pParms->Props, pParms->msDuration);356 AssertStmt(cbToRead, rc = VERR_INVALID_PARAMETER);357 358 if (RT_SUCCESS(rc))359 {360 AudioTestSetObjAddMetadataStr(pObj, "buffer_size_ms=%RU32\n", pTstEnv->cMsBufferSize);361 AudioTestSetObjAddMetadataStr(pObj, "prebuf_size_ms=%RU32\n", pTstEnv->cMsPreBuffer);362 AudioTestSetObjAddMetadataStr(pObj, "scheduling_hint_ms=%RU32\n", pTstEnv->cMsSchedulingHint);363 364 363 uint8_t abBuf[_4K]; 365 364 … … 444 443 const PAUDIOTESTSTREAM pTstStream = &pTstEnv->aStreams[0]; /** @todo Make this dynamic. */ 445 444 446 int rc = audioTestCreateStreamDefaultOut(pTstEnv, pTstStream, &pToneParms->Props); 445 int rc = audioTestStreamInit(&pTstEnv->DrvStack, pTstStream, PDMAUDIODIR_OUT, &pTstEnv->Props, false /* fWithMixer */, 446 pTstEnv->cMsBufferSize, pTstEnv->cMsPreBuffer, pTstEnv->cMsSchedulingHint); 447 447 if (RT_SUCCESS(rc)) 448 448 { … … 484 484 const PAUDIOTESTSTREAM pTstStream = &pTstEnv->aStreams[0]; /** @todo Make this dynamic. */ 485 485 486 int rc = audioTestCreateStreamDefaultIn(pTstEnv, pTstStream, &pToneParms->Props); 486 int rc = audioTestStreamInit(&pTstEnv->DrvStack, pTstStream, PDMAUDIODIR_IN, &pTstEnv->Props, false /* fWithMixer */, 487 pTstEnv->cMsBufferSize, pTstEnv->cMsPreBuffer, pTstEnv->cMsSchedulingHint); 487 488 if (RT_SUCCESS(rc)) 488 489 { … … 666 667 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Temp directory is '%s'\n", pTstEnv->szPathTemp); 667 668 669 if (!pTstEnv->cMsBufferSize) 670 pTstEnv->cMsBufferSize = UINT32_MAX; 671 if (!pTstEnv->cMsPreBuffer) 672 pTstEnv->cMsPreBuffer = UINT32_MAX; 673 if (!pTstEnv->cMsSchedulingHint) 674 pTstEnv->cMsSchedulingHint = UINT32_MAX; 675 668 676 PDMAudioHostEnumInit(&pTstEnv->DevEnum); 669 670 pTstEnv->cMsBufferSize = 300; /* ms */ /** @todo Randomize this also? */671 pTstEnv->cMsPreBuffer = 150; /* ms */ /** @todo Ditto. */672 pTstEnv->cMsSchedulingHint = RTRandU32Ex(10, 80); /* Choose a random scheduling (in ms). */673 677 674 678 bool fUseDriverStack = false; /* Whether to init + use the audio driver stack or not. */ … … 691 695 692 696 PPDMAUDIOHOSTDEV pDev; 693 rc = audioTestDevicesEnumerateAndCheck(pTstEnv, NULL /* pszDevice */, &pDev); /** @todo Implement device checking. */697 rc = audioTestDevicesEnumerateAndCheck(pTstEnv, pTstEnv->szDev, &pDev); 694 698 if (RT_FAILURE(rc)) 695 699 return rc; -
trunk/src/VBox/ValidationKit/utils/audio/vkatInternal.h
r89837 r89890 165 165 /** The stream config. */ 166 166 PDMAUDIOSTREAMCFG Cfg; 167 /** Associated mixing stream. Optional. */ 168 AUDIOTESTDRVMIXSTREAM Mix; 167 169 } AUDIOTESTSTREAM; 168 170 /** Pointer to audio test stream. */ … … 184 186 /** Whether skip the actual verification or not. */ 185 187 bool fSkipVerify; 188 /** The PCM properties to use. */ 189 PDMAUDIOPCMPROPS Props; 190 /** Name of the audio device to use. 191 * If empty the default audio device will be used. */ 192 char szDev[128]; 193 /** Audio volume to use (in percent). 194 * Might not be available on all systems. */ 195 uint8_t uVolumePercent; 186 196 /** Output path for storing the test environment's final test files. */ 187 197 char szTag[AUDIOTEST_TAG_MAX]; … … 427 437 /** @} */ 428 438 429 int audioTestWorker(PAUDIOTESTENV pTstEnv , PAUDIOTESTPARMS pOverrideParms);439 int audioTestWorker(PAUDIOTESTENV pTstEnv); 430 440 431 441 /** @name Command handlers
Note:
See TracChangeset
for help on using the changeset viewer.