Skip to content

Commit

Permalink
hints: Allow specifying audio device metadata.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
icculus committed May 4, 2020
1 parent 11fef29 commit 8601996
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 8 deletions.
42 changes: 42 additions & 0 deletions include/SDL_hints.h
Expand Up @@ -1306,6 +1306,48 @@ extern "C" {
*/
#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
*/
Expand Down
24 changes: 16 additions & 8 deletions src/audio/pulseaudio/SDL_pulseaudio.c
Expand Up @@ -27,6 +27,7 @@
*/
#include "../../SDL_internal.h"
#include "SDL_assert.h"
#include "SDL_hints.h"

#if SDL_AUDIO_DRIVER_PULSEAUDIO

Expand Down Expand Up @@ -237,16 +238,20 @@ squashVersion(const int major, const int minor, const int patch)
static const char *
getAppName(void)
{
const char *verstr = PULSEAUDIO_pa_get_library_version();
if (verstr != NULL) {
int maj, min, patch;
if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) {
if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) {
return NULL; /* 0.9.15+ handles NULL correctly. */
const char *retval = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
if (!retval || !*retval) {
const char *verstr = PULSEAUDIO_pa_get_library_version();
retval = "SDL Application"; /* the "oh well" default. */
if (verstr != NULL) {
int maj, min, patch;
if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) {
if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) {
retval = NULL; /* 0.9.15+ handles NULL correctly. */
}
}
}
}
return "SDL Application"; /* oh well. */
return retval;
}

static void
Expand Down Expand Up @@ -513,6 +518,7 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
pa_buffer_attr paattr;
pa_channel_map pacmap;
pa_stream_flags_t flags = 0;
const char *name = NULL;
int state = 0;
int rc = 0;

Expand Down Expand Up @@ -615,9 +621,11 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels,
PA_CHANNEL_MAP_WAVEEX);

name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME);

h->stream = PULSEAUDIO_pa_stream_new(
h->context,
"Simple DirectMedia Layer", /* stream description */
(name && *name) ? name : "Audio Stream", /* stream description */
&paspec, /* sample format spec */
&pacmap /* channel map */
);
Expand Down

0 comments on commit 8601996

Please sign in to comment.