Changeset 89258 in vbox for trunk/src/VBox/Devices
- Timestamp:
- May 25, 2021 9:58:08 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 144601
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r89229 r89258 4552 4552 AssertPtrReturn(pIHostDrvAudio->pfnGetConfig, VERR_INVALID_POINTER); 4553 4553 AssertPtrNullReturn(pIHostDrvAudio->pfnGetDevices, VERR_INVALID_POINTER); 4554 AssertPtrNullReturn(pIHostDrvAudio->pfnSetDevice, VERR_INVALID_POINTER); 4554 4555 AssertPtrNullReturn(pIHostDrvAudio->pfnGetStatus, VERR_INVALID_POINTER); 4555 4556 AssertPtrNullReturn(pIHostDrvAudio->pfnDoOnWorkerThread, VERR_INVALID_POINTER); -
trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp
r89213 r89258 1427 1427 pThis->IHostAudio.pfnGetConfig = drvHostAlsaAudioHA_GetConfig; 1428 1428 pThis->IHostAudio.pfnGetDevices = drvHostAlsaAudioHA_GetDevices; 1429 pThis->IHostAudio.pfnSetDevice = NULL; 1429 1430 pThis->IHostAudio.pfnGetStatus = drvHostAlsaAudioHA_GetStatus; 1430 1431 pThis->IHostAudio.pfnDoOnWorkerThread = NULL; -
trunk/src/VBox/Devices/Audio/DrvHostAudioCoreAudio.cpp
r89255 r89258 98 98 99 99 /** 100 * Default audio device information.100 * Audio device information. 101 101 * 102 102 * We do not use COREAUDIODEVICEDATA here as it contains lots more than what we … … 104 104 * PDMIHOSTAUDIO::pfnGetDevices callbacks to keep this information up to date. 105 105 */ 106 typedef struct DRVHSTAUDCADE FAULTDEV106 typedef struct DRVHSTAUDCADEVICE 107 107 { 108 108 /** The audio device ID. kAudioDeviceUnknown if not available. */ … … 112 112 /** The UID string (must release). NULL if not available. */ 113 113 CFStringRef hStrUid; 114 } DRVHSTAUDCADEFAULTDEV; 114 /** The UID string for a specific device, NULL if we're using the default device. */ 115 char *pszSpecific; 116 } DRVHSTAUDCADEVICE; 115 117 /** Pointer to info about a default device. */ 116 typedef DRVHSTAUDCADE FAULTDEV *PDRVHSTAUDCADEFAULTDEV;118 typedef DRVHSTAUDCADEVICE *PDRVHSTAUDCADEVICE; 117 119 118 120 … … 221 223 /** Pointer to host audio interface. */ 222 224 PDMIHOSTAUDIO IHostAudio; 223 /** The defaultinput device. */224 DRVHSTAUDCADE FAULTDEV DefaultInput;225 /** The defaultoutput device. */226 DRVHSTAUDCADE FAULTDEV DefaultOutput;225 /** The input device. */ 226 DRVHSTAUDCADEVICE InputDevice; 227 /** The output device. */ 228 DRVHSTAUDCADEVICE OutputDevice; 227 229 /** Upwards notification interface. */ 228 230 PPDMIHOSTAUDIOPORT pIHostAudioPort; … … 261 263 * Internal Functions * 262 264 *********************************************************************************************************************************/ 263 static void drvHstAudCaUpdateOneDefaultDevice(PDRVHOSTCOREAUDIO pThis, PDRVHSTAUDCADEFAULTDEV pDefaultDev, 264 bool fInput, bool fNotify); 265 static void drvHstAudCaUpdateOneDefaultDevice(PDRVHOSTCOREAUDIO pThis, PDRVHSTAUDCADEVICE pDevice, bool fInput, bool fNotify); 265 266 266 267 /* DrvHostAudioCoreAudioAuth.mm: */ … … 495 496 496 497 /** 498 * Translates a UID to an audio device ID. 499 * 500 * @returns Audio device ID on success, kAudioDeviceUnknown on failure. 501 * @param hStrUid The UID string to convert. 502 * @param pszUid The C-string vresion of @a hStrUid. 503 * @param pszWhat What we're converting (for logging). 504 */ 505 static AudioObjectID drvHstAudCaDeviceUidToId(CFStringRef hStrUid, const char *pszUid, const char *pszWhat) 506 { 507 AudioObjectPropertyAddress const PropAddr = 508 { 509 /*.mSelector = */ kAudioHardwarePropertyTranslateUIDToDevice, 510 /*.mScope = */ kAudioObjectPropertyScopeGlobal, 511 /*.mElement = */ kAudioObjectPropertyElementMaster 512 }; 513 AudioObjectID idDevice = 0; 514 UInt32 cb = sizeof(idDevice); 515 OSStatus orc = AudioObjectGetPropertyData(kAudioObjectSystemObject, &PropAddr, 516 sizeof(hStrUid), &hStrUid, &cb, &idDevice); 517 if (orc == noErr) 518 { 519 Log9Func(("%s device UID '%s' -> %RU32\n", pszWhat, pszUid, idDevice)); 520 return idDevice; 521 } 522 LogRelMax(64, ("CoreAudio: Failed to translate %s device UID '%s' to audio device ID: %#x\n", pszWhat, pszUid, orc)); 523 return kAudioDeviceUnknown; 524 } 525 526 527 /** 497 528 * Copies a CFString to a buffer (UTF-8). 498 529 * … … 644 675 for (unsigned i = 0; i < 2; i++) 645 676 { 646 if (idObject == (i == 0 ? pThis-> DefaultInput.idDevice : pThis->DefaultOutput.idDevice))677 if (idObject == (i == 0 ? pThis->InputDevice.idDevice : pThis->OutputDevice.idDevice)) 647 678 { 648 679 AudioObjectPropertyAddress const PropAddr = … … 707 738 * Update the default devices and notify parent driver if anything actually changed. 708 739 */ 709 drvHstAudCaUpdateOneDefaultDevice(pThis, &pThis-> DefaultOutput, false /*fInput*/, true /*fNotify*/);710 drvHstAudCaUpdateOneDefaultDevice(pThis, &pThis-> DefaultInput, true /*fInput*/, true /*fNotify*/);740 drvHstAudCaUpdateOneDefaultDevice(pThis, &pThis->OutputDevice, false /*fInput*/, true /*fNotify*/); 741 drvHstAudCaUpdateOneDefaultDevice(pThis, &pThis->InputDevice, true /*fInput*/, true /*fNotify*/); 711 742 712 743 return noErr; … … 805 836 * 806 837 * @param pThis The core audio driver instance data. 807 * @param pDe faultDev The default deviceto update.838 * @param pDevice The device information to update. 808 839 * @param fInput Set if input device, clear if output. 809 840 * @param fNotify Whether to notify the parent driver if something 810 841 * changed. 811 842 */ 812 static void drvHstAudCaUpdateOneDefaultDevice(PDRVHOSTCOREAUDIO pThis, PDRVHSTAUDCADEFAULTDEV pDefaultDev, 813 bool fInput, bool fNotify) 814 { 843 static void drvHstAudCaUpdateOneDefaultDevice(PDRVHOSTCOREAUDIO pThis, PDRVHSTAUDCADEVICE pDevice, bool fInput, bool fNotify) 844 { 845 /* 846 * Skip if there is a specific device we should use for this direction. 847 */ 848 if (pDevice->pszSpecific) 849 return; 850 815 851 /* 816 852 * Get the information before we enter the critical section. … … 856 892 if (RT_SUCCESS(rc)) 857 893 { 858 if (idDefaultDev != pDe faultDev->idDevice)894 if (idDefaultDev != pDevice->idDevice) 859 895 { 860 896 if (idDefaultDev != kAudioDeviceUnknown) 861 897 { 862 898 LogRel(("CoreAudio: Default %s device: %u (was %u), ID '%s'\n", 863 fInput ? "input" : "output", idDefaultDev, pDe faultDev->idDevice, szUid));899 fInput ? "input" : "output", idDefaultDev, pDevice->idDevice, szUid)); 864 900 pIHostAudioPort = fNotify ? pThis->pIHostAudioPort : NULL; /* (only if there is a new device) */ 865 901 } 866 902 else 867 LogRel(("CoreAudio: Default %s device is gone (was %u)\n", fInput ? "input" : "output", pDe faultDev->idDevice));868 869 if (pDe faultDev->hStrUid)870 CFRelease(pDe faultDev->hStrUid);871 if (pDe faultDev->fRegisteredListeners)872 drvHstAudCaDeviceUnregisterCallbacks(pThis, pDe faultDev->idDevice);873 pDe faultDev->hStrUid = hStrUid;874 pDe faultDev->idDevice = idDefaultDev;875 pDe faultDev->fRegisteredListeners = drvHstAudCaDeviceRegisterCallbacks(pThis, pDefaultDev->idDevice);903 LogRel(("CoreAudio: Default %s device is gone (was %u)\n", fInput ? "input" : "output", pDevice->idDevice)); 904 905 if (pDevice->hStrUid) 906 CFRelease(pDevice->hStrUid); 907 if (pDevice->fRegisteredListeners) 908 drvHstAudCaDeviceUnregisterCallbacks(pThis, pDevice->idDevice); 909 pDevice->hStrUid = hStrUid; 910 pDevice->idDevice = idDefaultDev; 911 pDevice->fRegisteredListeners = drvHstAudCaDeviceRegisterCallbacks(pThis, pDevice->idDevice); 876 912 hStrUid = NULL; 877 913 } … … 890 926 pIHostAudioPort->pfnNotifyDeviceChanged(pIHostAudioPort, fInput ? PDMAUDIODIR_IN : PDMAUDIODIR_OUT, NULL /*pvUser*/); 891 927 } 928 } 929 930 931 /** 932 * Sets the device to use in one or the other direction (@a fInput). 933 * 934 * @returns VBox status code. 935 * @param pThis The core audio driver instance data. 936 * @param pDevice The device info structure to update. 937 * @param fInput Set if input, clear if output. 938 * @param fNotify Whether to notify the parent driver if something 939 * changed. 940 * @param pszUid The UID string for the device to use. NULL or empty 941 * string if default should be used. 942 */ 943 static int drvHstAudCaSetDevice(PDRVHOSTCOREAUDIO pThis, PDRVHSTAUDCADEVICE pDevice, bool fInput, bool fNotify, 944 const char *pszUid) 945 { 946 if (!pszUid || !*pszUid) 947 { 948 /* 949 * Use default. Always refresh the given default device. 950 */ 951 int rc = RTCritSectEnter(&pThis->CritSect); 952 AssertRCReturn(rc, rc); 953 954 if (pDevice->pszSpecific) 955 { 956 LogRel(("CoreAudio: Changing %s device from '%s' to default.\n", fInput ? "input" : "output", pDevice->pszSpecific)); 957 RTStrFree(pDevice->pszSpecific); 958 pDevice->pszSpecific = NULL; 959 } 960 961 RTCritSectLeave(&pThis->CritSect); 962 963 drvHstAudCaUpdateOneDefaultDevice(pThis, pDevice, fInput, fNotify); 964 } 965 else 966 { 967 /* 968 * Use device specified by pszUid. If not change, search for the device 969 * again if idDevice is unknown. 970 */ 971 int rc = RTCritSectEnter(&pThis->CritSect); 972 AssertRCReturn(rc, rc); 973 974 bool fSkip = false; 975 bool fSame = false; 976 if (pDevice->pszSpecific) 977 { 978 if (strcmp(pszUid, pDevice->pszSpecific) != 0) 979 { 980 LogRel(("CoreAudio: Changing %s device from '%s' to '%s'.\n", 981 fInput ? "input" : "output", pDevice->pszSpecific, pszUid)); 982 RTStrFree(pDevice->pszSpecific); 983 pDevice->pszSpecific = NULL; 984 } 985 else 986 { 987 fSkip = pDevice->idDevice != kAudioDeviceUnknown; 988 fSame = true; 989 } 990 } 991 else 992 LogRel(("CoreAudio: Changing %s device from default to '%s'.\n", fInput ? "input" : "output", pszUid)); 993 994 /* 995 * Allocate and swap the strings. This is the bit that might fail. 996 */ 997 if (!fSame) 998 { 999 CFStringRef hStrUid = CFStringCreateWithBytes(NULL /*allocator*/, (UInt8 const *)pszUid, (CFIndex)strlen(pszUid), 1000 kCFStringEncodingUTF8, false /*isExternalRepresentation*/); 1001 char *pszSpecific = RTStrDup(pszUid); 1002 if (hStrUid && pszSpecific) 1003 { 1004 if (pDevice->hStrUid) 1005 CFRelease(pDevice->hStrUid); 1006 pDevice->hStrUid = hStrUid; 1007 RTStrFree(pDevice->pszSpecific); 1008 pDevice->pszSpecific = pszSpecific; 1009 } 1010 else 1011 { 1012 RTCritSectLeave(&pThis->CritSect); 1013 1014 LogFunc(("returns VERR_NO_STR_MEMORY!\n")); 1015 if (hStrUid) 1016 CFRelease(hStrUid); 1017 RTStrFree(pszSpecific); 1018 return VERR_NO_STR_MEMORY; 1019 } 1020 1021 if (pDevice->fRegisteredListeners) 1022 { 1023 drvHstAudCaDeviceUnregisterCallbacks(pThis, pDevice->idDevice); 1024 pDevice->fRegisteredListeners = false; 1025 } 1026 } 1027 1028 /* 1029 * Locate the device ID corresponding to the UID string. 1030 */ 1031 if (!fSkip) 1032 { 1033 pDevice->idDevice = drvHstAudCaDeviceUidToId(pDevice->hStrUid, pszUid, fInput ? "input" : "output"); 1034 pDevice->fRegisteredListeners = drvHstAudCaDeviceRegisterCallbacks(pThis, pDevice->idDevice); 1035 } 1036 1037 PPDMIHOSTAUDIOPORT pIHostAudioPort = fNotify && !fSame ? pThis->pIHostAudioPort : NULL; 1038 RTCritSectLeave(&pThis->CritSect); 1039 1040 /* 1041 * Notify parent driver to trigger a re-init of any associated streams. 1042 */ 1043 if (pIHostAudioPort) 1044 { 1045 LogFlowFunc(("Notifying parent driver about %s device change...\n", fInput ? "input" : "output")); 1046 pIHostAudioPort->pfnNotifyDeviceChanged(pIHostAudioPort, fInput ? PDMAUDIODIR_IN : PDMAUDIODIR_OUT, NULL /*pvUser*/); 1047 } 1048 } 1049 return VINF_SUCCESS; 892 1050 } 893 1051 … … 1152 1310 if (RT_FAILURE(rc)) 1153 1311 PDMAudioHostEnumDelete(pDeviceEnum); 1312 1313 LogFlowFunc(("returns %Rrc\n", rc)); 1314 return rc; 1315 } 1316 1317 1318 /** 1319 * @interface_method_impl{PDMIHOSTAUDIO,pfnSetDevice} 1320 */ 1321 static DECLCALLBACK(int) drvHstAudCaHA_SetDevice(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir, const char *pszId) 1322 { 1323 PDRVHOSTCOREAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTCOREAUDIO, IHostAudio); 1324 AssertPtrNullReturn(pszId, VERR_INVALID_POINTER); 1325 if (pszId && !*pszId) 1326 pszId = NULL; 1327 AssertMsgReturn(enmDir == PDMAUDIODIR_IN || enmDir == PDMAUDIODIR_OUT || enmDir == PDMAUDIODIR_DUPLEX, 1328 ("enmDir=%d\n", enmDir, pszId), VERR_INVALID_PARAMETER); 1329 1330 /* 1331 * Make the change. 1332 */ 1333 int rc = VINF_SUCCESS; 1334 if (enmDir == PDMAUDIODIR_IN || enmDir == PDMAUDIODIR_DUPLEX) 1335 rc = drvHstAudCaSetDevice(pThis, &pThis->InputDevice, true /*fInput*/, true /*fNotify*/, pszId); 1336 if (enmDir == PDMAUDIODIR_OUT || (enmDir == PDMAUDIODIR_DUPLEX && RT_SUCCESS(rc))) 1337 rc = drvHstAudCaSetDevice(pThis, &pThis->OutputDevice, false /*fInput*/, true /*fNotify*/, pszId); 1154 1338 1155 1339 LogFlowFunc(("returns %Rrc\n", rc)); … … 1355 1539 */ 1356 1540 RTCritSectEnter(&pThis->CritSect); 1357 CFStringRef hDevUidStr = pCfgReq->enmDir == PDMAUDIODIR_IN ? pThis-> DefaultInput.hStrUid : pThis->DefaultOutput.hStrUid;1541 CFStringRef hDevUidStr = pCfgReq->enmDir == PDMAUDIODIR_IN ? pThis->InputDevice.hStrUid : pThis->OutputDevice.hStrUid; 1358 1542 if (hDevUidStr) 1359 1543 CFRetain(hDevUidStr); … … 2463 2647 RTCritSectEnter(&pThis->CritSect); 2464 2648 2465 drvHstAudCaDeviceUnregisterCallbacks(pThis, pThis-> DefaultInput.idDevice);2466 pThis-> DefaultInput.idDevice = kAudioDeviceUnknown;2467 2468 drvHstAudCaDeviceUnregisterCallbacks(pThis, pThis-> DefaultOutput.idDevice);2469 pThis-> DefaultOutput.idDevice = kAudioDeviceUnknown;2649 drvHstAudCaDeviceUnregisterCallbacks(pThis, pThis->InputDevice.idDevice); 2650 pThis->InputDevice.idDevice = kAudioDeviceUnknown; 2651 2652 drvHstAudCaDeviceUnregisterCallbacks(pThis, pThis->OutputDevice.idDevice); 2653 pThis->OutputDevice.idDevice = kAudioDeviceUnknown; 2470 2654 2471 2655 RTCritSectLeave(&pThis->CritSect); … … 2574 2758 pThis->IHostAudio.pfnGetConfig = drvHstAudCaHA_GetConfig; 2575 2759 pThis->IHostAudio.pfnGetDevices = drvHstAudCaHA_GetDevices; 2760 pThis->IHostAudio.pfnSetDevice = drvHstAudCaHA_SetDevice; 2576 2761 pThis->IHostAudio.pfnGetStatus = drvHstAudCaHA_GetStatus; 2577 2762 pThis->IHostAudio.pfnDoOnWorkerThread = NULL; … … 2595 2780 * Validate and read configuration. 2596 2781 */ 2597 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "", ""); 2598 /** @todo (bird) Add OutputDeviceID and InputDeviceID, interpret them as 2599 * PDMAUDIOHOSTDEV::pszId values. This should be done for all other devices 2600 * where it is possible to use something other than the default devices 2601 * (e.g. not OSS). 2602 * 2603 * Also, add an optional pfnSetDevice method that does the same only at 2604 * runtime. */ 2782 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "InputDeviceID|OutputDeviceID", ""); 2783 2784 char *pszTmp = NULL; 2785 rc = CFGMR3QueryStringAlloc(pCfg, "InputDeviceID", &pszTmp); 2786 if (RT_SUCCESS(rc)) 2787 { 2788 rc = drvHstAudCaSetDevice(pThis, &pThis->InputDevice, true /*fInput*/, false /*fNotify*/, pszTmp); 2789 MMR3HeapFree(pszTmp); 2790 } 2791 else if (rc != VERR_CFGM_VALUE_NOT_FOUND && rc != VERR_CFGM_NO_PARENT) 2792 return PDMDRV_SET_ERROR(pDrvIns, rc, "Failed to query 'InputDeviceID'"); 2793 2794 rc = CFGMR3QueryStringAlloc(pCfg, "OutputDeviceID", &pszTmp); 2795 if (RT_SUCCESS(rc)) 2796 { 2797 rc = drvHstAudCaSetDevice(pThis, &pThis->OutputDevice, false /*fInput*/, false /*fNotify*/, pszTmp); 2798 MMR3HeapFree(pszTmp); 2799 } 2800 else if (rc != VERR_CFGM_VALUE_NOT_FOUND && rc != VERR_CFGM_NO_PARENT) 2801 return PDMDRV_SET_ERROR(pDrvIns, rc, "Failed to query 'OutputDeviceID'"); 2605 2802 2606 2803 /* … … 2645 2842 * Determin the default devices. 2646 2843 */ 2647 drvHstAudCaUpdateOneDefaultDevice(pThis, &pThis-> DefaultOutput, false /*fInput*/, false /*fNotifty*/);2648 drvHstAudCaUpdateOneDefaultDevice(pThis, &pThis-> DefaultInput, true /*fInput*/, false /*fNotifty*/);2844 drvHstAudCaUpdateOneDefaultDevice(pThis, &pThis->OutputDevice, false /*fInput*/, false /*fNotifty*/); 2845 drvHstAudCaUpdateOneDefaultDevice(pThis, &pThis->InputDevice, true /*fInput*/, false /*fNotifty*/); 2649 2846 2650 2847 /* -
trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp
r89229 r89258 2706 2706 pThis->IHostAudio.pfnGetConfig = drvHostDSoundHA_GetConfig; 2707 2707 pThis->IHostAudio.pfnGetDevices = drvHostDSoundHA_GetDevices; 2708 pThis->IHostAudio.pfnSetDevice = NULL; 2708 2709 pThis->IHostAudio.pfnGetStatus = drvHostDSoundHA_GetStatus; 2709 2710 pThis->IHostAudio.pfnDoOnWorkerThread = NULL; -
trunk/src/VBox/Devices/Audio/DrvHostAudioDebug.cpp
r89213 r89258 318 318 pThis->IHostAudio.pfnGetConfig = drvHostDebugAudioHA_GetConfig; 319 319 pThis->IHostAudio.pfnGetDevices = NULL; 320 pThis->IHostAudio.pfnSetDevice = NULL; 320 321 pThis->IHostAudio.pfnGetStatus = drvHostDebugAudioHA_GetStatus; 321 322 pThis->IHostAudio.pfnDoOnWorkerThread = NULL; -
trunk/src/VBox/Devices/Audio/DrvHostAudioNull.cpp
r89213 r89258 240 240 /* .pfnGetConfig =*/ drvHostNullAudioHA_GetConfig, 241 241 /* .pfnGetDevices =*/ NULL, 242 /* .pfnSetDevice =*/ NULL, 242 243 /* .pfnGetStatus =*/ drvHostNullAudioHA_GetStatus, 243 244 /* .pfnDoOnWorkerThread =*/ NULL, -
trunk/src/VBox/Devices/Audio/DrvHostAudioOss.cpp
r89213 r89258 885 885 pThis->IHostAudio.pfnGetConfig = drvHostOssAudioHA_GetConfig; 886 886 pThis->IHostAudio.pfnGetDevices = NULL; 887 pThis->IHostAudio.pfnSetDevice = NULL; 887 888 pThis->IHostAudio.pfnGetStatus = drvHostOssAudioHA_GetStatus; 888 889 pThis->IHostAudio.pfnDoOnWorkerThread = NULL; -
trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp
r89229 r89258 1931 1931 pThis->IHostAudio.pfnGetConfig = drvHostAudioPaHA_GetConfig; 1932 1932 pThis->IHostAudio.pfnGetDevices = drvHostAudioPaHA_GetDevices; 1933 pThis->IHostAudio.pfnSetDevice = NULL; 1933 1934 pThis->IHostAudio.pfnGetStatus = drvHostAudioPaHA_GetStatus; 1934 1935 pThis->IHostAudio.pfnDoOnWorkerThread = NULL; -
trunk/src/VBox/Devices/Audio/DrvHostAudioValidationKit.cpp
r89213 r89258 439 439 pThis->IHostAudio.pfnGetConfig = drvHostValKitAudioHA_GetConfig; 440 440 pThis->IHostAudio.pfnGetDevices = NULL; 441 pThis->IHostAudio.pfnSetDevice = NULL; 441 442 pThis->IHostAudio.pfnGetStatus = drvHostValKitAudioHA_GetStatus; 442 443 pThis->IHostAudio.pfnDoOnWorkerThread = NULL; -
trunk/src/VBox/Devices/Audio/DrvHostAudioWasApi.cpp
r89229 r89258 2945 2945 pThis->IHostAudio.pfnGetConfig = drvHostAudioWasHA_GetConfig; 2946 2946 pThis->IHostAudio.pfnGetDevices = drvHostAudioWasHA_GetDevices; 2947 pThis->IHostAudio.pfnSetDevice = NULL; 2947 2948 pThis->IHostAudio.pfnGetStatus = drvHostAudioWasHA_GetStatus; 2948 2949 pThis->IHostAudio.pfnDoOnWorkerThread = drvHostAudioWasHA_DoOnWorkerThread;
Note:
See TracChangeset
for help on using the changeset viewer.