After previous patches, we should be generating no combination ports, so
we don't need to store multiple devices per port. Simplify the code
based on this.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
A previous commit makes mapping names depend on the UCM device name.
Since UCM device names are unique, this means a mapping will at most
have one port and thus no combination ports can be generated.
This removes the dead code in the pa_alsa_ucm_add_ports_combination()
function, unrolls the remaining code in its helper functions that it
used, and renames it to pa_alsa_ucm_add_port() to signal that it no
longer generates combinations.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
PulseAudio combines UCM devices that have the same PlaybackPCM or
CapturePCM value into a single mapping with multiple ports. It also
creates ports in the same mapping for each valid combination of those
UCM devices.
Since mappings are the things we put in profiles, we can put in a
profile either all devices of a joint mapping or none of them. This
causes some complications with device conflicts. For example, a
different UCM device might be marked as conflicting with some (but not
all) of the devices in a joint mapping. In this case we can do one of
three things:
- Include all devices in one profile, and hope the conflicting device
isn't chosen as the mapping's active port. We shouldn't do this as it
puts conflicting devices in the same profile.
- Make one profile with the joint group, and one with the other device.
This is somewhat acceptable as we have no conflicts, but we sacrifice
some compatible combinations of devices.
- Do not group the devices into the same mapping, and make one profile
for each compatible combination of devices. This appears to be the
best option, one where we can always have the maximum number of
working devices.
This patch chooses the third option and makes one input and/or output
mapping per UCM device, by using UCM device names instead of PCM device
strings in the mapping names.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
Combination port logic calculates some useful properties for device
groups that we could reuse while generating multiple profiles to support
conflicting devices. Split them into their own functions.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
Right now this check is rejecting devices whose UCM config specifies
neither a conflicting device nor a supported device list, and accepting
devices which specify both. However, a device without neither list is
actually unrestricted, and a device with both lists is a configuration
error. Fix the check to accept the former.
Furthermore, this is missing another case where an already selected
device might have a supported devices list that doesn't have the
candidate device. Make this function also check against that, and also
make it accept devices already in the set.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
The existing code meant to generate device groups for combination ports
is tightly coupled to port creation. Similar functionality would be
useful to generate nonconflicting device groups for multiple profiles as
well, so this tries to rewrite it into a more reusable state.
Several things (e.g devices, mapping contexts) use idxsets to store a
device selection. This also switches this conformance check and device
group generation to using idxsets to make it easier to work with those,
with the eventual aim to unify device group representations.
Also try to adjust users of these functions to use idxsets these will
need/return, without causing too much interference.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
To support having multiple profiles per UCM verb, split the profile
creation into two parts based on whether they should run once for each
verb or for each profile (maybe multiple times per verb).
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
The ucm_create_mapping() function is not idempotent. It looks like it
was meant to be called once per device for the devices of a UCM verb
and takes a profile argument simply because a verb has generated a
single profile so far.
Make sure creating mappings per device and adding those mappings to the
profiles happens as separate steps to make it easier to split UCM verbs
and profiles as concepts.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
So far each profile had the exact name as their associated UCM verb,
which caused the one to be used where the other should have been.
Explicitly get and use the verb name where that was intended, and make
sure things about profiles aren't named after verbs.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
Currently each UCM verb generates one profile named the same as the
verb, meaning it's trivial to know which verb the profile belongs to.
This will be slightly harder to do when we generate multiple profiles
per UCM verb (e.g. to make use of conflicting devices).
It would still be possible to parse the profile name to get the UCM
verb, but instead let's keep track of the struct instance representing
the profile's associated verb. This also lets us remove a block of code
searching for the verb by its name.
Co-authored-by: Jaroslav Kysela <perex@perex.cz>
[Alper: Reused Jaroslav's UCM profile context changes for UCM verb
instead of combined devices.]
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
While switching profiles, it's possible that we will want to do more
work besides switching UCM verbs. The alsa-card module already has our
profiles as structs, but passes in only the names instead of the entire
struct. Make things work with the struct instead, so we can add other
things (like a UCM context) to it and use those here.
Co-authored-by: Tanu Kaskinen <tanuk@iki.fi>
[Alper: Split into its own commit and integrated Tanu's snippet.]
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
Right now manipulating device status is done inline once while setting a
port. However, we will need to reuse this code to disable conflicting
devices of a device we want to enable. Split it into enable and disable
helper functions.
There is another issue with the device enable logic, where trying to
disabling an already disabled device sometimes fails. To avoid that,
implement a status helper and check if the device we want to enable is
already enabled/disabled before trying to do so.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
Modifiers currently keep their conflicting and supported devices's
names, and these names are resolved to devices every time we need to use
them. Instead, resolve these device names while creating the modifier
struct and keep track of the resulting device structs in idxsets, same
as how device structs keep track of their support relations.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
This is intended to make the current and upcoming code a bit clearer, as
we won't need to constantly check for the existence of these idxsets
before using or operating on them.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
If UCM defines the private alsa-lib configuration, the ELD controls
are expected to use this device configuration too.
With this change:
I: [pulseaudio] alsa-util.c: Successfully attached to mixer '_ucm0009.hw:Loopback'
Without:
I: [pulseaudio] alsa-util.c: Successfully attached to mixer '_ucm0009.hw:Loopback'
I: [pulseaudio] alsa-util.c: Successfully attached to mixer 'hw:4'
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/673>
Alsa UCM device string can contain private configuration prefix required to make
correct device open call. Private prefix is dynamically generated by UCM manager
depending on internal state. Since pulseaudio sink/source port names currently
contain device string, these may change between runs breaking volume database
and module arguments referring to sink/source.
Fix this by skipping UCM private prefix available via `_alibpref` key while
creating UCM mapping name. Mapping object will still contain unmodified
device string for device open call.
See also https://github.com/alsa-project/alsa-ucm-conf/issues/104
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/598>
These two log messages are most likely intended for the path that was
just tried, but they are mistakenly printing the name of the port's
current path. Fix them.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/594>
We have a requirement to "hide" some hardware drivers, because
other (main) UCM configuration will refer them.
This patch use special error codes to notify the upper layers
to skip the module loading.
BugLink: https://github.com/alsa-project/alsa-ucm-conf/issues/30
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
It's possible for mdev to be NULL. In this case, an assert is taken
in pa_alsa_open_mixer_by_name() with debug builds, and a crash with
release builds. However, it's possible to bypass this trouble by taking
the error path if mdev is NULL.
Reported-by: Jarkko Sankala <jarkko.sankala@offcode.fi>
Signed-off-by: Eero Nurkkala <eero.nurkkala@offcode.fi>
It's completely normal to not have explicit channel configuration for
stereo devices. In fact, the ALSA developers actively avoid configuring
the channels for stereo devices.
I also dropped the word "duplex" from the messages, because "stereo
duplex" implies bidirectionality, but most devices use one direction
only.
The ALSA mixer can be opened multiple times (especially for UCM
in the probe). This adds a simple mixer cache to prevent
multiple open calls.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This is just invalid. It results to an error in almost all cases.
The hw:<number> scheme is sufficient to get the right card mixer.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Remove the implicit rule. It is perfectly ok to have the jack with
the same name for another I/O in the driver. Trust only the
value obtained from UCM.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
The UCM library is used to get the fallback values from the verbs
and the defaults section. There is no reason to duplicate this code
inside application.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
The mixer identifiers should be used for snd_mixer_selem API.
Use them as first, then try to fallback to the raw control
identifiers.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
- sync mixer logic added
- mixer path creation, empty set in mapping creation, paths added in path creation
- path creation moved inside new port creation as it might be called twice otherwise
- some comments added
This allows us to support the PlaybackVolume and CaptureVolume commands
in UCM, specifying a mixer control to use for hardware volume control.
This only works with ports corresponding to single devices at the
moment, and doesn't support stacking controls for combination ports.
The configuration is intended to provide a control (like Headphone
Playback Volume), but we try to resolve to a simple mixer control
(Headphone) to reuse existing volume paths.
On the UCM side, this also requires that when disabling the device for
the port, the volume should be reset to some default.
When enabling/disabling combination devices, things are a bit iffy since
we have no way to reset the volume before switching to a combination
device. It would be nice to have a combination-transition-sequence
command in UCM to handle this and other similar cases.
PlaybackSwitch and CaptureSwitch are yet to be implemented.