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"

or

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

or

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.
https://launchpad.net/~diwic
_______________________________________________
pulseaudio-discuss mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Reply via email to