Commit graph

3385 commits

Author SHA1 Message Date
Alper Nebi Yasak
cff0ef13c1 alsa-ucm: Disable old modifiers when switching profiles of same verb
While switching profiles of the same UCM verb, existing code first
disables devices that are only on the first profile to avoid conflicts.
However, it only disables devices, not modifiers. Even worse, modifiers
which have PlaybackPCM/CapturePCM are incorrectly treated as devices and
result in a segmentation fault.

Check what we are disabling, and call the appropriate disable function
for both devices and modifiers. Modifiers are disabled before devices,
because _dismod calls fail when the modifier's supported devices are
disabled.

Link: b74269016c
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
905241c4a1 alsa-ucm: Add enable, disable, status helpers for modifiers
These are mostly the same as the device helpers added in c83b34516929
("alsa-ucm: Add enable, disable, status helpers for devices"), but for
modifiers instead.

Link: b382a00f8b
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
d99e0586b0 alsa-ucm: Create multiple profiles per verb for conflicting devices
Right now we try to add all UCM devices of a verb to a single profile.
But if some devices using different PCMs are configured as conflicting
with one another, we will only be able to utilize one of them, chosen
seemingly based on the order in the UCM config file.

This is not a problem with conflicting devices sharing a PCM, as they
are assigned to the same mapping and the ports mechanism only enables
one of them to be active at a time.

To utilize all devices in a UCM verb even when there are conflicting
devices using different PCMs, calculate subsets of devices which
can be simultaneously used and create a profile for each such set.

Link: 5dd411190d
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
63a44038d2 alsa-ucm: Disable old devices when switching profiles of same verb
While switching profiles, it was enough to switch UCM verbs since that
disables all enabled UCM devices and every profile had a distinct verb.
However, switching to the current verb does not disable any devices.

To support multiple profiles for a verb we need to explicitly disable
the old profile's devices, since they might be conflicting with the new
profile's devices and will prevent them from being enabled. Compare both
profiles' mappings, and disable the devices not in the new mappings.

Link: e49da7bcd6
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
6b46909083 alsa-ucm: Make mapping UCM contexts have only one modifier
After previous patches, we should be generating no combination ports, so
we don't need to store multiple modifiers per mapping. Simplify the code
based on this.

Link: 4821a0569e
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
bc42a617a4 alsa-ucm: Make mapping UCM contexts have only one device
After previous patches, we should be generating no combination ports, so
we don't need to store multiple devices per mapping. Simplify the code
based on this.

Link: 084d70a1e2
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
[Wim: Apply to acp add_profiles() and acp_card_set_profile()]
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
b8361cc568 alsa-ucm: Make ports store only one device
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.

Link: bf1708213b
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
0fc80db7fe alsa-ucm: Remove combination port generation logic
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.

Link: 0789a8fb76
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
[Wim: Apply to acp add_profiles(), acp_card_set_profile(), compat.h]
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
833c86d35b alsa-ucm: Make one input/output mapping per UCM device
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.

Link: a50330a4a5
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
d93e96b666 alsa-ucm: Split out helpers for device set name, description, priority
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.

Link: e8e2f4320c
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
943967b826 alsa-ucm: Fix device conformance check
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.

Link: 5245117781
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
d7591edc25 alsa-ucm: Rewrite conformant device group generation with idxsets
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.

Link: 0f26022843
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Wim Taymans
236b7ee0e2 acp: Add idxset comparison and reverse search operations
Add contains() function that checks if an item is in an idxset. Add
isdisjoint(), issubset(), issuperset() and equals() functions that
element-wise compare two idxsets.

Add complementary functions to the existing idxset search(), first(),
next() functions that work in the reverse direction: reverse_search(),
last() and previous().

Add steal_last() to remove and return the last item in the idxset.

[Alper: original patches for PulseAudio, split from other commit]
Co-developed-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Link: fb63e58931
Link: ec668ac44b
Link: 97d9c28579
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
a208716724 alsa-ucm: Split profile creation into verb and profile parts
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).

Link: 638574c0b7
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
7883da6f52 alsa-ucm: Make mapping creation independent from indvidual profiles
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.

Link: aa5ced3887
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
07a347d3b6 alsa-ucm: Stop conflating profile name with UCM verb name
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.

Link: 4527890416
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
f4c66de9f0 alsa-ucm: Let profiles know their associated UCM verb
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.]
Link: 9fc7064b9a
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Jaroslav Kysela
a5d87a43df alsa-ucm: Set profiles by their struct instance, not their name
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>
Link: 880ff393f1
[Wim: Apply to acp_card_set_profile() as well]
Co-authored-by: Wim Taymans <wtaymans@redhat.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
396382ebb2 alsa-ucm: Add enable, disable, status helpers for devices
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.

Link: 9b06e8fef4
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
3ef2e874b2 alsa-ucm: Make modifiers track conflicting/supported devices as idxsets
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.

Link: 9b06e8fef4
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak
36af5f074a alsa-ucm: Always create device conflicting/supported device idxsets
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.

Link: d8c89de24d
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Hector Martin
9c868740c2 alsa: ucm: Fix spurious mixer path removal on initial profile set
The code that removes the mixer path if probing fails can be called in
the path that sets a non-off device profile on hotplug *before*
card->active_profile is updated, which results in spuriously removing
the mixer path. By this point, context->ucm->active_verb would be set
to the same as the profile name, so we can use that instead to avoid
the issue.

On Apple Silicon machines with the UCM profiles in the Asahi Linux repo,
this manifests as the headphones jack having hardware volume controls
*only* if PA is started with headphones connected and until they are
disconnected. Hotplugs end up triggering the bad codepath, and it falls
back to software volume (which is particularly a problem when the
hardware volume happens to be very low or 0 at that point).

Signed-off-by: Hector Martin <marcan@marcan.st>
Link: 3e038c6d88
2023-12-04 15:34:48 +00:00
Igor V. Kovalenko
3e45464603 alsa-util: Fix pa_alsa_get_supported_formats fallback.
Looks like original intention was to scan over sample formats supported by PA,
but code does the scan by list of alsa formats. Reverse the map and adjust
fallback case which now can use the same map.

Link: 5ab2b9cb0e
2023-12-04 15:34:48 +00:00
Igor V. Kovalenko
082680d8a2 alsa-util: Perform format and rate detection before setting HW params
Perform detection of supported sample format and rates just after device is
opened, before `snd_pcm_hw_params()` is called for the first time. This fixes a
problem where device restricts available sample rates after HW params are set
preventing sample rate detection (seen with UAC2 devices and kernel 6.1.9)

Bug: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/1414
Bug: https://github.com/alsa-project/alsa-lib/issues/119
Link: aed52c507f
[Wim: Apply to acp add_pro_profile(), enable pa_alsa_supported_*()]
2023-12-04 15:34:48 +00:00
Igor V. Kovalenko
79ee2fac73 alsa-util: Dump probed rates
Link: 8152f39603
2023-12-04 15:34:48 +00:00
Igor V. Kovalenko
ceb1c38ee9 alsa-util: Add more standard sample rates
Link: 86c5fbab57
2023-12-04 15:34:48 +00:00
Jaroslav Kysela
84120e1167 alsa-mixer: extend pa_alsa_mixer_find with the subdevice check
The full identifier check must be executed for the new melem
creation, otherwise the duplicate control element code check
is reached.

Example (using the snd-aloop driver):

numid=56,iface=PCM,name='PCM Notify',device=1,subdevice=1
numid=62,iface=PCM,name='PCM Notify',device=1,subdevice=2

Link: 81a051089f
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2023-12-04 15:34:48 +00:00
Jaroslav Kysela
4066bbaf09 alsa-mixer: fix the re-attach code for the mixer control element
The new helem must be tracked and old helem must be cleared
to make the code work properly. Introduce the pointer to helem
as the private value for melem and add the necessary code.

Also, add a check for the duplicate mixer elements. The duplicate
mixer element invokes the abort check in alsa-lib. Print a warning
instead and handle the exit gracefully.

Link: d1675df0cd
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2023-12-04 15:34:48 +00:00
Jaroslav Kysela
3177f41cb4 alsa-mixer: allow to re-attach the mixer control element
It may be possible that the ALSA control element appears
again. Allow this combination by checking, if the pulseaudio
mixer element already exists. Do not create the duplicate
mixer element in this case.

Link: def8eb074e
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2023-12-04 15:34:48 +00:00
Jaroslav Kysela
2c3e8d90d3 alsa-ucm: remove extra space from the device.intended_roles property
Before:
  device.intended_roles = " voice"

After:
  device.intended_roles = "voice"

Link: eb870fcba9
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2023-12-04 15:34:48 +00:00
George Kiagiadakis
f5546d27c1 acp: avoid copying structure into itself
sync_mixer() calls d->set_volume(d, &d->real_volume);
which makes v and &dev->real_volume point to the same memory area
and valgrind complains:

Source and destination overlap in memcpy(0xcc53e2c, 0xcc53e2c, 260)
   at 0x488CFA0: __GI_memcpy (vg_replace_strmem.c:1121)
   by 0xBB0803F: set_volume (acp.c:1143)
   by 0xBB0EDCB: acp_device_set_port (acp.c:1897)
   by 0xBA9CD87: impl_set_param (alsa-acp-device.c:757)

because the compiler apparently implicitly converts this into a memcpy()
and memcpy(3) explicitly says "The memory areas must not overlap."
2023-12-02 20:30:40 +00:00
Wim Taymans
a532c2abdb acp: add support for hiding profiles and ports
api.acp.hidden-ports and api.acp.hidden-profiles can be used to pass
a json array of ports and profiles to hide. They will not show and
will not be selectable.
2023-11-30 17:40:48 +01:00
Wim Taymans
85a9e30908 alsa: clamp buffer_frames correctly
Don't try to multiple the max_buffer_size with the frame scale or else
we might try to set a min_buffer_size larger than the max_buffer_size.

Instead, use the frame_scale only to scale the quantum_limit and then
clamp against the max_buffer size.

See #3000
2023-11-30 13:28:16 +01:00
Frédéric Danis
442a208382 Bluez5: backend-native: HSP AG release SCO link on AT+CKPD=200
Bluetooth PTS test HSP/AG/ACR/BV-01-I request AG to release the SCO link
upon reception of AT+CKPD=200 reception
2023-11-29 15:43:22 +00:00
Arun Raghavan
c2e4e336ac alsa: Correctly bail if pitch ctls are not available
The `goto error` got misplaced while refactoring this code for
bind-ctls.
2023-11-29 15:41:24 +00:00
Wim Taymans
eca1f5685e alsa: place defaults in properties as fallback
We place the currently configured runtime settings in the properties but
clear the values when not negotiated. Don't do that but place the
defaults (when set) instead.
2023-11-27 16:20:21 +01:00
Wim Taymans
2af5a90c90 evl: add fds to pollfd from rt thread
When we don't have the thread id yet, don't add the pollfds yet
but wait until we do our first wait operation.

Use flags for eventfd. We can use this to communicate between all kinds
of threads with read/write.

Use evl_init() in the init function, don't attach the main loop, just
the thread that dos the first poll.
2023-11-24 11:58:28 +01:00
Pauli Virtanen
f14572648a bluez5: deal with too small Supported_Max_Codec_Frames_Per_SDU
Some devices appear to set Supported_Max_Codec_Frames_Per_SDU == 1 while
claiming they support two channels per stream, which is then not
possible.

In this case, limit the number of channels by the number of frames per
SDU when selecting.

Also adjust PAC sorting.
2023-11-23 17:47:55 +00:00
Pauli Virtanen
f327ed845f bluez5: add some debug to bap-codec-lc3
We don't want to dump on all calls to codec_select_config, so use debug
context.
2023-11-23 17:47:55 +00:00
Arun Raghavan
dec1102574 alsa: Move ctl sources to a main loop
It doesn't make sense to hang these on the data loop, so let's have
these on the main loop instead. Also avoids a potential crash while
removing them (since removal happens on the main loop and the data loop
might be polling while we're doing the remove).
2023-11-22 16:00:25 +00:00
Wim Taymans
e4cee8eec2 libcamera: add latency param query
JACK queries this unconditionally but it's a good idea to implement this
like v4l2-source.
2023-11-20 17:51:27 +01:00
Wim Taymans
49cdb468c2 alsa: also use interpolated time as nsec in IRQ mode
Don't use the current time as the nsec field in the graph clock because
it can jitter a lot. Instead, use the smoothed next_time, like we do
for timer based scheduling.

Since we track the current time against the rate converted ideal time,
lock on to the first timestamp when we reset the dll.

See #3657
2023-11-20 13:14:54 +01:00
Wim Taymans
ca069974fc bluez5: avoid compiler warning 2023-11-16 10:35:33 +01:00
Wim Taymans
179fbb51fc alsa: return 0 from successful resume
Don't return the value of the last snd_pcm_resume() call because that
might be -ENOSYS when resume is not implemented for the card and then
the non-error (because we used drop/prepare later) propagates and
logs an error.
2023-11-15 10:10:56 +01:00
Wim Taymans
0da4ea3b30 alsa: handle poll error
Recover after a poll error. This fixes resume after suspend.

Fixes #3646
2023-11-15 09:56:24 +01:00
Wim Taymans
443751bf16 alsa: remove err argument in alsa_recover()
We don't actually use it.
2023-11-15 09:55:58 +01:00
Wim Taymans
7b756c9090 alsa: improve debug 2023-11-15 09:55:36 +01:00
Pauli Virtanen
43af0645b7 bluez5: set BAP QoS RTN correctly
Set QoS RTN according to values supported by server values.
2023-11-14 22:08:23 +02:00
Pauli Virtanen
de9086481f bluez5: media-sink: set node.group for ISO group nodes
It's better to schedule nodes in the same ISO group together, since they
are supposed to produce synchronized output.
2023-11-12 18:48:25 +02:00
Pauli Virtanen
17c583bbe7 bluez5: iso-io: get proper group id for broadcast 2023-11-12 18:48:25 +02:00