hints: Allow specifying audio device metadata.

This is only supported on PulseAudio. You can set a description when opening
your audio device that will show up in pauvcontrol, which lets you set
per-stream volume levels.

Fixes Bugzilla #4801.
This commit is contained in:
Ryan C. Gordon 2020-05-03 22:13:48 -04:00
parent 11fef299d1
commit 8601996fbc
2 changed files with 58 additions and 8 deletions

View File

@ -1306,6 +1306,48 @@ extern "C" {
*/ */
#define SDL_HINT_DISPLAY_USABLE_BOUNDS "SDL_DISPLAY_USABLE_BOUNDS" #define SDL_HINT_DISPLAY_USABLE_BOUNDS "SDL_DISPLAY_USABLE_BOUNDS"
/**
* \brief Specify an application name for an audio device.
*
* Some audio backends (such as PulseAudio) allow you to describe your audio
* stream. Among other things, this description might show up in a system
* control panel that lets the user adjust the volume on specific audio
* streams instead of using one giant master volume slider.
*
* This hints lets you transmit that information to the OS. The contents of
* this hint are used while opening an audio device. You should use a string
* that describes your program ("My Game 2: The Revenge")
*
* Setting this to "" or leaving it unset will have SDL use a reasonable
* default: probably the application's name or "SDL Application" if SDL
* doesn't have any better information.
*
* On targets where this is not supported, this hint does nothing.
*/
#define SDL_HINT_AUDIO_DEVICE_APP_NAME "SDL_AUDIO_DEVICE_APP_NAME"
/**
* \brief Specify an application name for an audio device.
*
* Some audio backends (such as PulseAudio) allow you to describe your audio
* stream. Among other things, this description might show up in a system
* control panel that lets the user adjust the volume on specific audio
* streams instead of using one giant master volume slider.
*
* This hints lets you transmit that information to the OS. The contents of
* this hint are used while opening an audio device. You should use a string
* that describes your what your program is playing ("audio stream" is
* probably sufficient in many cases, but this could be useful for something
* like "team chat" if you have a headset playing VoIP audio separately).
*
* Setting this to "" or leaving it unset will have SDL use a reasonable
* default: "audio stream" or something similar.
*
* On targets where this is not supported, this hint does nothing.
*/
#define SDL_HINT_AUDIO_DEVICE_STREAM_NAME "SDL_AUDIO_DEVICE_STREAM_NAME"
/** /**
* \brief An enumeration of hint priorities * \brief An enumeration of hint priorities
*/ */

View File

@ -27,6 +27,7 @@
*/ */
#include "../../SDL_internal.h" #include "../../SDL_internal.h"
#include "SDL_assert.h" #include "SDL_assert.h"
#include "SDL_hints.h"
#if SDL_AUDIO_DRIVER_PULSEAUDIO #if SDL_AUDIO_DRIVER_PULSEAUDIO
@ -237,16 +238,20 @@ squashVersion(const int major, const int minor, const int patch)
static const char * static const char *
getAppName(void) getAppName(void)
{ {
const char *retval = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
if (!retval || !*retval) {
const char *verstr = PULSEAUDIO_pa_get_library_version(); const char *verstr = PULSEAUDIO_pa_get_library_version();
retval = "SDL Application"; /* the "oh well" default. */
if (verstr != NULL) { if (verstr != NULL) {
int maj, min, patch; int maj, min, patch;
if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) { if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) {
if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) { if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) {
return NULL; /* 0.9.15+ handles NULL correctly. */ retval = NULL; /* 0.9.15+ handles NULL correctly. */
} }
} }
} }
return "SDL Application"; /* oh well. */ }
return retval;
} }
static void static void
@ -513,6 +518,7 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
pa_buffer_attr paattr; pa_buffer_attr paattr;
pa_channel_map pacmap; pa_channel_map pacmap;
pa_stream_flags_t flags = 0; pa_stream_flags_t flags = 0;
const char *name = NULL;
int state = 0; int state = 0;
int rc = 0; int rc = 0;
@ -615,9 +621,11 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels, PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels,
PA_CHANNEL_MAP_WAVEEX); PA_CHANNEL_MAP_WAVEEX);
name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME);
h->stream = PULSEAUDIO_pa_stream_new( h->stream = PULSEAUDIO_pa_stream_new(
h->context, h->context,
"Simple DirectMedia Layer", /* stream description */ (name && *name) ? name : "Audio Stream", /* stream description */
&paspec, /* sample format spec */ &paspec, /* sample format spec */
&pacmap /* channel map */ &pacmap /* channel map */
); );