Changeset 88693 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Apr 23, 2021 9:49:34 PM (4 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHda.cpp
r88674 r88693 4446 4446 if (ppDrv) 4447 4447 *ppDrv = pDrv; 4448 4449 /* 4450 * While we're here, give the windows backends a hint about our typical playback 4451 * configuration. 4452 * Note! If 48000Hz is advertised to the guest, add it here. 4453 */ 4454 if ( pDrv->pConnector 4455 && pDrv->pConnector->pfnStreamConfigHint) 4456 { 4457 PDMAUDIOSTREAMCFG Cfg; 4458 RT_ZERO(Cfg); 4459 Cfg.enmDir = PDMAUDIODIR_OUT; 4460 Cfg.u.enmDst = PDMAUDIOPLAYBACKDST_FRONT; 4461 Cfg.enmLayout = PDMAUDIOSTREAMLAYOUT_INTERLEAVED; 4462 Cfg.Device.cMsSchedulingHint = 10; 4463 Cfg.Backend.cFramesPreBuffering = UINT32_MAX; 4464 PDMAudioPropsInit(&Cfg.Props, 2, true /*fSigned*/, 2, 44100); 4465 RTStrPrintf(Cfg.szName, sizeof(Cfg.szName), "output 44.1kHz 2ch S16 (HDA config hint)"); 4466 4467 pDrv->pConnector->pfnStreamConfigHint(pDrv->pConnector, &Cfg); /* (may trash CfgReq) */ 4468 } 4448 4469 } 4449 4470 else -
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r88666 r88693 2268 2268 AssertPtrNullReturn(pHostDrvAudio->pfnGetDevices, VERR_INVALID_POINTER); 2269 2269 AssertPtrNullReturn(pHostDrvAudio->pfnGetStatus, VERR_INVALID_POINTER); 2270 AssertPtrNullReturn(pHostDrvAudio->pfnStreamConfigHint, VERR_INVALID_POINTER); 2270 2271 AssertPtrReturn(pHostDrvAudio->pfnStreamCreate, VERR_INVALID_POINTER); 2271 2272 AssertPtrReturn(pHostDrvAudio->pfnStreamDestroy, VERR_INVALID_POINTER); … … 2450 2451 2451 2452 /** 2453 * Adjusts the request stream configuration, applying our settings. 2454 * 2455 * This also does some basic validations. 2456 * 2457 * Used by both the stream creation and stream configuration hinting code. 2458 * 2459 * @returns VBox status code. 2460 * @param pThis Pointer to the DrvAudio instance data. 2461 * @param pCfgReq The request configuration that should be adjusted. 2462 * @param pszName Stream name to use when logging warnings and errors. 2463 */ 2464 static int drvAudioStreamAdjustConfig(PDRVAUDIO pThis, PPDMAUDIOSTREAMCFG pCfgReq, const char *pszName) 2465 { 2466 /* Get the right configuration for the stream to be created. */ 2467 PDRVAUDIOCFG pDrvCfg = pCfgReq->enmDir == PDMAUDIODIR_IN ? &pThis->In.Cfg : &pThis->Out.Cfg; 2468 2469 /* Fill in the tweakable parameters into the requested host configuration. 2470 * All parameters in principle can be changed and returned by the backend via the acquired configuration. */ 2471 2472 /* 2473 * PCM 2474 */ 2475 if (PDMAudioPropsSampleSize(&pDrvCfg->Props) != 0) /* Anything set via custom extra-data? */ 2476 { 2477 PDMAudioPropsSetSampleSize(&pCfgReq->Props, PDMAudioPropsSampleSize(&pDrvCfg->Props)); 2478 LogRel2(("Audio: Using custom sample size of %RU8 bytes for stream '%s'\n", 2479 PDMAudioPropsSampleSize(&pCfgReq->Props), pszName)); 2480 } 2481 2482 if (pDrvCfg->Props.uHz) /* Anything set via custom extra-data? */ 2483 { 2484 pCfgReq->Props.uHz = pDrvCfg->Props.uHz; 2485 LogRel2(("Audio: Using custom Hz rate %RU32 for stream '%s'\n", pCfgReq->Props.uHz, pszName)); 2486 } 2487 2488 if (pDrvCfg->uSigned != UINT8_MAX) /* Anything set via custom extra-data? */ 2489 { 2490 pCfgReq->Props.fSigned = RT_BOOL(pDrvCfg->uSigned); 2491 LogRel2(("Audio: Using custom %s sample format for stream '%s'\n", 2492 pCfgReq->Props.fSigned ? "signed" : "unsigned", pszName)); 2493 } 2494 2495 if (pDrvCfg->uSwapEndian != UINT8_MAX) /* Anything set via custom extra-data? */ 2496 { 2497 pCfgReq->Props.fSwapEndian = RT_BOOL(pDrvCfg->uSwapEndian); 2498 LogRel2(("Audio: Using custom %s endianess for samples of stream '%s'\n", 2499 pCfgReq->Props.fSwapEndian ? "swapped" : "original", pszName)); 2500 } 2501 2502 if (PDMAudioPropsChannels(&pDrvCfg->Props) != 0) /* Anything set via custom extra-data? */ 2503 { 2504 PDMAudioPropsSetChannels(&pCfgReq->Props, PDMAudioPropsChannels(&pDrvCfg->Props)); 2505 LogRel2(("Audio: Using custom %RU8 channel(s) for stream '%s'\n", PDMAudioPropsChannels(&pDrvCfg->Props), pszName)); 2506 } 2507 2508 /* Validate PCM properties. */ 2509 if (!AudioHlpPcmPropsAreValid(&pCfgReq->Props)) 2510 { 2511 LogRel(("Audio: Invalid custom PCM properties set for stream '%s', cannot create stream\n", pszName)); 2512 return VERR_INVALID_PARAMETER; 2513 } 2514 2515 /* 2516 * Period size 2517 */ 2518 const char *pszWhat = "device-specific"; 2519 if (pDrvCfg->uPeriodSizeMs) 2520 { 2521 pCfgReq->Backend.cFramesPeriod = PDMAudioPropsMilliToFrames(&pCfgReq->Props, pDrvCfg->uPeriodSizeMs); 2522 pszWhat = "custom"; 2523 } 2524 2525 if (!pCfgReq->Backend.cFramesPeriod) /* Set default period size if nothing explicitly is set. */ 2526 { 2527 pCfgReq->Backend.cFramesPeriod = PDMAudioPropsMilliToFrames(&pCfgReq->Props, 150 /*ms*/); 2528 pszWhat = "default"; 2529 } 2530 2531 LogRel2(("Audio: Using %s period size %RU64 ms / %RU32 frames for stream '%s'\n", 2532 pszWhat, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod), 2533 pCfgReq->Backend.cFramesPeriod, pszName)); 2534 2535 /* 2536 * Buffer size 2537 */ 2538 pszWhat = "device-specific"; 2539 if (pDrvCfg->uBufferSizeMs) 2540 { 2541 pCfgReq->Backend.cFramesBufferSize = PDMAudioPropsMilliToFrames(&pCfgReq->Props, pDrvCfg->uBufferSizeMs); 2542 pszWhat = "custom"; 2543 } 2544 2545 if (!pCfgReq->Backend.cFramesBufferSize) /* Set default buffer size if nothing explicitly is set. */ 2546 { 2547 pCfgReq->Backend.cFramesBufferSize = PDMAudioPropsMilliToFrames(&pCfgReq->Props, 300 /*ms*/); 2548 pszWhat = "default"; 2549 } 2550 2551 LogRel2(("Audio: Using %s buffer size %RU64 ms / %RU32 frames for stream '%s'\n", 2552 pszWhat, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize), 2553 pCfgReq->Backend.cFramesBufferSize, pszName)); 2554 2555 /* 2556 * Pre-buffering size 2557 */ 2558 pszWhat = "device-specific"; 2559 if (pDrvCfg->uPreBufSizeMs != UINT32_MAX) /* Anything set via global / per-VM extra-data? */ 2560 { 2561 pCfgReq->Backend.cFramesPreBuffering = PDMAudioPropsMilliToFrames(&pCfgReq->Props, pDrvCfg->uPreBufSizeMs); 2562 pszWhat = "custom"; 2563 } 2564 else /* No, then either use the default or device-specific settings (if any). */ 2565 { 2566 if (pCfgReq->Backend.cFramesPreBuffering == UINT32_MAX) /* Set default pre-buffering size if nothing explicitly is set. */ 2567 { 2568 /* Pre-buffer 66% of the buffer. */ 2569 pCfgReq->Backend.cFramesPreBuffering = pCfgReq->Backend.cFramesBufferSize * 2 / 3; 2570 pszWhat = "default"; 2571 } 2572 } 2573 2574 LogRel2(("Audio: Using %s pre-buffering size %RU64 ms / %RU32 frames for stream '%s'\n", 2575 pszWhat, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPreBuffering), 2576 pCfgReq->Backend.cFramesPreBuffering, pszName)); 2577 2578 /* 2579 * Validate input. 2580 */ 2581 if (pCfgReq->Backend.cFramesBufferSize < pCfgReq->Backend.cFramesPeriod) 2582 { 2583 LogRel(("Audio: Error for stream '%s': Buffering size (%RU64ms) must not be smaller than the period size (%RU64ms)\n", 2584 pszName, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize), 2585 PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod))); 2586 return VERR_INVALID_PARAMETER; 2587 } 2588 2589 if ( pCfgReq->Backend.cFramesPreBuffering != UINT32_MAX /* Custom pre-buffering set? */ 2590 && pCfgReq->Backend.cFramesPreBuffering) 2591 { 2592 if (pCfgReq->Backend.cFramesBufferSize < pCfgReq->Backend.cFramesPreBuffering) 2593 { 2594 LogRel(("Audio: Error for stream '%s': Buffering size (%RU64ms) must not be smaller than the pre-buffering size (%RU64ms)\n", 2595 pszName, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPreBuffering), 2596 PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize))); 2597 return VERR_INVALID_PARAMETER; 2598 } 2599 } 2600 2601 return VINF_SUCCESS; 2602 } 2603 2604 /** 2452 2605 * Worker for drvAudioStreamInitInternal and drvAudioStreamReInitInternal that 2453 2606 * creates the backend (host driver) side of an audio stream. … … 2473 2626 ("Stream '%s' already initialized in backend\n", pStreamEx->Core.szName)); 2474 2627 2475 /* Get the right configuration for the stream to be created. */ 2476 PDRVAUDIOCFG pDrvCfg = pCfgReq->enmDir == PDMAUDIODIR_IN ? &pThis->In.Cfg : &pThis->Out.Cfg; 2477 2478 /* Fill in the tweakable parameters into the requested host configuration. 2479 * All parameters in principle can be changed and returned by the backend via the acquired configuration. */ 2480 2481 /* 2482 * PCM 2483 */ 2484 if (PDMAudioPropsSampleSize(&pDrvCfg->Props) != 0) /* Anything set via custom extra-data? */ 2485 { 2486 PDMAudioPropsSetSampleSize(&pCfgReq->Props, PDMAudioPropsSampleSize(&pDrvCfg->Props)); 2487 LogRel2(("Audio: Using custom sample size of %RU8 bytes for stream '%s'\n", 2488 PDMAudioPropsSampleSize(&pCfgReq->Props), pStreamEx->Core.szName)); 2489 } 2490 2491 if (pDrvCfg->Props.uHz) /* Anything set via custom extra-data? */ 2492 { 2493 pCfgReq->Props.uHz = pDrvCfg->Props.uHz; 2494 LogRel2(("Audio: Using custom Hz rate %RU32 for stream '%s'\n", pCfgReq->Props.uHz, pStreamEx->Core.szName)); 2495 } 2496 2497 if (pDrvCfg->uSigned != UINT8_MAX) /* Anything set via custom extra-data? */ 2498 { 2499 pCfgReq->Props.fSigned = RT_BOOL(pDrvCfg->uSigned); 2500 LogRel2(("Audio: Using custom %s sample format for stream '%s'\n", 2501 pCfgReq->Props.fSigned ? "signed" : "unsigned", pStreamEx->Core.szName)); 2502 } 2503 2504 if (pDrvCfg->uSwapEndian != UINT8_MAX) /* Anything set via custom extra-data? */ 2505 { 2506 pCfgReq->Props.fSwapEndian = RT_BOOL(pDrvCfg->uSwapEndian); 2507 LogRel2(("Audio: Using custom %s endianess for samples of stream '%s'\n", 2508 pCfgReq->Props.fSwapEndian ? "swapped" : "original", pStreamEx->Core.szName)); 2509 } 2510 2511 if (PDMAudioPropsChannels(&pDrvCfg->Props) != 0) /* Anything set via custom extra-data? */ 2512 { 2513 PDMAudioPropsSetChannels(&pCfgReq->Props, PDMAudioPropsChannels(&pDrvCfg->Props)); 2514 LogRel2(("Audio: Using custom %RU8 channel(s) for stream '%s'\n", PDMAudioPropsChannels(&pDrvCfg->Props), pStreamEx->Core.szName)); 2515 } 2516 2517 /* Validate PCM properties. */ 2518 if (!AudioHlpPcmPropsAreValid(&pCfgReq->Props)) 2519 { 2520 LogRel(("Audio: Invalid custom PCM properties set for stream '%s', cannot create stream\n", pStreamEx->Core.szName)); 2521 return VERR_INVALID_PARAMETER; 2522 } 2523 2524 /* 2525 * Period size 2526 */ 2527 const char *pszWhat = "device-specific"; 2528 if (pDrvCfg->uPeriodSizeMs) 2529 { 2530 pCfgReq->Backend.cFramesPeriod = PDMAudioPropsMilliToFrames(&pCfgReq->Props, pDrvCfg->uPeriodSizeMs); 2531 pszWhat = "custom"; 2532 } 2533 2534 if (!pCfgReq->Backend.cFramesPeriod) /* Set default period size if nothing explicitly is set. */ 2535 { 2536 pCfgReq->Backend.cFramesPeriod = PDMAudioPropsMilliToFrames(&pCfgReq->Props, 150 /*ms*/); 2537 pszWhat = "default"; 2538 } 2539 2540 LogRel2(("Audio: Using %s period size %RU64 ms / %RU32 frames for stream '%s'\n", 2541 pszWhat, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod), 2542 pCfgReq->Backend.cFramesPeriod, pStreamEx->Core.szName)); 2543 2544 /* 2545 * Buffer size 2546 */ 2547 pszWhat = "device-specific"; 2548 if (pDrvCfg->uBufferSizeMs) 2549 { 2550 pCfgReq->Backend.cFramesBufferSize = PDMAudioPropsMilliToFrames(&pCfgReq->Props, pDrvCfg->uBufferSizeMs); 2551 pszWhat = "custom"; 2552 } 2553 2554 if (!pCfgReq->Backend.cFramesBufferSize) /* Set default buffer size if nothing explicitly is set. */ 2555 { 2556 pCfgReq->Backend.cFramesBufferSize = PDMAudioPropsMilliToFrames(&pCfgReq->Props, 300 /*ms*/); 2557 pszWhat = "default"; 2558 } 2559 2560 LogRel2(("Audio: Using %s buffer size %RU64 ms / %RU32 frames for stream '%s'\n", 2561 pszWhat, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize), 2562 pCfgReq->Backend.cFramesBufferSize, pStreamEx->Core.szName)); 2563 2564 /* 2565 * Pre-buffering size 2566 */ 2567 pszWhat = "device-specific"; 2568 if (pDrvCfg->uPreBufSizeMs != UINT32_MAX) /* Anything set via global / per-VM extra-data? */ 2569 { 2570 pCfgReq->Backend.cFramesPreBuffering = PDMAudioPropsMilliToFrames(&pCfgReq->Props, pDrvCfg->uPreBufSizeMs); 2571 pszWhat = "custom"; 2572 } 2573 else /* No, then either use the default or device-specific settings (if any). */ 2574 { 2575 if (pCfgReq->Backend.cFramesPreBuffering == UINT32_MAX) /* Set default pre-buffering size if nothing explicitly is set. */ 2576 { 2577 /* Pre-buffer 66% of the buffer. */ 2578 pCfgReq->Backend.cFramesPreBuffering = pCfgReq->Backend.cFramesBufferSize * 2 / 3; 2579 pszWhat = "default"; 2580 } 2581 } 2582 2583 LogRel2(("Audio: Using %s pre-buffering size %RU64 ms / %RU32 frames for stream '%s'\n", 2584 pszWhat, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPreBuffering), 2585 pCfgReq->Backend.cFramesPreBuffering, pStreamEx->Core.szName)); 2586 2587 /* 2588 * Validate input. 2589 */ 2590 if (pCfgReq->Backend.cFramesBufferSize < pCfgReq->Backend.cFramesPeriod) 2591 { 2592 LogRel(("Audio: Error for stream '%s': Buffering size (%RU64ms) must not be smaller than the period size (%RU64ms)\n", 2593 pStreamEx->Core.szName, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize), 2594 PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod))); 2595 return VERR_INVALID_PARAMETER; 2596 } 2597 2598 if ( pCfgReq->Backend.cFramesPreBuffering != UINT32_MAX /* Custom pre-buffering set? */ 2599 && pCfgReq->Backend.cFramesPreBuffering) 2600 { 2601 if (pCfgReq->Backend.cFramesBufferSize < pCfgReq->Backend.cFramesPreBuffering) 2602 { 2603 LogRel(("Audio: Error for stream '%s': Buffering size (%RU64ms) must not be smaller than the pre-buffering size (%RU64ms)\n", 2604 pStreamEx->Core.szName, PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesPreBuffering), 2605 PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize))); 2606 return VERR_INVALID_PARAMETER; 2607 } 2608 } 2628 /* 2629 * Adjust the requested stream config, applying our settings. 2630 */ 2631 int rc = drvAudioStreamAdjustConfig(pThis, pCfgReq, pStreamEx->Core.szName); 2632 if (RT_FAILURE(rc)) 2633 return rc; 2609 2634 2610 2635 /* … … 2613 2638 */ 2614 2639 /** @todo r=bird: This is conveniently not documented in the interface... */ 2615 intrc = PDMAudioStrmCfgCopy(pCfgAcq, pCfgReq);2640 rc = PDMAudioStrmCfgCopy(pCfgAcq, pCfgReq); 2616 2641 if (RT_FAILURE(rc)) 2617 2642 { … … 3231 3256 3232 3257 /** 3258 * @interface_method_impl{PDMIAUDIOCONNECTOR,pfnStreamConfigHint} 3259 */ 3260 static DECLCALLBACK(void) drvAudioStreamConfigHint(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAMCFG pCfg) 3261 { 3262 PDRVAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVAUDIO, IAudioConnector); 3263 AssertReturnVoid(pCfg->enmDir == PDMAUDIODIR_IN || pCfg->enmDir == PDMAUDIODIR_OUT); 3264 3265 int rc = RTCritSectEnter(&pThis->CritSect); /** @todo Reconsider the locking for DrvAudio */ 3266 AssertRCReturnVoid(rc); 3267 3268 /* 3269 * Don't do anything unless the backend has a pfnStreamConfigHint method 3270 * and the direction is currently enabled. 3271 */ 3272 if ( pThis->pHostDrvAudio 3273 && pThis->pHostDrvAudio->pfnStreamConfigHint) 3274 { 3275 if (pCfg->enmDir == PDMAUDIODIR_OUT ? pThis->Out.fEnabled : pThis->In.fEnabled) 3276 { 3277 /* 3278 * Adjust the configuration (applying out settings) then call the backend driver. 3279 */ 3280 rc = drvAudioStreamAdjustConfig(pThis, pCfg, pCfg->szName); 3281 AssertLogRelRC(rc); 3282 if (RT_SUCCESS(rc)) 3283 pThis->pHostDrvAudio->pfnStreamConfigHint(pThis->pHostDrvAudio, pCfg); 3284 } 3285 else 3286 LogFunc(("Ignoring hint because direction is not currently enabled\n")); 3287 } 3288 else 3289 LogFlowFunc(("Ignoring hint because backend has no pfnStreamConfigHint method.\n")); 3290 3291 RTCritSectLeave(&pThis->CritSect); 3292 } 3293 3294 /** 3233 3295 * @interface_method_impl{PDMIAUDIOCONNECTOR,pfnStreamGetReadable} 3234 3296 */ … … 4069 4131 pThis->IAudioConnector.pfnGetConfig = drvAudioGetConfig; 4070 4132 pThis->IAudioConnector.pfnGetStatus = drvAudioGetStatus; 4133 pThis->IAudioConnector.pfnStreamConfigHint = drvAudioStreamConfigHint; 4071 4134 pThis->IAudioConnector.pfnStreamCreate = drvAudioStreamCreate; 4072 4135 pThis->IAudioConnector.pfnStreamDestroy = drvAudioStreamDestroy; -
trunk/src/VBox/Devices/Audio/DrvHostAudioNull.cpp
r88561 r88693 230 230 /* .pfnGetDevices =*/ NULL, 231 231 /* .pfnGetStatus =*/ drvHostNullAudioHA_GetStatus, 232 /* .pfnStreamConfigHint =*/ NULL, 232 233 /* .pfnStreamCreate =*/ drvHostNullAudioHA_StreamCreate, 233 234 /* .pfnStreamDestroy =*/ drvHostNullAudioHA_StreamDestroy, -
trunk/src/VBox/Devices/Audio/DrvHostAudioWasApi.cpp
r88691 r88693 1278 1278 RT_NOREF(pInterface, enmDir); 1279 1279 return PDMAUDIOBACKENDSTS_RUNNING; 1280 } 1281 1282 1283 /** 1284 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamConfigHint} 1285 */ 1286 static DECLCALLBACK(void) drvHostAudioWasHA_StreamConfigHint(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAMCFG pCfg) 1287 { 1288 PDRVHOSTAUDIOWAS pThis = RT_FROM_MEMBER(pInterface, DRVHOSTAUDIOWAS, IHostAudio); 1289 LogFlowFunc(("pCfg=%p\n", pCfg)); 1290 1291 /* 1292 * Get the device. 1293 */ 1294 pThis->pNotifyClient->lockEnter(); 1295 IMMDevice *pIDevice = pCfg->enmDir == PDMAUDIODIR_IN ? pThis->pIDeviceInput : pThis->pIDeviceOutput; 1296 if (pIDevice) 1297 pIDevice->AddRef(); 1298 pThis->pNotifyClient->lockLeave(); 1299 if (pIDevice) 1300 { 1301 /* 1302 * Look up the config and put it back. 1303 */ 1304 PDRVHOSTAUDIOWASCACHEDEVCFG pDevCfg = drvHostAudioWasCacheLookupOrCreate(pThis, pIDevice, pCfg); 1305 LogFlowFunc(("pDevCfg=%p\n")); 1306 if (pDevCfg) 1307 drvHostAudioWasCachePutBack(pThis, pDevCfg); 1308 pIDevice->Release(); 1309 } 1280 1310 } 1281 1311 … … 2333 2363 pThis->IHostAudio.pfnGetDevices = drvHostAudioWasHA_GetDevices; 2334 2364 pThis->IHostAudio.pfnGetStatus = drvHostAudioWasHA_GetStatus; 2365 pThis->IHostAudio.pfnStreamConfigHint = drvHostAudioWasHA_StreamConfigHint; 2335 2366 pThis->IHostAudio.pfnStreamCreate = drvHostAudioWasHA_StreamCreate; 2336 2367 pThis->IHostAudio.pfnStreamDestroy = drvHostAudioWasHA_StreamDestroy;
Note:
See TracChangeset
for help on using the changeset viewer.