Changeset 88371 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Apr 6, 2021 1:45:57 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 143618
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp
r88362 r88371 21 21 *********************************************************************************************************************************/ 22 22 #define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO 23 #define INITGUID 23 24 #include <VBox/log.h> 24 25 #include <iprt/win/windows.h> 25 26 #include <dsound.h> 27 #include <Mmdeviceapi.h> 28 #include <functiondiscoverykeys_devpkey.h> 26 29 27 30 #include <iprt/alloc.h> … … 59 62 * Messages which always should go to the release log use LogRel. 60 63 */ 61 /* General code behavior. */64 /** General code behavior. */ 62 65 #define DSLOG(a) do { LogRel2(a); } while(0) 63 /* Something which produce a lot of logging during playback/recording. */66 /** Something which produce a lot of logging during playback/recording. */ 64 67 #define DSLOGF(a) do { LogRel3(a); } while(0) 65 /* Important messages like errors. Limited in the default release log to avoid log flood. */68 /** Important messages like errors. Limited in the default release log to avoid log flood. */ 66 69 #define DSLOGREL(a) \ 67 70 do { \ … … 215 218 /** List of devices of last enumeration. */ 216 219 PDMAUDIOHOSTENUM DeviceEnum; 217 /** Whether this backend supports any audio input. */ 220 /** Whether this backend supports any audio input. 221 * @todo r=bird: This is not actually used for anything. */ 218 222 bool fEnabledIn; 219 /** Whether this backend supports any audio output. */ 223 /** Whether this backend supports any audio output. 224 * @todo r=bird: This is not actually used for anything. */ 220 225 bool fEnabledOut; 221 226 /** The Direct Sound playback interface. */ … … 639 644 wfx.cbSize)); 640 645 646 /** @todo r=bird: Why is this called every time? It triggers a device 647 * enumeration. Andy claimed on IRC that enumeration was only done once... 648 * It's generally a 'ing waste of time here too, as we dont really use any of 649 * the information we gather there. */ 641 650 dsoundUpdateStatusInternal(pThis); 642 651 … … 1380 1389 return E_INVALIDARG; 1381 1390 1391 /** @todo r=bird: Why is this called every time? It triggers a device 1392 * enumeration. Andy claimed on IRC that enumeration was only done once... */ 1382 1393 dsoundUpdateStatusInternal(pThis); 1383 1394 … … 1569 1580 * @param lpContext Pointer to PDSOUNDENUMCBCTX context for storing the enumerated information. 1570 1581 * 1571 * @note Carbon copy of dsoundDevicesEnumCb Playbackwith OUT direction.1582 * @note Carbon copy of dsoundDevicesEnumCbCapture with OUT direction. 1572 1583 */ 1573 1584 static BOOL CALLBACK dsoundDevicesEnumCbPlayback(LPGUID pGUID, LPCWSTR pwszDescription, LPCWSTR pwszModule, PVOID lpContext) … … 1775 1786 } 1776 1787 1788 1789 /** 1790 * Queries information for @a pDevice and adds an entry to the enumeration. 1791 * 1792 * @returns VBox status code. 1793 * @param pDevEnm The enumeration to add the device to. 1794 * @param pDevice The device. 1795 * @param enmType The type of device. 1796 * @param fDefault Whether it's the default device. 1797 */ 1798 static int dsoundDeviceNewStyleAdd(PPDMAUDIOHOSTENUM pDevEnm, IMMDevice *pDevice, EDataFlow enmType, bool fDefault) 1799 { 1800 int rc = VINF_SUCCESS; /* ignore most errors */ 1801 1802 /* 1803 * Gather the necessary properties. 1804 */ 1805 IPropertyStore *pProperties = NULL; 1806 HRESULT hrc = pDevice->OpenPropertyStore(STGM_READ, &pProperties); 1807 if (SUCCEEDED(hrc)) 1808 { 1809 /* Get the friendly name. */ 1810 PROPVARIANT VarName; 1811 PropVariantInit(&VarName); 1812 hrc = pProperties->GetValue(PKEY_Device_FriendlyName, &VarName); 1813 if (SUCCEEDED(hrc)) 1814 { 1815 /* Get the DirectSound GUID. */ 1816 PROPVARIANT VarGUID; 1817 PropVariantInit(&VarGUID); 1818 hrc = pProperties->GetValue(PKEY_AudioEndpoint_GUID, &VarGUID); 1819 if (SUCCEEDED(hrc)) 1820 { 1821 /* Get the device format. */ 1822 PROPVARIANT VarFormat; 1823 PropVariantInit(&VarFormat); 1824 hrc = pProperties->GetValue(PKEY_AudioEngine_DeviceFormat, &VarFormat); 1825 if (SUCCEEDED(hrc)) 1826 { 1827 WAVEFORMATEX const * const pFormat = (WAVEFORMATEX const *)VarFormat.blob.pBlobData; 1828 AssertPtr(pFormat); 1829 1830 /* 1831 * Create a enumeration entry for it. 1832 */ 1833 PDSOUNDDEV pDev = (PDSOUNDDEV)PDMAudioHostDevAlloc(sizeof(DSOUNDDEV)); 1834 if (pDev) 1835 { 1836 pDev->Core.enmUsage = enmType == eRender ? PDMAUDIODIR_OUT : PDMAUDIODIR_IN; 1837 pDev->Core.enmType = PDMAUDIODEVICETYPE_BUILTIN; 1838 if (enmType == eRender) 1839 pDev->Core.cMaxOutputChannels = pFormat->nChannels; 1840 else 1841 pDev->Core.cMaxInputChannels = pFormat->nChannels; 1842 1843 RT_NOREF(fDefault); 1844 //if (fDefault) 1845 hrc = UuidFromStringW(VarGUID.pwszVal, &pDev->Guid); 1846 if (SUCCEEDED(hrc)) 1847 { 1848 char *pszName; 1849 rc = RTUtf16ToUtf8(VarName.pwszVal, &pszName); 1850 if (RT_SUCCESS(rc)) 1851 { 1852 RTStrCopy(pDev->Core.szName, sizeof(pDev->Core.szName), pszName); 1853 RTStrFree(pszName); 1854 1855 PDMAudioHostEnumAppend(pDevEnm, &pDev->Core); 1856 } 1857 else 1858 PDMAudioHostDevFree(&pDev->Core); 1859 } 1860 else 1861 { 1862 LogFunc(("UuidFromStringW(%ls): %Rhrc\n", VarGUID.pwszVal, hrc)); 1863 PDMAudioHostDevFree(&pDev->Core); 1864 } 1865 } 1866 else 1867 rc = VERR_NO_MEMORY; 1868 PropVariantClear(&VarFormat); 1869 } 1870 else 1871 LogFunc(("Failed to get PKEY_AudioEngine_DeviceFormat: %Rhrc\n", hrc)); 1872 PropVariantClear(&VarGUID); 1873 } 1874 else 1875 LogFunc(("Failed to get PKEY_AudioEndpoint_GUID: %Rhrc\n", hrc)); 1876 PropVariantClear(&VarName); 1877 } 1878 else 1879 LogFunc(("Failed to get PKEY_Device_FriendlyName: %Rhrc\n", hrc)); 1880 pProperties->Release(); 1881 } 1882 else 1883 LogFunc(("OpenPropertyStore failed: %Rhrc\n", hrc)); 1884 1885 if (hrc == E_OUTOFMEMORY && RT_SUCCESS_NP(rc)) 1886 rc = VERR_NO_MEMORY; 1887 return rc; 1888 } 1889 1777 1890 /** 1778 1891 * Does a (Re-)enumeration of the host's playback + capturing devices. … … 1789 1902 DSLOG(("DSound: Enumerating devices ...\n")); 1790 1903 1904 /* 1905 * Use the Vista+ API. 1906 */ 1907 IMMDeviceEnumerator *pEnumerator; 1908 HRESULT hrc = CoCreateInstance(__uuidof(MMDeviceEnumerator), 0, CLSCTX_ALL, 1909 __uuidof(IMMDeviceEnumerator), (void **)&pEnumerator); 1910 if (SUCCEEDED(hrc)) 1911 { 1912 int rc = VINF_SUCCESS; 1913 for (unsigned idxPass = 0; idxPass < 2 && RT_SUCCESS(rc); idxPass++) 1914 { 1915 EDataFlow const enmType = idxPass == 0 ? EDataFlow::eRender : EDataFlow::eCapture; 1916 1917 /* Get the default device first. */ 1918 IMMDevice *pDefaultDevice = NULL; 1919 hrc = pEnumerator->GetDefaultAudioEndpoint(enmType, eMultimedia, &pDefaultDevice); 1920 if (SUCCEEDED(hrc)) 1921 rc = dsoundDeviceNewStyleAdd(pDevEnm, pDefaultDevice, enmType, true); 1922 else 1923 pDefaultDevice = NULL; 1924 1925 /* Enumerate the devices. */ 1926 IMMDeviceCollection *pCollection = NULL; 1927 hrc = pEnumerator->EnumAudioEndpoints(enmType, DEVICE_STATE_ACTIVE /*| DEVICE_STATE_UNPLUGGED?*/, &pCollection); 1928 if (SUCCEEDED(hrc) && pCollection != NULL) 1929 { 1930 UINT cDevices = 0; 1931 hrc = pCollection->GetCount(&cDevices); 1932 if (SUCCEEDED(hrc)) 1933 { 1934 for (UINT idxDevice = 0; idxDevice < cDevices && RT_SUCCESS(rc); idxDevice++) 1935 { 1936 IMMDevice *pDevice = NULL; 1937 hrc = pCollection->Item(idxDevice, &pDevice); 1938 if (SUCCEEDED(hrc) && pDevice) 1939 { 1940 if (pDevice != pDefaultDevice) 1941 rc = dsoundDeviceNewStyleAdd(pDevEnm, pDevice, enmType, false); 1942 pDevice->Release(); 1943 } 1944 } 1945 } 1946 pCollection->Release(); 1947 } 1948 else 1949 LogRelMax(10, ("EnumAudioEndpoints(%s) failed: %Rhrc\n", idxPass == 0 ? "output" : "input", hrc)); 1950 1951 if (pDefaultDevice) 1952 pDefaultDevice->Release(); 1953 } 1954 pEnumerator->Release(); 1955 if (pDevEnm->cDevices > 0 || RT_FAILURE(rc)) 1956 { 1957 DSLOG(("DSound: Enumerating devices done - %u device (%Rrc)\n", pDevEnm->cDevices, rc)); 1958 return rc; 1959 } 1960 } 1961 1962 /* 1963 * Fall back on dsound. 1964 */ 1791 1965 RTLDRMOD hDSound = NULL; 1792 1966 int rc = RTLdrLoadSystem("dsound.dll", true /*fNoUnload*/, &hDSound); … … 1855 2029 * state and all connected (native) audio streams. 1856 2030 * 2031 * @todo r=bird: This is a 'ing waste of 'ing time! We're doing this everytime 2032 * an 'ing stream is created and we doesn't 'ing use the information here 2033 * for any darn thing! Given the reported slowness of enumeration and 2034 * issues with eh 'ing code the only appropriate response is: 2035 * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARG!!!!!!! 2036 * 1857 2037 * @param pThis Host audio driver instance. 1858 2038 */ 1859 2039 static void dsoundUpdateStatusInternal(PDRVHOSTDSOUND pThis) 1860 2040 { 2041 #if 0 /** @todo r=bird: This isn't doing *ANYTHING* useful. So, I've just disabled it. */ 1861 2042 AssertPtrReturnVoid(pThis); 1862 /* pCfg is optional. */1863 1864 2043 LogFlowFuncEnter(); 1865 2044 2045 PDMAudioHostEnumDelete(&pThis->DeviceEnum); 1866 2046 int rc = dsoundDevicesEnumerate(pThis, &pThis->DeviceEnum); 1867 2047 if (RT_SUCCESS(rc)) … … 1880 2060 1881 2061 LogFlowFuncLeaveRC(rc); 2062 #else 2063 RT_NOREF(pThis); 2064 #endif 1882 2065 } 1883 2066
Note:
See TracChangeset
for help on using the changeset viewer.