[pulseaudio-discuss] Card and sink/source specific config

Tanu Kaskinen tanuk at iki.fi
Fri Apr 5 11:52:30 PDT 2013

On Thu, 2013-04-04 at 10:32 +0200, David Henningsson wrote:
> With all these configuration discussions, there's one more aspect I'd 
> like to throw into the mix.
> We have a lot of global parameters that should really be configured by 
> card, or by sink/source.
> In daemon.conf, we have these:
> ; default-sample-format = s16le
> ; default-sample-rate = 44100
> ; alternate-sample-rate = 48000
> ; default-sample-channels = 2
> ; default-channel-map = front-left,front-right
> ; default-fragments = 4
> ; default-fragment-size-msec = 25
> ...all the above should be configurable per sink/source, rather than set 
> globally. Maybe you can override some of them by loading a sink or 
> source module manually, but then you lose the hotplug ability, so that's 
> not a good option.
> And all the parameters to module-udev-detect:
> tsched=<enable system timer based scheduling mode?>
> tsched_buffer_size=<buffer size when using timer based scheduling>
> fixed_latency_range=<disable latency range changes on underrun?>
> ignore_dB=<ignore dB information from the device?>
> deferred_volume=<syncronize sw and hw volume changes in IO-thread?>
> use_ucm=<use ALSA UCM for card configuration?>
> All these are really per card or per sink/source [1]. The only reason we 
> have these parameters in module-udev-detect, is because it's simpler to 
> configure things from default.pa that way. That's a bit stupid IMO.

Yes, it's a bit stupid.

> When you're thinking about configuration interfaces and such, would it 
> be possible to design in a solution to this too? :-)

I have thought about this lately and also not-so-lately. I'll present my
latest design idea, which I'm sure will again be shot down as

I'd like to have these per-sink options in configuration files, like

[AlsaSink foo]
scheduling-type = interrupt-driven

There's a problem: what should "foo" be? The obvious answer is that it
should be the sink name, but I don't really like that, because it looks
like we occasionally change the naming scheme, which breaks
configuration files if they use sink names for identification.

I propose that we don't match the objects in the configuration file with
runtime objects using the identifier in the configuration file ("foo" in
the example). Instead, those identifiers only exist to tell the
different objects of the same class apart. For matching with runtime
objects, "identification properties" are used, as opposed to "normal
properties" and "pointer properties" (there's no syntactic difference).
"scheduling-type" is a normal property, i.e. something that the user
might want to change. Pointer properties are used just for linking
objects in the configuration file. An identification property would be
something like serial number or vendor name: something that we can
expect to never change, unlike our sink naming scheme. A serial number
or vendor name should be a property of the card, not sink, though, so
I'll expand the example:

[AlsaCard c]
serial = 123  # identification property, matched with udev data
ports = p1 p2 # pointer property

[AlsaPort p1]
name = analog-output-speaker # identification property,
                             # matched with names of
                             # runtime port objects
sinks = s1 # pointer property

[AlsaPort p2]
name = analog-output-headphones
sinks = s2

[AlsaSink s1]
# There's no need for any identification properties, because p1
# has only one sink. Having multiple sinks for one port is very
# rare with alsa, but not impossible: remember that N9 example
# where headphones could be used via two different alsa sinks?
# I'm not sure what data should be used for identification in
# that case, but it could be e.g. the alsa device number.
scheduling-type = interrupt-driven # normal property

[AlsaSink s2]
scheduling-type = timer-driven

This adds some complexity compared to just using the card/port/sink
names for identification. If "we may change the naming scheme" is not a
good enough reason for this complexity, I'll give another use case: two
identical USB sound cards. We may have all possible identification
information available to be used in the card name, but the problem is
that it's all identical for the two cards, and the user wants to use
both cards at the same time, and to configure them differently, and the
configuration should be remembered. This can be solved with using the
USB bus address (or whatever it's called) in the card name, but that
isn't a good general solution, because those users that only have one
USB sound card want PulseAudio to recognize it as the same card
regardless of the USB port that it's plugged in.

The identification properties can be used to solve this problem: the bus
addresses wouldn't be added to the configuration file until PulseAudio
detects that there are two sound cards in the system that can't be
distinguished in any other way (yes, I expect the server to modify the
configuration file at runtime). After the bus addresses have been added
to the configuration, the configuration becomes tied to the USB port
(for that particular sound card model only).


More information about the pulseaudio-discuss mailing list