[pulseaudio-discuss] RFC: New volume functionality for PulseAudio

David Henningsson david.henningsson at canonical.com
Fri Feb 14 06:23:24 CET 2014

On 02/11/2014 03:03 PM, Tanu Kaskinen wrote:
> Hi all!
> I'm working (together with other people at Intel) on adding system
> volume control functionality to Tizen (primarily the IVI profile,
> although there's nothing inherently IVI specific here). Tizen uses web
> APIs for the UI, and since there are no existing web API standards for
> this functionality, we need to design the API from scratch. The current
> design can be seen at [1], in case you're interested (it's good
> background material for this discussion). What I'd like to discuss in
> this thread, however, is not the web API as such, but the use cases
> behind that design and what those use cases ultimately require from
> PulseAudio. (Feedback for the web API proposal is welcome too, but I
> think that should be discussed in a separate thread.)
> We want to support:
>  * A single main output volume control. Think of things like the Gnome
> volume applet: when you click the applet icon, you get a single volume
> slider for controlling the "current output", whatever that means. The
> Gnome volume applet implements the main volume by using the default sink
> volume, but we'd like to make the main volume contextual, so that the
> main volume can control different things at different times. Ideally the
> contextual logic would be implemented in PulseAudio (by a policy
> module), not in the volume applet. The volume applet should know when
> the main volume controls e.g. the headphones volume or the phone call
> volume.
>  * Volume classes. A car manufacturer may want to present only two
> volume controls for the user: "system" and "entertainment". A policy
> module in PulseAudio should classify streams based on whether their
> volume should be controlled by the "system" volume or by the
> "entertainment" volume. The volume classification should be separate
> from the routing classification (module-stream-restore, among other
> problems, doesn't allow separate classification for volume and routing).
>  * Fine-grained volume UIs that show all application and device volumes,
> like pavucontrol. PulseAudio already handles this pretty well.
> The first question: do you agree that PulseAudio should support those
> use cases in one way or another?
> If the answer to the first question is "yes", then we can start
> discussing the details of the implementation. How would you implement
> the support for the listed requirements?
> I propose that we introduce a new concept: volume control. It would be a
> separate object that could be referenced from other objects. For
> example, all devices would have their own volume control objects. The
> main volume could point to some of the device volume controls, or any
> other volume control object. Streams could have their own volume control
> objects, or multiple streams could reference the shared volume control
> of their volume class.
> introspect.h could have something like this:
> typedef struct pa_volume_control_info {
>     uint32_t index;
>     char *name;
>     char *description;
>     pa_volume_t volume;
>     pa_channel_map channel_map;
>     double *balance; /* per-channel balance, values between 0.0 and 1.0 */
> } pa_volume_control_info;
> The alternative for separate volume controls is that we keep embedding
> the volume in various other objects, like sinks, sources, ports (which,
> btw, are currently missing volume control altogether when they are
> inactive), sink inputs and source outputs. This is certainly a possible
> approach, but I very much prefer the separate volume control object idea.
> Benefits of separate volume control objects:
>  * Solves the problem of figuring out what the main volume controls. For
> example, the Gnome volume applet shows a headphone icon when the main
> volume controls the headphones volume. The volume applet can check if
> the main volume points to the same volume control object as the headset
> port.
>  * If two streams share the same volume, a pavucontrol-like application
> can group the two streams under one volume slider.
>  * Opportunity to separate the overall volume from the channel balance.
> The pa_cvolume volume representation loses all balance information when
> the user slides the overall volume to zero.
>  * Flexibility to easily add new volume control objects for whatever
> purpose in the future. For example, there could be a volume debug mode
> where the individual alsa volume elements would be exposed as read-only
> volume controls, or separate read-only volume control objects for the
> "reference", "real" and "soft" components of sink volumes. pactl could
> show and control all volumes without understanding what the volumes are
> associated with.
> Drawbacks of separate volume control objects:
>  * Duplication in the API. The old volume functionality in the public
> API can't be removed, so there would be two ways to control most volumes.
> The main volume would be added to pa_server_info as a new field (index
> referencing the appropriate volume control object).
> The volume classes would be separate objects:
> typedef struct pa_volume_class {
>     uint32_t index;
>     char *name;
>     char *description;
>     uint32_t volume_control;
> } pa_volume_class;
> I would add the volume control objects, the main volume and the volume
> classes to the core API, because this is functionality that is used
> pretty much everywhere (desktop environments, mobile devices, IVI
> systems), but I'm open to implementing this in a module too, with a
> protocol extension.
> [1] https://wiki.tizen.org/wiki/User:Tanuk/AudioSystemAPI

Hi Tanu,

my gut feeling would say:

The volume objects, I think I understand the usefulness of those. I also
acknowledge the problem of having balance information lost when main
slider is zero.
However we currently have the pa_cvolume type as well, which is sort of
the same as the new fields volume+channel_map+balance. I wonder if it
makes sense to group these together and call it pa_cvolume2 or something.
And as somebody already pointed out, having either a global or
per-channel mute in that struct as well would probably be a good thing too.

If you want main volume to represent one of these, you might want to add
a property list too, to contain the icon property (the UI could show a
headphone icon when controlling headphone volume).

The volume classes however seem more like routing/policy implementation
internals. They could be kept inside the routing/policy module, exported
through property lists, or something like that. Either that, or I didn't
really understand the concept.

David Henningsson, Canonical Ltd.

More information about the pulseaudio-discuss mailing list