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

David Henningsson david.henningsson at canonical.com
Wed Apr 10 02:32:49 PDT 2013

On 04/05/2013 08:52 PM, Tanu Kaskinen wrote:
> 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
> over-engineered...
> I'd like to have these per-sink options in configuration files, like
> this:
> [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.

If we change the naming scheme, volume db would be destroyed too, IIRC.

> 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

So, I don't think I mind the general idea too much. I don't know if 
there's something simpler that solves the problem.
I especially like that we can match udev data right in the configuration 
file; rather than having to add specific udev rules.

I'd more like to discuss the actual format of these files.

Perhaps it would be easier to understand if all matching properties 
begun with "match-", e g:

match-udev = ID_PATH="pci-0000:03:07.0"


match-name = alsa_card.pci-0000_03_07.0


match-property = device.bus_path="pci-0000:03:07.0"

to match one of my sound cards. Matching rules are "AND", i e, if no 
matching specified, it matches any card.

I'd also prefer

match-card = c

on the port, rather than "ports = p1 p2" on the card. So my example 
would look something like:

[alsa_card JuliCard]
match-property = alsa.card_name="ESI Juli@"

[alsa_sink JuliSink]
match-card = JuliCard
modargs = "tsched=0"

...but the complexity can easily grow out of hand. What if we want OR 
conditions between matches, wildcards, and what not. Maybe we should do 
+= instead of = for the modargs?

And for profiles and paths, do you think something like this could work:

[alsa_mapping force-internal-mic]
match-card = JuliCard
match-name = analog-stereo
paths-input += analog-input-internal-mic-always

> [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).

I'm not sure I follow on this part. If two identical USB cards are 
detected, the system would somehow reconfigure itself to add bus 
addresses. Would it then reconfigure itself back again if one of them 
are unplugged?

David Henningsson, Canonical Ltd.

More information about the pulseaudio-discuss mailing list