Changeset 89532 in vbox
- Timestamp:
- Jun 7, 2021 12:31:09 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp
r89531 r89532 199 199 * Specify UINT32_MAX for unlimited logging. */ 200 200 uint32_t cLogErrors; 201 /** The stream (base) name; needed for distinguishing202 * streams in the PulseAudio mixer controls if multiple203 * VMs are running at the same time. */204 char szStreamName[64];205 201 /** Don't want to put this on the stack... */ 206 202 DRVHSTAUDPASTATECHGCTX InitStateChgCtx; 207 203 /** Pointer to host audio interface. */ 208 204 PDMIHOSTAUDIO IHostAudio; 205 /** Upwards notification interface. */ 206 PPDMIHOSTAUDIOPORT pIHostAudioPort; 207 208 /** The stream (base) name. 209 * This is needed for distinguishing streams in the PulseAudio mixer controls if 210 * multiple VMs are running at the same time. */ 211 char szStreamName[64]; 212 /** The name of the input device to use. Empty string for default. */ 213 char szInputDev[256]; 214 /** The name of the output device to use. Empty string for default. */ 215 char szOutputDev[256]; 209 216 } DRVHSTAUDPA; 210 217 … … 690 697 691 698 /** 699 * @interface_method_impl{PDMIHOSTAUDIO,pfnSetDevice} 700 */ 701 static DECLCALLBACK(int) drvHstAudPaHA_SetDevice(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir, const char *pszId) 702 { 703 PDRVHSTAUDPA pThis = RT_FROM_MEMBER(pInterface, DRVHSTAUDPA, IHostAudio); 704 705 /* 706 * Validate and normalize input. 707 */ 708 AssertReturn(enmDir == PDMAUDIODIR_IN || enmDir == PDMAUDIODIR_OUT || enmDir == PDMAUDIODIR_DUPLEX, VERR_INVALID_PARAMETER); 709 AssertPtrNullReturn(pszId, VERR_INVALID_POINTER); 710 if (!pszId || !*pszId) 711 pszId = ""; 712 else 713 { 714 size_t cch = strlen(pszId); 715 AssertReturn(cch < sizeof(pThis->szInputDev), VERR_INVALID_NAME); 716 } 717 LogFunc(("enmDir=%d pszId=%s\n", enmDir, pszId)); 718 719 /* 720 * Update input. 721 */ 722 if (enmDir == PDMAUDIODIR_IN || enmDir == PDMAUDIODIR_DUPLEX) 723 { 724 pa_threaded_mainloop_lock(pThis->pMainLoop); 725 if (strcmp(pThis->szInputDev, pszId) == 0) 726 pa_threaded_mainloop_unlock(pThis->pMainLoop); 727 else 728 { 729 LogRel(("PulseAudio: Changing input device: '%s' -> '%s'\n", pThis->szInputDev, pszId)); 730 RTStrCopy(pThis->szInputDev, sizeof(pThis->szInputDev), pszId); 731 PPDMIHOSTAUDIOPORT pIHostAudioPort = pThis->pIHostAudioPort; 732 pa_threaded_mainloop_unlock(pThis->pMainLoop); 733 if (pIHostAudioPort) 734 { 735 LogFlowFunc(("Notifying parent driver about input device change...\n")); 736 pIHostAudioPort->pfnNotifyDeviceChanged(pIHostAudioPort, PDMAUDIODIR_IN, NULL /*pvUser*/); 737 } 738 } 739 } 740 741 /* 742 * Update output. 743 */ 744 if (enmDir == PDMAUDIODIR_OUT || enmDir == PDMAUDIODIR_DUPLEX) 745 { 746 pa_threaded_mainloop_lock(pThis->pMainLoop); 747 if (strcmp(pThis->szOutputDev, pszId) == 0) 748 pa_threaded_mainloop_unlock(pThis->pMainLoop); 749 else 750 { 751 LogRel(("PulseAudio: Changing output device: '%s' -> '%s'\n", pThis->szOutputDev, pszId)); 752 RTStrCopy(pThis->szOutputDev, sizeof(pThis->szOutputDev), pszId); 753 PPDMIHOSTAUDIOPORT pIHostAudioPort = pThis->pIHostAudioPort; 754 pa_threaded_mainloop_unlock(pThis->pMainLoop); 755 if (pIHostAudioPort) 756 { 757 LogFlowFunc(("Notifying parent driver about output device change...\n")); 758 pIHostAudioPort->pfnNotifyDeviceChanged(pIHostAudioPort, PDMAUDIODIR_OUT, NULL /*pvUser*/); 759 } 760 } 761 } 762 763 return VINF_SUCCESS; 764 } 765 766 767 768 769 /** 692 770 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetStatus} 693 771 */ … … 954 1032 LogFunc(("Input stream attributes: maxlength=%d fragsize=%d\n", 955 1033 pStreamPA->BufAttr.maxlength, pStreamPA->BufAttr.fragsize)); 956 rc = pa_stream_connect_record(pStream, NULL /*dev*/, &pStreamPA->BufAttr, (pa_stream_flags_t)fFlags); 1034 rc = pa_stream_connect_record(pStream, pThis->szInputDev[0] ? pThis->szInputDev : NULL, 1035 &pStreamPA->BufAttr, (pa_stream_flags_t)fFlags); 957 1036 } 958 1037 else … … 960 1039 LogFunc(("Output buffer attributes: maxlength=%d tlength=%d prebuf=%d minreq=%d\n", 961 1040 pStreamPA->BufAttr.maxlength, pStreamPA->BufAttr.tlength, pStreamPA->BufAttr.prebuf, pStreamPA->BufAttr.minreq)); 962 rc = pa_stream_connect_playback(pStream, NULL /*dev*/, &pStreamPA->BufAttr, (pa_stream_flags_t)fFlags,1041 rc = pa_stream_connect_playback(pStream, pThis->szOutputDev[0] ? pThis->szOutputDev : NULL, &pStreamPA->BufAttr, (pa_stream_flags_t)fFlags, 963 1042 NULL /*volume*/, NULL /*sync_stream*/); 964 1043 } … … 2142 2221 pThis->IHostAudio.pfnGetConfig = drvHstAudPaHA_GetConfig; 2143 2222 pThis->IHostAudio.pfnGetDevices = drvHstAudPaHA_GetDevices; 2144 pThis->IHostAudio.pfnSetDevice = NULL;2223 pThis->IHostAudio.pfnSetDevice = drvHstAudPaHA_SetDevice; 2145 2224 pThis->IHostAudio.pfnGetStatus = drvHstAudPaHA_GetStatus; 2146 2225 pThis->IHostAudio.pfnDoOnWorkerThread = NULL; … … 2165 2244 * Read configuration. 2166 2245 */ 2167 int rc2 = CFGMR3QueryString(pCfg, "VmName", pThis->szStreamName, sizeof(pThis->szStreamName)); 2168 AssertMsgRCReturn(rc2, ("Confguration error: No/bad \"VmName\" value, rc=%Rrc\n", rc2), rc2); 2246 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "VmName|InputDeviceID|OutputDeviceID", ""); 2247 int rc = CFGMR3QueryString(pCfg, "VmName", pThis->szStreamName, sizeof(pThis->szStreamName)); 2248 AssertMsgRCReturn(rc, ("Confguration error: No/bad \"VmName\" value, rc=%Rrc\n", rc), rc); 2249 rc = CFGMR3QueryStringDef(pCfg, "InputDeviceID", pThis->szInputDev, sizeof(pThis->szInputDev), ""); 2250 AssertMsgRCReturn(rc, ("Confguration error: Failed to read \"InputDeviceID\" as string: rc=%Rrc\n", rc), rc); 2251 rc = CFGMR3QueryStringDef(pCfg, "OutputDeviceID", pThis->szOutputDev, sizeof(pThis->szOutputDev), ""); 2252 AssertMsgRCReturn(rc, ("Confguration error: Failed to read \"OutputDeviceID\" as string: rc=%Rrc\n", rc), rc); 2253 2254 /* 2255 * Query the notification interface from the driver/device above us. 2256 */ 2257 pThis->pIHostAudioPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIHOSTAUDIOPORT); 2258 AssertReturn(pThis->pIHostAudioPort, VERR_PDM_MISSING_INTERFACE_ABOVE); 2169 2259 2170 2260 /* 2171 2261 * Load the pulse audio library. 2172 2262 */ 2173 intrc = audioLoadPulseLib();2263 rc = audioLoadPulseLib(); 2174 2264 if (RT_SUCCESS(rc)) 2175 2265 LogRel(("PulseAudio: Using version %s\n", pa_get_library_version()));
Note:
See TracChangeset
for help on using the changeset viewer.