Changeset 89596 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Jun 10, 2021 11:37:53 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145039
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostAudioWasApi.cpp
r89551 r89596 232 232 /** The upwards interface. */ 233 233 PPDMIHOSTAUDIOPORT pIHostAudioPort; 234 /** The output device ID, NULL for default. */ 234 /** The output device ID, NULL for default. 235 * Protected by DrvHostAudioWasMmNotifyClient::m_CritSect. */ 235 236 PRTUTF16 pwszOutputDevId; 236 /** The input device ID, NULL for default. */ 237 /** The input device ID, NULL for default. 238 * Protected by DrvHostAudioWasMmNotifyClient::m_CritSect. */ 237 239 PRTUTF16 pwszInputDevId; 238 240 … … 1662 1664 1663 1665 /** 1666 * Worker for drvHostAudioWasHA_SetDevice. 1667 */ 1668 static int drvHostAudioWasSetDeviceWorker(PDRVHOSTAUDIOWAS pThis, const char *pszId, PRTUTF16 *ppwszDevId, IMMDevice **ppIDevice, 1669 EDataFlow enmFlow, PDMAUDIODIR enmDir, const char *pszWhat) 1670 { 1671 pThis->pNotifyClient->lockEnter(); 1672 1673 /* 1674 * Did anything actually change? 1675 */ 1676 if ( (pszId == NULL) != (*ppwszDevId == NULL) 1677 || ( pszId 1678 && RTUtf16ICmpUtf8(*ppwszDevId, pszId) != 0)) 1679 { 1680 /* 1681 * Duplicate the ID. 1682 */ 1683 PRTUTF16 pwszDevId = NULL; 1684 if (pszId) 1685 { 1686 int rc = RTStrToUtf16(pszId, &pwszDevId); 1687 AssertRCReturnStmt(rc, pThis->pNotifyClient->lockLeave(), rc); 1688 } 1689 1690 /* 1691 * Try get the device. 1692 */ 1693 IMMDevice *pIDevice = NULL; 1694 HRESULT hrc; 1695 if (pwszDevId) 1696 hrc = pThis->pIEnumerator->GetDevice(pwszDevId, &pIDevice); 1697 else 1698 hrc = pThis->pIEnumerator->GetDefaultAudioEndpoint(enmFlow, eMultimedia, &pIDevice); 1699 LogFlowFunc(("Got device %p (%Rhrc)\n", pIDevice, hrc)); 1700 if (FAILED(hrc)) 1701 { 1702 LogRel(("WasAPI: Failed to get IMMDevice for %s audio device '%s' (SetDevice): %Rhrc\n", 1703 pszWhat, pszId ? pszId : "{default}", hrc)); 1704 pIDevice = NULL; 1705 } 1706 1707 /* 1708 * Make the switch. 1709 */ 1710 LogRel(("PulseAudio: Changing %s device: '%ls' -> '%s'\n", 1711 pszWhat, *ppwszDevId ? *ppwszDevId : L"{Default}", pszId ? pszId : "{Default}")); 1712 1713 if (*ppIDevice) 1714 (*ppIDevice)->Release(); 1715 *ppIDevice = pIDevice; 1716 1717 RTUtf16Free(*ppwszDevId); 1718 *ppwszDevId = pwszDevId; 1719 1720 /* 1721 * Only notify the driver above us. 1722 */ 1723 PPDMIHOSTAUDIOPORT const pIHostAudioPort = pThis->pIHostAudioPort; 1724 pThis->pNotifyClient->lockLeave(); 1725 1726 if (pIHostAudioPort) 1727 { 1728 LogFlowFunc(("Notifying parent driver about %s device change...\n", pszWhat)); 1729 pIHostAudioPort->pfnNotifyDeviceChanged(pIHostAudioPort, enmDir, NULL); 1730 } 1731 } 1732 else 1733 { 1734 pThis->pNotifyClient->lockLeave(); 1735 LogFunc(("No %s device change\n", pszWhat)); 1736 } 1737 1738 return VINF_SUCCESS; 1739 } 1740 1741 1742 /** 1743 * @interface_method_impl{PDMIHOSTAUDIO,pfnSetDevice} 1744 */ 1745 static DECLCALLBACK(int) drvHostAudioWasHA_SetDevice(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir, const char *pszId) 1746 { 1747 PDRVHOSTAUDIOWAS pThis = RT_FROM_MEMBER(pInterface, DRVHOSTAUDIOWAS, IHostAudio); 1748 1749 /* 1750 * Validate and normalize input. 1751 */ 1752 AssertReturn(enmDir == PDMAUDIODIR_IN || enmDir == PDMAUDIODIR_OUT || enmDir == PDMAUDIODIR_DUPLEX, VERR_INVALID_PARAMETER); 1753 AssertPtrNullReturn(pszId, VERR_INVALID_POINTER); 1754 if (!pszId || !*pszId) 1755 pszId = NULL; 1756 else 1757 AssertReturn(strlen(pszId) < 1024, VERR_INVALID_NAME); 1758 LogFunc(("enmDir=%d pszId=%s\n", enmDir, pszId)); 1759 1760 /* 1761 * Do the updating. 1762 */ 1763 if (enmDir == PDMAUDIODIR_IN || enmDir == PDMAUDIODIR_DUPLEX) 1764 { 1765 int rc = drvHostAudioWasSetDeviceWorker(pThis, pszId, &pThis->pwszInputDevId, &pThis->pIDeviceInput, 1766 eCapture, PDMAUDIODIR_IN, "input"); 1767 AssertRCReturn(rc, rc); 1768 } 1769 1770 if (enmDir == PDMAUDIODIR_OUT || enmDir == PDMAUDIODIR_DUPLEX) 1771 { 1772 int rc = drvHostAudioWasSetDeviceWorker(pThis, pszId, &pThis->pwszOutputDevId, &pThis->pIDeviceOutput, 1773 eRender, PDMAUDIODIR_OUT, "output"); 1774 AssertRCReturn(rc, rc); 1775 } 1776 1777 return VINF_SUCCESS; 1778 } 1779 1780 1781 /** 1664 1782 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetStatus} 1665 1783 */ … … 1864 1982 if (!pIDevice) 1865 1983 { 1866 /** @todo we can eliminate this too... */ 1984 /* This might not strictly be necessary anymore, however it shouldn't 1985 hurt and may be useful when using specific devices. */ 1867 1986 HRESULT hrc; 1868 1987 if (pwszDevId) … … 2988 3107 pThis->IHostAudio.pfnGetConfig = drvHostAudioWasHA_GetConfig; 2989 3108 pThis->IHostAudio.pfnGetDevices = drvHostAudioWasHA_GetDevices; 2990 pThis->IHostAudio.pfnSetDevice = NULL;3109 pThis->IHostAudio.pfnSetDevice = drvHostAudioWasHA_SetDevice; 2991 3110 pThis->IHostAudio.pfnGetStatus = drvHostAudioWasHA_GetStatus; 2992 3111 pThis->IHostAudio.pfnDoOnWorkerThread = drvHostAudioWasHA_DoOnWorkerThread; … … 3011 3130 * Validate and read the configuration. 3012 3131 */ 3013 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "VmName|VmUuid", ""); 3014 /** @todo make it possible to override the default device selection. */ 3132 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "VmName|VmUuid|InputDeviceID|OutputDeviceID", ""); 3133 3134 char szTmp[1024]; 3135 int rc = CFGMR3QueryStringDef(pCfg, "InputDeviceID", szTmp, sizeof(szTmp), ""); 3136 AssertMsgRCReturn(rc, ("Confguration error: Failed to read \"InputDeviceID\" as string: rc=%Rrc\n", rc), rc); 3137 if (szTmp[0]) 3138 { 3139 rc = RTStrToUtf16(szTmp, &pThis->pwszInputDevId); 3140 AssertRCReturn(rc, rc); 3141 } 3142 3143 rc = CFGMR3QueryStringDef(pCfg, "OutputDeviceID", szTmp, sizeof(szTmp), ""); 3144 AssertMsgRCReturn(rc, ("Confguration error: Failed to read \"OutputDeviceID\" as string: rc=%Rrc\n", rc), rc); 3145 if (szTmp[0]) 3146 { 3147 rc = RTStrToUtf16(szTmp, &pThis->pwszOutputDevId); 3148 AssertRCReturn(rc, rc); 3149 } 3015 3150 3016 3151 AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER, … … 3021 3156 * Initialize the critical sections early. 3022 3157 */ 3023 intrc = RTCritSectRwInit(&pThis->CritSectStreamList);3158 rc = RTCritSectRwInit(&pThis->CritSectStreamList); 3024 3159 AssertRCReturn(rc, rc); 3025 3160
Note:
See TracChangeset
for help on using the changeset viewer.