hints: Allow specifying audio device metadata.
authorRyan C. Gordon <icculus@icculus.org>
Sun, 03 May 2020 22:13:48 -0400
changeset 137874d04f91e1776
parent 13786 b176e7ebf6c5
child 13788 56eb55f090f3
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.
include/SDL_hints.h
src/audio/pulseaudio/SDL_pulseaudio.c
     1.1 --- a/include/SDL_hints.h	Sun May 03 20:56:18 2020 -0400
     1.2 +++ b/include/SDL_hints.h	Sun May 03 22:13:48 2020 -0400
     1.3 @@ -1307,6 +1307,48 @@
     1.4  #define SDL_HINT_DISPLAY_USABLE_BOUNDS "SDL_DISPLAY_USABLE_BOUNDS"
     1.5  
     1.6  /**
     1.7 + *  \brief Specify an application name for an audio device.
     1.8 + *
     1.9 + * Some audio backends (such as PulseAudio) allow you to describe your audio
    1.10 + * stream. Among other things, this description might show up in a system
    1.11 + * control panel that lets the user adjust the volume on specific audio
    1.12 + * streams instead of using one giant master volume slider.
    1.13 + *
    1.14 + * This hints lets you transmit that information to the OS. The contents of
    1.15 + * this hint are used while opening an audio device. You should use a string
    1.16 + * that describes your program ("My Game 2: The Revenge")
    1.17 + *
    1.18 + * Setting this to "" or leaving it unset will have SDL use a reasonable
    1.19 + * default: probably the application's name or "SDL Application" if SDL
    1.20 + * doesn't have any better information.
    1.21 + *
    1.22 + * On targets where this is not supported, this hint does nothing.
    1.23 + */
    1.24 +#define SDL_HINT_AUDIO_DEVICE_APP_NAME "SDL_AUDIO_DEVICE_APP_NAME"
    1.25 +
    1.26 +/**
    1.27 + *  \brief Specify an application name for an audio device.
    1.28 + *
    1.29 + * Some audio backends (such as PulseAudio) allow you to describe your audio
    1.30 + * stream. Among other things, this description might show up in a system
    1.31 + * control panel that lets the user adjust the volume on specific audio
    1.32 + * streams instead of using one giant master volume slider.
    1.33 + *
    1.34 + * This hints lets you transmit that information to the OS. The contents of
    1.35 + * this hint are used while opening an audio device. You should use a string
    1.36 + * that describes your what your program is playing ("audio stream" is
    1.37 + * probably sufficient in many cases, but this could be useful for something
    1.38 + * like "team chat" if you have a headset playing VoIP audio separately).
    1.39 + *
    1.40 + * Setting this to "" or leaving it unset will have SDL use a reasonable
    1.41 + * default: "audio stream" or something similar.
    1.42 + *
    1.43 + * On targets where this is not supported, this hint does nothing.
    1.44 + */
    1.45 +#define SDL_HINT_AUDIO_DEVICE_STREAM_NAME "SDL_AUDIO_DEVICE_STREAM_NAME"
    1.46 +
    1.47 +
    1.48 +/**
    1.49   *  \brief  An enumeration of hint priorities
    1.50   */
    1.51  typedef enum
     2.1 --- a/src/audio/pulseaudio/SDL_pulseaudio.c	Sun May 03 20:56:18 2020 -0400
     2.2 +++ b/src/audio/pulseaudio/SDL_pulseaudio.c	Sun May 03 22:13:48 2020 -0400
     2.3 @@ -27,6 +27,7 @@
     2.4  */
     2.5  #include "../../SDL_internal.h"
     2.6  #include "SDL_assert.h"
     2.7 +#include "SDL_hints.h"
     2.8  
     2.9  #if SDL_AUDIO_DRIVER_PULSEAUDIO
    2.10  
    2.11 @@ -237,16 +238,20 @@
    2.12  static const char *
    2.13  getAppName(void)
    2.14  {
    2.15 -    const char *verstr = PULSEAUDIO_pa_get_library_version();
    2.16 -    if (verstr != NULL) {
    2.17 -        int maj, min, patch;
    2.18 -        if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) {
    2.19 -            if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) {
    2.20 -                return NULL;  /* 0.9.15+ handles NULL correctly. */
    2.21 +    const char *retval = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
    2.22 +    if (!retval || !*retval) {
    2.23 +        const char *verstr = PULSEAUDIO_pa_get_library_version();
    2.24 +        retval = "SDL Application";  /* the "oh well" default. */
    2.25 +        if (verstr != NULL) {
    2.26 +            int maj, min, patch;
    2.27 +            if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) {
    2.28 +                if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) {
    2.29 +                    retval = NULL;  /* 0.9.15+ handles NULL correctly. */
    2.30 +                }
    2.31              }
    2.32          }
    2.33      }
    2.34 -    return "SDL Application";  /* oh well. */
    2.35 +    return retval;
    2.36  }
    2.37  
    2.38  static void
    2.39 @@ -513,6 +518,7 @@
    2.40      pa_buffer_attr paattr;
    2.41      pa_channel_map pacmap;
    2.42      pa_stream_flags_t flags = 0;
    2.43 +    const char *name = NULL;
    2.44      int state = 0;
    2.45      int rc = 0;
    2.46  
    2.47 @@ -615,9 +621,11 @@
    2.48      PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels,
    2.49                                          PA_CHANNEL_MAP_WAVEEX);
    2.50  
    2.51 +    name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME);
    2.52 +
    2.53      h->stream = PULSEAUDIO_pa_stream_new(
    2.54          h->context,
    2.55 -        "Simple DirectMedia Layer", /* stream description */
    2.56 +        (name && *name) ? name : "Audio Stream", /* stream description */
    2.57          &paspec,    /* sample format spec */
    2.58          &pacmap     /* channel map */
    2.59          );