[pulseaudio-discuss] GSoC Proposal: Configurable maximum volume for sinks and sources

Tanu Kaskinen tanuk at iki.fi
Wed Mar 28 23:03:58 PDT 2012

On Tue, 2012-03-27 at 19:16 +0200, Matěj Laitl wrote:
> > Note, however, that there's another "extra" job that you'd preferably do
> > before starting with the volume things (or at least before starting to
> > extend the client API), which reduces the probability of running out of
> > stuff to do. One of the project ideas is a "configuration system". There
> > was a discussion between me, Colin and Arun, and we thought that it
> > would be really good if the volume limit feature could use the
> > configuration system's client API as the client interface. Since the
> > configuration system doesn't exist, designing the client API for it
> > would have to be part of the volume limit project. The API probably can
> > be quite simple, since all it has to do is to provide means for getting
> > and setting configuration values and for subscribing to updates. You
> > wouldn't have to implement the whole configuration infrastructure, only
> > as much as is needed to make the limit configuration to work. We should
> > update the idea page to reflect this...
> Okay, no problem. So, what are goals of such configuration system? How should 
> it fit into existing pulseaudio configuration possibilities in /etc/pulse?

I wouldn't worry about that too much yet. The volume limits will most
likely be stored in some new file, so the old files won't be touched.
Later we probably want to move e.g. the options in daemon.conf to the
new configuration system, and at that point some transition plan has to
be thought out.

> It 
> looks like a simple key->value storage, but at least volume limits should be 
> per-port as mentioned, others may be per-{server,module,stream,source,sink}?

It probably could be a simple key-value database, but since object
identifiers like sink names can be quite complex and contain
"special-ish" characters, I think the keys would get quite ugly. Here's
my initial proposal, any opinions are most welcome:

Each option has to be identified by tuple (object type, object id,
option name). All that information could be smashed into one string so
the system would then be a simple key-value database. As I said, I think
the option names would get quite ugly sometimes, so I propose that
clients have to provide the three parts separately. I would guess that
it would also be more convenient: programmers don't need to allocate a
new string for concatenating a bunch of other strings.

    pa_configuration_set(pa_context *c, const char *object_type, const char *object_id, const char *option, const char *value);

An example:

    pa_configuration_set(context, "core.Port", "alsa_card.pci-0000_00_1b.0:analog-output", "volume-limit", "50 %");

Ports actually don't have globally unique identifiers. Here I've
constructed the port id from a card name and a port name. There's also a
bug about this[1]. I think you don't have to fix that bug if there's
already enough things to do, but at least we should agree what the port
id should look like so that there won't be unnecessary incompatibilities
when the bug finally gets fixed some day. My suggestion is
"cardname:portname" as shown in the above example.

I'm also suggesting that object types (like "Port") have a namespace for
separating core objects and module objects (for example, "core.Port" and
"stream-restore.Entry"). This is not strictly needed (especially the
core namespace), but I'd like it anyway.

How the settings are stored on disk is an implementation detail. I'd
store the settings in ini-style files (we already have a parser for
them) with one file for each namespace. So there would be core.conf,
stream-restore.conf etc. There would be a section for each object. For
example, core.conf could contain this:

    [Port alsa_card.pci-0000_00_1b.0:analog-output]
    volume-limit = 32768

(In this example, the volume is stored in the "native" format, while I
think it makes sense to allow clients to use different formats, like
percentages, when setting the option. And BTW, I hope that multi-channel
limits won't be needed.)

[1] https://bugs.freedesktop.org/show_bug.cgi?id=44793

> > [1] The limits need to be handled separately for each port. It's not
> > sufficient to have per-sink limits.
> Hmm, is there any documentation on ports? I seem to find much less information 
> on them compared to sinks & sources.

I don't think there's much documentation beyond source code. The concept
isn't complicated, though: each sink and source can have zero or more
ports, and one of the ports is always active. The ports are used, for
example, to switch between a laptop's internal speakers and the
headphone output. Note that a sink might have zero ports: this is
obviously a problem if you want to set a volume limit for the sink when
the limits are set for ports. We should fix it so that sinks and sources
always have at least one port. I think this won't block your work,
though: if you use the auto-detected alsa devices for testing, I think
they will always have ports. I don't think fixing the zero-port case
needs to be a part of your project, although getting it fixed would of
course be nice!


More information about the pulseaudio-discuss mailing list