Support "media role" property for PulseAudio devices
authorSteve Youngs <steve@sxemacs.org>
Mon, 25 Jun 2012 03:41:45 +0000 (13:41 +1000)
committerSteve Youngs <steve@sxemacs.org>
Mon, 25 Jun 2012 03:41:45 +0000 (13:41 +1000)
With PulseAudio a client can set various properties to tell the server
more about the client.  One of these properties is a "media role" which
tells the PulseAudio server what type of media the client is supplying.
For example a mp3 player might set a role of "music", or a movie player
might set a role of "video".

You can't do anything in SXEmacs with roles other than set them, but in
your PulseAudio config you can then do nifty things based on them.  Like,
you can get PulseAudio to mute (cork) your "music" streams when you play a
"video" stream.

This changeset allows the user to set the media role via the `:role'
keyword in #'make-audio-device.

* src/media/sound-pulse.c (sound_pulse_data_s): Add new object,
`role'.

* src/media/sound-pulse.c (sound_pulse_create): Parse :role as
well.

* src/media/sound-pulse.c (sound_pulse_finish):

* src/media/sound-pulse.c (sound_pulse_init_mainloop): Set
PULSE_PROP_media.role with the role.

* src/media/sound.c (Fmake_audio_device): Document PulseAudio
roles.

Signed-off-by: Steve Youngs <steve@sxemacs.org>
src/media/sound-pulse.c
src/media/sound.c

index f51bcf2..a6d4fa7 100644 (file)
@@ -80,6 +80,7 @@ time_ev_cb(pa_mainloop_api*, pa_time_event*, const struct timeval*, void*);
 struct sound_pulse_data_s {
        Lisp_Object stream; /* media has to deal with this actually */
        Lisp_Object client;
+       Lisp_Object role;
        Lisp_Object sink;
        Lisp_Object source;
        Lisp_Object server;
@@ -228,6 +229,7 @@ sound_pulse_create(Lisp_Object pulse_options)
        Lisp_Object opt_sink = Qnil;
        Lisp_Object opt_source = Qnil;
        Lisp_Object opt_client = Qnil;
+       Lisp_Object opt_role = Qnil;
        Lisp_Object opt_stream = Qnil;
        Lisp_Object opt_immediate = Qnil;
        Lisp_Object opt_threaded = Qnil;
@@ -252,6 +254,12 @@ sound_pulse_create(Lisp_Object pulse_options)
                return NULL;
        }
 
+       opt_role = Fplist_get(pulse_options, intern(":role"), Qnil);
+       if (!NILP(opt_role) && !STRINGP(opt_role)) {
+               wrong_type_argument(Qstringp, opt_role);
+               return NULL;
+       }
+
        opt_stream = Fplist_get(pulse_options, intern(":stream"), Qnil);
        if (!NILP(opt_stream) && !STRINGP(opt_stream)) {
                wrong_type_argument(Qstringp, opt_stream);
@@ -266,6 +274,7 @@ sound_pulse_create(Lisp_Object pulse_options)
        spd = xnew_and_zero(struct sound_pulse_data_s);
        spd->server = opt_server;
        spd->client = opt_client;
+       spd->role = opt_role;
        spd->sink = opt_sink;
        spd->source = opt_source;
        spd->stream = opt_stream;
@@ -302,6 +311,7 @@ sound_pulse_finish(ad_device_data *data)
                spd->stream = Qnil;
                spd->server = Qnil;
                spd->client = Qnil;
+               spd->role = Qnil;
                spd->sink = Qnil;
                spd->source = Qnil;
        }
@@ -1117,6 +1127,9 @@ sound_pulse_init_mainloop(ad_device_data *devdata)
        const char *server =
                (NILP(spd->server) ? NULL :
                 (const char*)XSTRING_DATA(spd->server));
+       const char *role =
+               (NILP(spd->role) ? "event" :
+                (const char*)XSTRING_DATA(spd->role));
        int threadedp = spd->ml_threaded_p;
 
        /* cannot use Pulse on incomplete or corrupt audio devices */
@@ -1125,6 +1138,8 @@ sound_pulse_init_mainloop(ad_device_data *devdata)
 
        SXE_SEMAPH_INIT(&(spd->ctxsem));
 
+       setenv("PULSE_PROP_media.role", role, 1);
+
        /* Set up a new main loop */
        if (threadedp)
                spd->tml = pa_threaded_mainloop_new();
index de5cb6b..681b14c 100644 (file)
@@ -1137,6 +1137,16 @@ Valid keywords for Pulse are:
 :sink - the name of the sink to connect to (e.g. "output")
 :source - the name of the source to record from (e.g. "mic_in")
 :client - how to call the client on the server (default "SXEmacs")
+:role - a one-word description of the "type" of media to be played
+  on the server. It can be one of:
+          "video" - for movie/video streams
+          "music" - for music streams (like mp3's, oga's etc)
+           "game" - for audio from games
+          "event" - for event sounds (this is the default)
+          "phone" - for VoIP and Instant Messaging audio
+      "animation" - for animations
+     "production" - for audio production applications
+           "a11y" - for accessibility applications
 :stream - how to call the stream on the server (e.g. "fancy-sound")
 :immediate - connect to sink immediately and keep the connection
   alive as long as the audio device exists (default `t')