Changeset 89063 in vbox for trunk/src/VBox/ValidationKit/utils/audio
- Timestamp:
- May 16, 2021 8:00:06 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp
r89061 r89063 40 40 #include <iprt/stream.h> 41 41 #include <iprt/string.h> 42 #include <iprt/uuid.h> 42 43 #include <iprt/test.h> 43 44 #include <iprt/formats/riff.h> … … 205 206 static int audioTestPlayTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms); 206 207 static int audioTestStreamDestroy(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream); 208 209 static int audioTestDrvConstruct(PAUDIOTESTDRVSTACK pDrvStack, PCPDMDRVREG pDrvReg, 210 PPDMDRVINS pParentDrvIns, PPPDMDRVINS ppDrvIns); 207 211 208 212 static RTEXITCODE audioTestUsage(PRTSTREAM pStrm); … … 325 329 326 330 /********************************************************************************************************************************* 327 * Fake PDM driver handling. *331 * Fake PDM Driver Handling. * 328 332 *********************************************************************************************************************************/ 329 333 330 /** @name Driver Helper Fakes /Stubs334 /** @name Driver Fakes/Stubs 331 335 * 332 336 * @note The VMM functions defined here will turn into driver helpers before … … 336 340 * @{ */ 337 341 338 VMMR3DECL(PCFGMNODE) 342 VMMR3DECL(PCFGMNODE) CFGMR3GetChild(PCFGMNODE pNode, const char *pszPath) 339 343 { 340 344 RT_NOREF(pNode, pszPath); … … 372 376 } 373 377 374 VMMR3DECL(int) CFGMR3QueryBoolDef(PCFGMNODE pNode, const char *pszName, bool *pf, bool fDef)378 VMMR3DECL(int) CFGMR3QueryBoolDef(PCFGMNODE pNode, const char *pszName, bool *pf, bool fDef) 375 379 { 376 380 RT_NOREF(pNode, pszName, pf); … … 378 382 } 379 383 380 VMMR3DECL(int) CFGMR3QueryU8(PCFGMNODE pNode, const char *pszName, uint8_t *pu8)384 VMMR3DECL(int) CFGMR3QueryU8(PCFGMNODE pNode, const char *pszName, uint8_t *pu8) 381 385 { 382 386 RT_NOREF(pNode, pszName, pu8); … … 384 388 } 385 389 386 VMMR3DECL(int) CFGMR3QueryU32(PCFGMNODE pNode, const char *pszName, uint32_t *pu32)390 VMMR3DECL(int) CFGMR3QueryU32(PCFGMNODE pNode, const char *pszName, uint32_t *pu32) 387 391 { 388 392 RT_NOREF(pNode, pszName, pu32); … … 399 403 400 404 /** @} */ 405 406 /** @name Driver Helper Fakes 407 * @{ */ 408 409 static DECLCALLBACK(int) audioTestDrvHlp_Attach(PPDMDRVINS pDrvIns, uint32_t fFlags, PPDMIBASE *ppBaseInterface) 410 { 411 /* DrvAudio must be allowed to attach the backend driver (paranoid 412 backend drivers may call us to check that nothing is attached). */ 413 if (strcmp(pDrvIns->pReg->szName, "AUDIO") == 0) 414 { 415 PAUDIOTESTDRVSTACK pDrvStack = pDrvIns->Internal.s.pStack; 416 AssertReturn(pDrvStack->pDrvBackendIns == NULL, VERR_PDM_DRIVER_ALREADY_ATTACHED); 417 418 if (g_uVerbosity > 1) 419 RTMsgInfo("Attaching backend '%s' to DrvAudio...\n", pDrvStack->pDrvReg->szName); 420 int rc = audioTestDrvConstruct(pDrvStack, pDrvStack->pDrvReg, pDrvIns, &pDrvStack->pDrvBackendIns); 421 if (RT_SUCCESS(rc)) 422 { 423 if (ppBaseInterface) 424 *ppBaseInterface = &pDrvStack->pDrvBackendIns->IBase; 425 } 426 else 427 RTMsgError("Failed to attach backend: %Rrc", rc); 428 return rc; 429 } 430 RT_NOREF(fFlags); 431 return VERR_PDM_NO_ATTACHED_DRIVER; 432 } 433 434 static DECLCALLBACK(void) audioTestDrvHlp_STAMRegisterF(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, 435 STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc, 436 const char *pszName, ...) 437 { 438 RT_NOREF(pDrvIns, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName); 439 } 440 441 static DECLCALLBACK(void) audioTestDrvHlp_STAMRegisterV(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, 442 STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc, 443 const char *pszName, va_list args) 444 { 445 RT_NOREF(pDrvIns, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, args); 446 } 447 448 static DECLCALLBACK(int) audioTestDrvHlp_STAMDeregister(PPDMDRVINS pDrvIns, void *pvSample) 449 { 450 RT_NOREF(pDrvIns, pvSample); 451 return VINF_SUCCESS; 452 } 453 454 static DECLCALLBACK(int) audioTestDrvHlp_STAMDeregisterByPrefix(PPDMDRVINS pDrvIns, const char *pszPrefix) 455 { 456 RT_NOREF(pDrvIns, pszPrefix); 457 return VINF_SUCCESS; 458 } 459 460 /** 461 * Get the driver helpers. 462 */ 463 static const PDMDRVHLPR3 *audioTestFakeGetDrvHlp(void) 464 { 465 /* 466 * Note! No initializer for s_DrvHlp (also why it's not a file global). 467 * We do not want to have to update this code every time PDMDRVHLPR3 468 * grows new entries or are otherwise modified. Only when the 469 * entries used by the audio driver changes do we want to change 470 * our code. 471 */ 472 static PDMDRVHLPR3 s_DrvHlp; 473 if (s_DrvHlp.u32Version != PDM_DRVHLPR3_VERSION) 474 { 475 s_DrvHlp.u32Version = PDM_DRVHLPR3_VERSION; 476 s_DrvHlp.u32TheEnd = PDM_DRVHLPR3_VERSION; 477 s_DrvHlp.pfnAttach = audioTestDrvHlp_Attach; 478 s_DrvHlp.pfnSTAMRegisterF = audioTestDrvHlp_STAMRegisterF; 479 s_DrvHlp.pfnSTAMRegisterV = audioTestDrvHlp_STAMRegisterV; 480 s_DrvHlp.pfnSTAMDeregister = audioTestDrvHlp_STAMDeregister; 481 s_DrvHlp.pfnSTAMDeregisterByPrefix = audioTestDrvHlp_STAMDeregisterByPrefix; 482 } 483 return &s_DrvHlp; 484 } 485 486 /** @} */ 487 488 489 /** 490 * Implementation of PDMIBASE::pfnQueryInterface for a fake device above 491 * DrvAudio. 492 */ 493 static DECLCALLBACK(void *) audioTestFakeDeviceIBaseQueryInterface(PPDMIBASE pInterface, const char *pszIID) 494 { 495 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, pInterface); 496 RTMsgWarning("audioTestFakeDeviceIBaseQueryInterface: Unknown interface: %s\n", pszIID); 497 return NULL; 498 } 499 500 /** IBase interface for a fake device above DrvAudio. */ 501 static PDMIBASE g_AudioTestFakeDeviceIBase = { audioTestFakeDeviceIBaseQueryInterface }; 502 503 504 static DECLCALLBACK(int) audioTestIHostAudioPort_DoOnWorkerThread(PPDMIHOSTAUDIOPORT pInterface, PPDMAUDIOBACKENDSTREAM pStream, 505 uintptr_t uUser, void *pvUser) 506 { 507 RT_NOREF(pInterface, pStream, uUser, pvUser); 508 RTMsgWarning("audioTestIHostAudioPort_DoOnWorkerThread was called\n"); 509 return VERR_NOT_IMPLEMENTED; 510 } 511 512 DECLCALLBACK(void) audioTestIHostAudioPort_NotifyDeviceChanged(PPDMIHOSTAUDIOPORT pInterface, PDMAUDIODIR enmDir, void *pvUser) 513 { 514 RT_NOREF(pInterface, enmDir, pvUser); 515 RTMsgWarning("audioTestIHostAudioPort_NotifyDeviceChanged was called\n"); 516 } 517 518 static DECLCALLBACK(void) audioTestIHostAudioPort_StreamNotifyPreparingDeviceSwitch(PPDMIHOSTAUDIOPORT pInterface, 519 PPDMAUDIOBACKENDSTREAM pStream) 520 { 521 RT_NOREF(pInterface, pStream); 522 RTMsgWarning("audioTestIHostAudioPort_StreamNotifyPreparingDeviceSwitch was called\n"); 523 } 524 525 static DECLCALLBACK(void) audioTestIHostAudioPort_StreamNotifyDeviceChanged(PPDMIHOSTAUDIOPORT pInterface, 526 PPDMAUDIOBACKENDSTREAM pStream, bool fReInit) 527 { 528 RT_NOREF(pInterface, pStream, fReInit); 529 RTMsgWarning("audioTestIHostAudioPort_StreamNotifyDeviceChanged was called\n"); 530 } 531 532 static DECLCALLBACK(void) audioTestIHostAudioPort_NotifyDevicesChanged(PPDMIHOSTAUDIOPORT pInterface) 533 { 534 RT_NOREF(pInterface); 535 RTMsgWarning("audioTestIHostAudioPort_NotifyDevicesChanged was called\n"); 536 } 537 538 static PDMIHOSTAUDIOPORT g_AudioTestIHostAudioPort = 539 { 540 audioTestIHostAudioPort_DoOnWorkerThread, 541 audioTestIHostAudioPort_NotifyDeviceChanged, 542 audioTestIHostAudioPort_StreamNotifyPreparingDeviceSwitch, 543 audioTestIHostAudioPort_StreamNotifyDeviceChanged, 544 audioTestIHostAudioPort_NotifyDevicesChanged, 545 }; 546 547 /** 548 * Implementation of PDMIBASE::pfnQueryInterface for a fake DrvAudio above a 549 * backend. 550 */ 551 static DECLCALLBACK(void *) audioTestFakeDrvAudioIBaseQueryInterface(PPDMIBASE pInterface, const char *pszIID) 552 { 553 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, pInterface); 554 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIOPORT, &g_AudioTestIHostAudioPort); 555 RTMsgWarning("audioTestFakeDrvAudioIBaseQueryInterface: Unknown interface: %s\n", pszIID); 556 return NULL; 557 } 558 559 /** IBase interface for a fake DrvAudio above a lonesome backend. */ 560 static PDMIBASE g_AudioTestFakeDrvAudioIBase = { audioTestFakeDrvAudioIBaseQueryInterface }; 561 562 401 563 402 564 /** … … 420 582 */ 421 583 AssertPtrReturn(pDrvReg, VERR_INVALID_POINTER); 422 RT TestPrintf(g_hTest, RTTESTLVL_ALWAYS,"Initializing backend '%s' ...\n", pDrvReg->szName);584 RTMsgInfo("Initializing backend '%s' ...\n", pDrvReg->szName); 423 585 AssertPtrReturn(pDrvReg->pfnConstruct, VERR_INVALID_PARAMETER); 424 425 /*426 * Initialize the driver helper the first time thru.427 */428 static PDMDRVHLPR3 s_DrvHlp;429 if (s_DrvHlp.u32Version == 0)430 {431 s_DrvHlp.u32Version = PDM_DRVHLPR3_VERSION;432 s_DrvHlp.u32TheEnd = PDM_DRVHLPR3_VERSION;433 }434 586 435 587 /* … … 441 593 pDrvIns->u32Version = PDM_DRVINS_VERSION; 442 594 pDrvIns->iInstance = 0; 443 pDrvIns->pHlpR3 = &s_DrvHlp;595 pDrvIns->pHlpR3 = audioTestFakeGetDrvHlp(); 444 596 pDrvIns->pvInstanceDataR3 = &pDrvIns->achInstanceData[0]; 445 597 pDrvIns->pReg = pDrvReg; … … 454 606 pDrvIns->pUpBase = &pParentDrvIns->IBase; 455 607 } 608 else if (strcmp(pDrvReg->szName, "AUDIO") == 0) 609 pDrvIns->pUpBase = &g_AudioTestFakeDeviceIBase; 610 else 611 pDrvIns->pUpBase = &g_AudioTestFakeDrvAudioIBase; 456 612 457 613 /* … … 534 690 /** 535 691 * Initializes a driver stack. 692 * 536 693 * @returns VBox status code. 537 694 * @param pDrvStack The driver stack to initialize. … … 541 698 static int audioTestDriverStackInit(PAUDIOTESTDRVSTACK pDrvStack, PCPDMDRVREG pDrvReg, bool fWithDrvAudio) 542 699 { 543 int rc;544 700 RT_ZERO(*pDrvStack); 545 701 pDrvStack->pDrvReg = pDrvReg; 702 703 int rc; 546 704 if (!fWithDrvAudio) 547 705 rc = audioTestDrvConstruct(pDrvStack, pDrvReg, NULL /*pParentDrvIns*/, &pDrvStack->pDrvBackendIns); 548 706 else 549 707 { 550 rc = VERR_NOT_IMPLEMENTED; 708 rc = audioTestDrvConstruct(pDrvStack, &g_DrvAUDIO, NULL /*pParentDrvIns*/, &pDrvStack->pDrvAudioIns); 709 if (RT_SUCCESS(rc)) 710 { 711 Assert(pDrvStack->pDrvAudioIns); 712 PPDMIBASE const pIBase = &pDrvStack->pDrvAudioIns->IBase; 713 pDrvStack->pIAudioConnector = (PPDMIAUDIOCONNECTOR)pIBase->pfnQueryInterface(pIBase, PDMIAUDIOCONNECTOR_IID); 714 if (pDrvStack->pIAudioConnector) 715 { 716 /* Both input and output is disabled by default. Fix that: */ 717 rc = pDrvStack->pIAudioConnector->pfnEnable(pDrvStack->pIAudioConnector, PDMAUDIODIR_OUT, true); 718 if (RT_SUCCESS(rc)) 719 rc = pDrvStack->pIAudioConnector->pfnEnable(pDrvStack->pIAudioConnector, PDMAUDIODIR_IN, true); 720 if (RT_FAILURE(rc)) 721 { 722 RTTestFailed(g_hTest, "Failed to enabled input and output: %Rrc", rc); 723 audioTestDriverStackDelete(pDrvStack); 724 } 725 } 726 else 727 { 728 RTTestFailed(g_hTest, "Failed to query PDMIAUDIOCONNECTOR"); 729 audioTestDriverStackDelete(pDrvStack); 730 rc = VERR_PDM_MISSING_INTERFACE; 731 } 732 } 551 733 } 552 734 … … 556 738 if (RT_SUCCESS(rc)) 557 739 { 558 pDrvStack->pIHostAudio 559 = (PPDMIHOSTAUDIO)pDrvStack->pDrvBackendIns->IBase.pfnQueryInterface(&pDrvStack->pDrvBackendIns->IBase, 560 PDMIHOSTAUDIO_IID); 740 PPDMIBASE const pIBase = &pDrvStack->pDrvBackendIns->IBase; 741 pDrvStack->pIHostAudio = (PPDMIHOSTAUDIO)pIBase->pfnQueryInterface(pIBase, PDMIHOSTAUDIO_IID); 561 742 if (pDrvStack->pIHostAudio) 562 743 { … … 590 771 PPDMAUDIOSTREAM *ppStream) 591 772 { 773 char szTmp[PDMAUDIOSTRMCFGTOSTRING_MAX + 16]; 592 774 *ppStream = NULL; 593 775 594 int rc; 776 /* 777 * Calculate the stream config. 778 */ 779 PDMAUDIOSTREAMCFG CfgReq; 780 int rc = PDMAudioStrmCfgInitWithProps(&CfgReq, pProps); 781 AssertRC(rc); 782 CfgReq.enmDir = PDMAUDIODIR_OUT; 783 CfgReq.u.enmDst = PDMAUDIOPLAYBACKDST_FRONT; 784 CfgReq.enmLayout = PDMAUDIOSTREAMLAYOUT_INTERLEAVED; 785 CfgReq.Device.cMsSchedulingHint = cMsSchedulingHint == UINT32_MAX || cMsSchedulingHint == 0 786 ? 10 : cMsSchedulingHint; 787 if (pDrvStack->pIAudioConnector && (cMsBufferSize == UINT32_MAX || cMsBufferSize == 0)) 788 CfgReq.Backend.cFramesBufferSize = 0; /* DrvAudio picks the default */ 789 else 790 CfgReq.Backend.cFramesBufferSize = PDMAudioPropsMilliToFrames(pProps, 791 cMsBufferSize == UINT32_MAX || cMsBufferSize == 0 792 ? 300 : cMsBufferSize); 793 if (cMsPreBuffer == UINT32_MAX) 794 CfgReq.Backend.cFramesPreBuffering = pDrvStack->pIAudioConnector ? UINT32_MAX /*DrvAudo picks the default */ 795 : CfgReq.Backend.cFramesBufferSize * 2 / 3; 796 else 797 CfgReq.Backend.cFramesPreBuffering = PDMAudioPropsMilliToFrames(pProps, cMsPreBuffer); 798 if ( CfgReq.Backend.cFramesPreBuffering >= CfgReq.Backend.cFramesBufferSize + 16 799 && !pDrvStack->pIAudioConnector /*DrvAudio deals with it*/ ) 800 { 801 RTMsgWarning("Cannot pre-buffer %#x frames with only %#x frames of buffer!", 802 CfgReq.Backend.cFramesPreBuffering, CfgReq.Backend.cFramesBufferSize); 803 CfgReq.Backend.cFramesPreBuffering = CfgReq.Backend.cFramesBufferSize > 16 804 ? CfgReq.Backend.cFramesBufferSize - 16 : 0; 805 } 806 807 static uint32_t s_idxStream = 0; 808 uint32_t const idxStream = s_idxStream++; 809 RTStrPrintf(CfgReq.szName, sizeof(CfgReq.szName), "out-%u", idxStream); 810 595 811 if (pDrvStack->pIAudioConnector) 596 812 { 597 rc = VERR_NOT_IMPLEMENTED; 813 /* 814 * DrvAudio does most of the work here. 815 */ 816 PDMAUDIOSTREAMCFG CfgGst = CfgReq; 817 rc = pDrvStack->pIAudioConnector->pfnStreamCreate(pDrvStack->pIAudioConnector, PDMAUDIOSTREAM_CREATE_F_NO_MIXBUF, 818 &CfgReq, &CfgGst, ppStream); 819 if (RT_SUCCESS(rc)) 820 { 821 RTMsgInfo("Created backend stream: %s\n", PDMAudioStrmCfgToString(&CfgReq, szTmp, sizeof(szTmp))); 822 return rc; 823 } 824 RTTestFailed(g_hTest, "pfnStreamCreate failed: %Rrc", rc); 598 825 } 599 826 else 600 827 { 601 /*602 * Calculate the stream config.603 */604 PDMAUDIOSTREAMCFG CfgReq;605 rc = PDMAudioStrmCfgInitWithProps(&CfgReq, pProps);606 AssertRC(rc);607 CfgReq.enmDir = PDMAUDIODIR_OUT;608 CfgReq.u.enmDst = PDMAUDIOPLAYBACKDST_UNKNOWN;609 CfgReq.enmLayout = PDMAUDIOSTREAMLAYOUT_INTERLEAVED;610 CfgReq.Device.cMsSchedulingHint = cMsSchedulingHint == UINT32_MAX || cMsSchedulingHint == 0611 ? 10 : cMsSchedulingHint;612 CfgReq.Backend.cFramesBufferSize = PDMAudioPropsMilliToFrames(pProps,613 cMsBufferSize == UINT32_MAX || cMsBufferSize == 0614 ? 300 : cMsBufferSize);615 if (cMsPreBuffer == UINT32_MAX)616 CfgReq.Backend.cFramesPreBuffering = CfgReq.Backend.cFramesBufferSize * 2 / 3;617 else618 CfgReq.Backend.cFramesPreBuffering = PDMAudioPropsMilliToFrames(pProps, cMsPreBuffer);619 if (CfgReq.Backend.cFramesPreBuffering >= CfgReq.Backend.cFramesBufferSize + 16)620 {621 RTMsgWarning("Cannot pre-buffer %#x frames with only %#x frames of buffer!",622 CfgReq.Backend.cFramesPreBuffering, CfgReq.Backend.cFramesBufferSize);623 CfgReq.Backend.cFramesPreBuffering = CfgReq.Backend.cFramesBufferSize > 16624 ? CfgReq.Backend.cFramesBufferSize - 16 : 0;625 }626 627 static uint32_t s_idxStream = 0;628 uint32_t const idxStream = s_idxStream++;629 RTStrPrintf(CfgReq.szName, sizeof(CfgReq.szName), "out-%u", idxStream);630 631 828 /* 632 829 * Get the config so we can see how big the PDMAUDIOBACKENDSTREAM … … 666 863 pStreamAt->Core.Props = pStreamAt->Cfg.Props; 667 864 if (g_uVerbosity > 1) 668 {669 char szTmp[PDMAUDIOSTRMCFGTOSTRING_MAX + 16];670 865 RTMsgInfo("Created backend stream: %s\n", 671 866 PDMAudioStrmCfgToString(&pStreamAt->Cfg, szTmp, sizeof(szTmp))); 672 }673 867 674 868 /* Return if stream is ready: */ … … 1941 2135 * Command: play * 1942 2136 *********************************************************************************************************************************/ 1943 /**1944 * Command line parameters for test mode.1945 */1946 static const RTGETOPTDEF g_aCmdPlayOptions[] =1947 {1948 { "--backend", 'b', RTGETOPT_REQ_STRING },1949 };1950 1951 /** the 'play' command option help. */1952 static DECLCALLBACK(const char *) audioTestCmdPlayHelp(PCRTGETOPTDEF pOpt)1953 {1954 switch (pOpt->iShort)1955 {1956 case 'b': return "The audio backend to use.";1957 default: return NULL;1958 }1959 }1960 2137 1961 2138 /** … … 1963 2140 */ 1964 2141 static RTEXITCODE audioTestPlayOne(const char *pszFile, PCPDMDRVREG pDrvReg, uint32_t cMsBufferSize, 1965 uint32_t cMsPreBuffer, uint32_t cMsSchedulingHint )2142 uint32_t cMsPreBuffer, uint32_t cMsSchedulingHint, bool fWithDrvAudio) 1966 2143 { 1967 2144 /* … … 1989 2166 RTEXITCODE rcExit = RTEXITCODE_FAILURE; 1990 2167 AUDIOTESTDRVSTACK DrvStack; 1991 rc = audioTestDriverStackInit(&DrvStack, pDrvReg, f alse /*fWithDrvAudio*/);2168 rc = audioTestDriverStackInit(&DrvStack, pDrvReg, fWithDrvAudio); 1992 2169 if (RT_SUCCESS(rc)) 1993 2170 { … … 2096 2273 2097 2274 /** 2275 * Command line parameters for test mode. 2276 */ 2277 static const RTGETOPTDEF g_aCmdPlayOptions[] = 2278 { 2279 { "--backend", 'b', RTGETOPT_REQ_STRING }, 2280 { "--with-drv-audio", 'd', RTGETOPT_REQ_NOTHING }, 2281 }; 2282 2283 /** the 'play' command option help. */ 2284 static DECLCALLBACK(const char *) audioTestCmdPlayHelp(PCRTGETOPTDEF pOpt) 2285 { 2286 switch (pOpt->iShort) 2287 { 2288 case 'b': return "The audio backend to use."; 2289 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend."; 2290 default: return NULL; 2291 } 2292 } 2293 2294 /** 2098 2295 * The 'play' command handler. 2099 2296 * … … 2104 2301 static DECLCALLBACK(RTEXITCODE) audioTestCmdPlayHandler(int argc, char **argv) 2105 2302 { 2106 /*2107 * Parse arguments.2108 */2109 2303 /* Option values: */ 2110 2304 PCPDMDRVREG pDrvReg = g_aBackends[0].pDrvReg; … … 2112 2306 uint32_t cMsPreBuffer = UINT32_MAX; 2113 2307 uint32_t cMsSchedulingHint = UINT32_MAX; 2114 2308 bool fWithDrvAudio = false; 2309 2310 /* Init option state: */ 2115 2311 RTGETOPTSTATE GetState; 2116 2312 int rc = RTGetOptInit(&GetState, argc, argv, g_aCmdPlayOptions, RT_ELEMENTS(g_aCmdPlayOptions), … … 2118 2314 AssertRCReturn(rc, RTEXITCODE_INIT); 2119 2315 2316 /* Argument processing loop: */ 2120 2317 RTGETOPTUNION ValueUnion; 2121 2318 while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0) … … 2136 2333 break; 2137 2334 2335 case 'd': 2336 fWithDrvAudio = true; 2337 break; 2338 2138 2339 case VINF_GETOPT_NOT_OPTION: 2139 2340 { 2140 RTEXITCODE rcExit = audioTestPlayOne(ValueUnion.psz, pDrvReg, cMsBufferSize, cMsPreBuffer, cMsSchedulingHint); 2341 RTEXITCODE rcExit = audioTestPlayOne(ValueUnion.psz, pDrvReg, cMsBufferSize, cMsPreBuffer, 2342 cMsSchedulingHint, fWithDrvAudio); 2141 2343 if (rcExit != RTEXITCODE_SUCCESS) 2142 2344 return rcExit;
Note:
See TracChangeset
for help on using the changeset viewer.