From 736a424ff470334a5657d44054c03717b0116dec Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 27 Jul 2021 13:12:57 -0400 Subject: [PATCH] pulseaudio: Optionally add "monitor" sources to device list. There's a new hint to enable this. Fixes #2917. --- include/SDL_hints.h | 19 +++++++++++++++++++ src/audio/pulseaudio/SDL_pulseaudio.c | 10 ++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 549ed6626..ba043acf2 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -1675,6 +1675,25 @@ extern "C" { */ #define SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING "SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING" +/** + * \brief A variable that causes SDL to not ignore audio "monitors" + * + * This is currently only used for PulseAudio and ignored elsewhere. + * + * By default, SDL ignores audio devices that aren't associated with physical + * hardware. Changing this hint to "1" will expose anything SDL sees that + * appears to be an audio source or sink. This will add "devices" to the list + * that the user probably doesn't want or need, but it can be useful in + * scenarios where you want to hook up SDL to some sort of virtual device, + * etc. + * + * The default value is "0". This hint must be set before SDL_Init(). + * + * This hint is available since SDL 2.0.16. Before then, virtual devices are + * always ignored. + */ +#define SDL_HINT_AUDIO_INCLUDE_MONITORS "SDL_AUDIO_INCLUDE_MONITORS" + /** * \brief An enumeration of hint priorities diff --git a/src/audio/pulseaudio/SDL_pulseaudio.c b/src/audio/pulseaudio/SDL_pulseaudio.c index bb5997ed1..c97f15681 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.c +++ b/src/audio/pulseaudio/SDL_pulseaudio.c @@ -46,6 +46,10 @@ #include "SDL_loadso.h" #include "../../thread/SDL_systhread.h" +/* should we include monitors in the device list? Set at SDL_Init time */ +static SDL_bool include_monitors = SDL_FALSE; + + #if (PA_API_VERSION < 12) /** Return non-zero if the passed state is one of the connected states */ static SDL_INLINE int PA_CONTEXT_IS_GOOD(pa_context_state_t x) { @@ -744,8 +748,8 @@ SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *da { SDL_AudioSpec spec; if (i) { - /* Skip "monitor" sources. These are just output from other sinks. */ - if (i->monitor_of_sink == PA_INVALID_INDEX) { + /* Maybe skip "monitor" sources. These are just output from other sinks. */ + if (include_monitors || (i->monitor_of_sink == PA_INVALID_INDEX)) { spec.freq = i->sample_spec.rate; spec.channels = i->sample_spec.channels; spec.format = PulseFormatToSDLFormat(i->sample_spec.format); @@ -834,6 +838,8 @@ PULSEAUDIO_Init(SDL_AudioDriverImpl * impl) return 0; } + include_monitors = SDL_GetHintBoolean(SDL_HINT_AUDIO_INCLUDE_MONITORS, SDL_FALSE); + /* Set the function pointers */ impl->DetectDevices = PULSEAUDIO_DetectDevices; impl->OpenDevice = PULSEAUDIO_OpenDevice;