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

Tanu Kaskinen tanu.kaskinen at linux.intel.com
Tue Feb 11 06:03:19 PST 2014

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 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


More information about the pulseaudio-discuss mailing list