Card and sink/source specific config

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2013-04-10 at 11:32 +0200, David Henningsson wrote:
> 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.

Yes, all the restore modules rely on stable naming.

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

I'm OK with a convention of using a "match-" prefix for matching
properties.

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

My intention was that when matching an object in a configuration file to
runtime objects, there would never be multiple matches. Or in case there
are multiple matches, like in the "identical cards" case, then that
would be resolved by adding more identification information (bus
address) to the configuration file. This largely removes the need to do
any wildcard matching.

I agree that allowing multiple matches makes sense in the alsa-mixer
configuration, though. I've been only thinking about the
"normal" (mutable) configuration files, while you seem to be more
interested in the static alsa-mixer files. I wouldn't mind if these two
types of configuration used different approaches to identification.

A sidenote: we have both used the scheduling mode as an example, but it
probably makes more sense in the alsa-mixer configuration, because if
there's need to use timer-based scheduling on some hardware, we should
use it automatically for all users of that hardware, and therefore it
should be part of the static alsa configuration files.

I fully support having a += operator. While we're on the topic of
extending the configuration file syntax, I propose that we also add the
possibility to unset a property, so that the implicit default will be
used (potentially useful when overriding configuration files). One
possible implementation for that would be to interpret value "unset" as
special, so when that value is assigned to a property, the property
becomes unset.

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

No, it wouldn't reconfigure itself back again, because that would lose
the separate configuration that has been done for the two cards. My
assumption is that if the user has two identical USB cards, they will
always be connected to the same ports. One or both being unplugged is
not a problem in this case. Does someone have better solutions that
don't need such assumptions?

-- 
Tanu



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux