レナート   TBFKAYIBYNYAAYB   ﻟﻴﻨﺎﺭﺕ

Fri, 20 Feb 2009

Tagging Audio Streams

So you are hacking an audio application and the audio data you are generating might eventually end up in PulseAudio before it is played. If that's the case then please make sure to read this!

Here's the quick summary for Gtk+ developers:

PulseAudio can enforce all kinds of policy on sounds. For example, starting in 0.9.15, we will automatically pause your media player while a phone call is going on. To implement this we however need to know what the stream you are sending to PulseAudio should be categorized as: is it music? Is it a movie? Is it game sounds? Is it a phone call stream?

Also, PulseAudio would like to show a nice icon and an application name next to each stream in the volume control. That requires it to be able to deduce this data from the stream.

And here's where you come into the game: please add three lines like the following next to the beginning of your main() function to your Gtk+ application:

...
g_set_application_name(_("Totem Movie Player"));
gtk_window_set_default_icon_name("totem");
g_setenv("PULSE_PROP_media.role", "video", TRUE);
...

If you do this then the PulseAudio client libraries will be able to figure out the rest for you.

There is more meta information (aka "properties") you can set for your application or for your streams that is useful to PulseAudio. In case you want to know more about them or you are looking for equivalent code to the above example for non-Gtk+ applications, make sure to read the mentioned page.

Thank you!

Oh, and even if your app doesn't do audio, calling g_set_application_name() and gtk_window_set_default_icon_name() is always a good idea!

posted at: 22:02 | path: /projects | permanent link to this entry | 15 comments


Posted by ulrik at Fri Feb 20 22:30:22 2009
If everyone on the desktop required from everyone else, that they would have to categorize their apps into different categories, we would have a mess. Somehow this seems to be solved at the wrong level, especially given that the application mentioned might_not end up in pulseaudio, and probably does no "pulseaudio programming" at all.

If all underlying libraries were like this on the desktop? what a mess. Desktop apps should speak with the session, dbus, gnome-session, whatever, but shouldn't care about individual "implementation details".

Two arguments:
1. it's a mess if more than 2 parts of the desktop require something like this
2. pulseaudio is not unique, and this info should not go to it, but more generally go to the session. A video playing app should halt the screensaver for example, while music players shouldn't.. etc etc.

Posted by Lennart at Fri Feb 20 22:33:56 2009
ulrik: Ah, that's the classic "Let's lose focus, let's not fix individual problems, let's fix the entire world at once" reply!

Posted by Morten Welinder at Fri Feb 20 22:42:19 2009
g_setenv seems like a fairly bad way of communicating this information:

1. It is, in general, inherited by subprocesses
where it is likely inaccurate.

2. What do I do if my application can change role?
Think iPhone here -- sometimes music player,
sometimes telephone.

3. If different threads have different roles, it
breaks completely down.

Posted by Lennart at Fri Feb 20 22:46:08 2009
Morten: Yes, that's why I mentioned exactly this in the wiki page referenced here. Good that you replied only after having read what this post is actually about! Oh! ... wait...

Posted by Larry Ewing at Fri Feb 20 23:07:33 2009
Can you go into a little more detail about what the various roles mean and which ones get paused?  Something like flash seems to cover 3-4 of the roles depending on what it is being used for.

Posted by Kragil at Fri Feb 20 23:07:55 2009
Lennart, it is not easy being you, is it? :)

Posted by Lennart at Fri Feb 20 23:20:52 2009
Larry: the currently defined roles are described in the mentioned wiki page:

http://pulseaudio.org/wiki/ApplicationProperties#PA_PROP_MEDIA_ROLE

In 0.9.15 the policy we enforce is trivial: If at least one "phone" stream is active all "video" and "music" streams are paused. That is all. More complex policies might be added to the defaults eventually. Note however that applications should not set roles in expectance of certain active policies -- instead they should simply tag their streams properly and let the policies figure things out.

It's a bit pointless to discuss how Flash fits into this, because it simply doesn't: it cannot use the env vars mentioned above (because it is a plugin), nor does the plugin even really now what it actually is doing (is something a game? advertisment? video? music). Also, there is no sane way to make Flash pause. For the media players we fake XF86AudioPause key events to make them pause, which probably everyone agress is a terribly kludgy hack. (The better future solution for this will hopefully be a future version of MPRIS) But Flash does not respond to those key events, nor will it ever support MPRS. For now, stuff like Flash should be tagged as "animation", but it is an illusion that even this will ever happen, given its closed source nature, and the environment it is running in (see above).

Maybe this might improve a bit when stuff like swfdec gets more useful to use.

Posted by Larry Ewing at Fri Feb 20 23:30:33 2009
Thanks for the information.  I was asking relation to moonlight and how we should try to map what information we have on our side (which isn't much) with the pa streams.

Posted by Hans Rödtang at Sat Feb 21 02:50:58 2009
Any tips on how this should be done in Python?

Posted by Christophe Fergeau at Sat Feb 21 11:02:58 2009
GStreamer gconfaudiosink has a property which can be used to describe which kind of stream we are about to play. Is there something similar which can be done with the pulseaudio sink or do apps using gstreamer also have to do this ugly g_setenv ?

Posted by Christophe Fergeau at Sat Feb 21 11:03:35 2009
Here is the kind of code Rhythmbox has to set this gconfaudiosink property :
if (sink != NULL) {
/* set the profile property on the gconfaudiosink to "music and movies" */
if (g_object_class_find_property (G_OBJECT_GET_CLASS (sink), "profile"))
g_object_set (G_OBJECT (sink), "profile", 1, NULL);

g_object_set (G_OBJECT (mp->priv->playbin), "audio-sink", sink, NULL);
}

Posted by Stefan Kost at Sat Feb 21 20:03:58 2009
As Lennart mentions, the g_setenv is a kind of hack. I suggested using the information from the dekstop files in http://bugzilla.gnome.org/show_bug.cgi?id=567721 - please discuss there.

Regarding GConfAudioSink and the profiles, there is http://bugzilla.gnome.org/show_bug.cgi?id=567656.

Posted by Christophe Fergeau at Sat Feb 21 23:53:56 2009
Thanks for the links Stefan. Fwiw, I agree with Lennart comment in bug #567656 that setting this per-app (as would be the case if using a .desktop file) isn't fine-grained enough (though this is exactly what we get with the current g_setenv solution). And I didn't comment on the bugs as you suggested because a "me too" didn't seem really useful there ;)

Posted by Morten Welinder at Sun Feb 22 19:51:23 2009
Lennart, you are pathetically defensive in your
responses.  It is as-if you cannot handle other
opinions than your own.

You reference your wiki page which says precisely
nothing about the three things wrong with your
setenv.  The closest I see is some wishy-washy
sentence "However usually it is still safe to
simply set a process-global environment variable."
Usually?  All week, except Sunday?  Only if you
name has more than two vowels?

Perhaps you should read the comments before
responding to them.  And then relate to the
substance.

Posted by Laszlo Pandy at Sun Feb 22 19:52:40 2009
@Hans
I just implemented this for Jokosher, heres what it looks like:

gobject.set_application_name(
  _("Jokosher Audio Editor"))
gtk.window_set_default_icon_name("jokosher")
os.environ["PULSE_PROP_media.role"] = "production"

Leave a Comment:

Your Name:


Your E-mail (optional):


Comment:


As a protection against comment spam, please type the following number into the field on the right:
Secret Number Image

Please note that this is neither a support forum nor a bug tracker! Support questions or bug reports posted here will be ignored and not responded to!


It should be obvious but in case it isn't: the opinions reflected here are my own. They are not the views of my employer, or Ronald McDonald, or anyone else.

Please note that I take the liberty to delete any comments posted here that I deem inappropriate, off-topic, or insulting. And I excercise this liberty quite agressively. So yes, if you comment here, I might censor you. If you don't want to be censored your are welcome to comment on your own blog instead.


Lennart Poettering <mzoybt (at) 0pointer (dot) net>
Syndicated on Planet GNOME, Planet Fedora, planet.freedesktop.org, Planet Debian Upstream. feed RSS 0.91, RSS 2.0
Archives: 2005, 2006, 2007, 2008, 2009, 2010

Valid XHTML 1.0 Strict!   Valid CSS!