Commit graph

1231 commits

Author SHA1 Message Date
Pauli Virtanen
bd3a8b594f spa: acp: indicate ALSA UCM profile errors in UIs
Add "[ALSA UCM error]" to the end of card description, to indicate
something is wrong.
2025-03-13 21:25:55 +00:00
Pauli Virtanen
4338189f76 spa: acp: allow also too few channels in SplitPCM configs
GoXLR Mini has different numbers of channels actually available (21, 23,
or 25) depending on its firmware/etc, but its UCM profile specifies
always 23. The count can then be bigger or smaller than what is actually
available.

Fail a bit more gracefully in the case of too few channels: create all
the split devices specified by the profile. The channels that aren't
actually available in HW just won't get routed anywhere.

ALSA upstream IIUC is saying that the channel counts should be fixed, so
spew warnings that say the UCM profiles are wrong if they look wrong.
2025-03-13 21:25:55 +00:00
Wim Taymans
bf3c7aa6e1 alsa-seq: fix UMP output
We need to set the UMP flag, which is done with
snd_seq_ev_set_ump_data() to make it output the midi data.
2025-03-11 13:29:38 +01:00
Wim Taymans
ff08c28b62 alsa-seq: avoid uninitialized warning 2025-03-11 12:33:08 +01:00
Pauli Virtanen
a503244c10 spa: avoid casting between snd_seq_event_t & snd_seq_ump_event_t
Although the two structs have same initial sequence, it's not really
correct to cast between their pointers. Alsa-lib also does this only
internally, but not in API.
2025-03-10 18:12:54 +00:00
Pauli Virtanen
fd5bd5ca6e spa: fix ALSA UMP support detection in meson 2025-03-10 18:12:54 +00:00
Pauli Virtanen
4379cf446f spa: alsa: support also MIDI-1.0 IO for ALSA seq
Support also non-UMP IO with ALSA seq, in case either alsa-lib or the
kernel does not have UMP enabled.

Add configuration option "api.alsa.seq.ump" for optionally turning UMP
I/O off, for easier debugging.
2025-03-10 18:12:54 +00:00
Nikolay Borodin
6620c6cde1 spa: alsa: allow building without UMP in libalsa
Allow building with older libalsa releases that don't have UMP.
2025-03-10 18:12:54 +00:00
Pauli Virtanen
5c1d6fb5ad spa: acp: make spa-acp-tool debug output easier to read
Include log level, file/line numbers, and indent messages for debug
levels.
2025-03-09 16:15:56 +02:00
Pauli Virtanen
6d51b4bb11 spa: acp: be more noisy when UCM profiles fail to be supported
Generally ALSA UCM profiles should all work as they're supposed to be
device-specific, so be more noisy when the profile fails to be supported
due to the PCM device failing to open.

Some logging on the probe outcome in failure case also makes
spa-acp-tool etc. log output easier to read.
2025-03-09 13:10:37 +02:00
Pauli Virtanen
bc890d3b83 spa: acp: in SplitPCM probe channel count and allow excess
In SplitPCM mode, Focusrite Scarlett Gen 4 (USB 1235:8218) UCM profile
specifies "CaptureChannels 2" for the Mic1/2 inputs, but
snd_pcm_hw_params_set_channels(2) fails for the HW device.

Fix by not requiring the channel count to be exact for SplitPCM, but
also allow larger numbers of channels than what UCM profile specifies.
2025-03-09 13:04:26 +02:00
Stefan Ursella
fb7c37aeb4 alsa-pcm: recognize headroom to calculate max_error and max_resync 2025-03-03 12:26:05 +01:00
Joakim Tjernlund
c374aaca5b 90-pipewire-alsa.rules: Check firewire before pci
Fixes #4528
2025-02-07 16:43:52 +01:00
Andrew Sayers
db972b5bc1 Downgrade snd_pcm_mmap_commit error to warning 2025-01-21 11:20:23 +00:00
Wim Taymans
9889d1ce0a alsa: close the sequence on error. 2025-01-19 15:56:01 +01:00
Wim Taymans
e4fc8d43bb alsa: handle error from _set_client_midi_version()
See #4507
2025-01-19 15:52:48 +01:00
Pauli Virtanen
b9e130fd8c spa: alsa: do not allow setting Route that is not in current profile
When setting Route param, check that the route actually is part of the
active profile.

Also, check that the device given corresponds to the given route, before
setting properties. acp_device_set_port() also checks this, but we
shouldn't allow updating properties of Routes in non-active profiles.

Setting ports or applying props on devices not part of the profile can
do unexpected things e.g. alter mixer settings.
2025-01-12 11:13:47 +00:00
Pauli Virtanen
90f8b0e40b spa: acp: remove some strictly not necessary SplitPCM properties
Remove some api.alsa.split.* properties that the monitor script can
figure out itself.
2024-12-23 11:46:02 +02:00
Pauli Virtanen
dcccfcab7f spa: acp: get and emit UCM information for SplitPCM devices
When api.alsa.split-enable=true for ACP device, instruct UCM to not
use alsa-lib plugins for SplitPCM devices.

Grab the information from UCM for the intended channel remapping, and
add the splitting information to the nodes emitted.

Session manager can then look at that, and load nodes to do the channel
splitting.
2024-12-21 16:03:19 +02:00
Pauli Virtanen
7d7019d939 spa-acp-tool: parse properties with spa_json
Fixes crash in parsing properties due to access after end of string.
2024-12-21 16:03:19 +02:00
Alper Nebi Yasak
507ec0b39a alsa-ucm: Set up hardware volumes again on duplicate port additions
While initializing ALSA cards with UCM, we call pa_alsa_ucm_add_port()
for each UCM device for each UCM verb. This checks if a port has been
already added by name and skips port initialization if it is already
done. Different UCM verbs can have devices with the same name, which
means their port names end up being the same. So, this port creation
step currently is only done for one UCM verb for both UCM devices.

Volume control setup is also part of this process. The UCM devices only
know about the volume mixer information from the UCM verb that they are
defined in, so the volume control setup is done for one UCM verb at a
time. Skipping this setup when a same-named port exists means only the
profiles belonging to the first initialized UCM verb have working
hardware volume control.

Move the volume control setup out of the port initialization block so
that we try to do it every time, therefore for every UCM verb. However,
check that we don't run it twice for the same UCM verb for a port.

In theory, the PlaybackVolume etc. value can be different per-verb
for the same device, so we can't simplify this code to a single volume
setup per port.

Link: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/840
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2024-12-07 18:32:48 +00:00
Arun Raghavan
5cbf3654c7 spa: alsa: Add a NULL check before updating rate match
The RateMatch IO might be NULL for the driver, and trying to update rate
matching with state->rate_match crashes in this case.
2024-12-05 13:08:04 -05:00
Alper Nebi Yasak
35dbaa840b alsa-ucm: Set icon names for mappings as well
Commit 88bb0bd7cc ("alsa: Allow to augment ucm port properties") adds
icon properties for some common port names, so that GUIs can show a
relevant icon to help disambiguate devices. However, these still do not
show up in pavucontrol, because it shows icons based on mappings'
properties. Add the relevant property to mappings as well.

Link: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/839
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2024-12-04 20:42:03 +00:00
Alper Nebi Yasak
e726c5f6db alsa-ucm: Fix possible segfault from recursion due to too many devices
While trying to figure out device subsets that have aren't internally
contain conflicting devices, we walk through all possible subsets and
check each set if it satisfies ConflictingDevices/SupportedDevices
listed in UCM configuration. For a better user experience, we want to
skip subsets that are fully included in another valid subset we will
also generate.

The iterate_device_subsets() function that achieves the former is
intentionally in iterative form to avoid a stack overflow, since it will
walk through 2^n sets. However, the iterate_maximal_device_subsets()
function that skips incomplete sets is in recursive form, as I had
assumed tail-call optimization would take care of the potential problem.

Convert iterate_maximal_device_subsets() to an iterative form, because
the recursion seems to trigger a segfault with more than 16 devices on
PulseAudio. It doesn't seem to happen on PipeWire, but it's better to
not leave it to luck.

Link: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/838
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2024-12-04 20:40:16 +00:00
Wim Taymans
e2a0d720f9 alsa: reduce debug level that got accidentally increased 2024-12-03 16:44:45 +01:00
Wim Taymans
22f0b858b1 alsa: improve target bandwidth calculation
Also use the average error to calculate the bandwidth. If we are not
around 0, we should increase the bandwidth.
2024-12-03 12:11:20 +01:00
Arun Raghavan
7bc84305e6 spa: alsa: Don't assume all PCMs have a card
dmix/dsnoop devices, for example, don't have an associated card, so all
the card-related checks don't make sense. Let's explicitly deal with
this case.

Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4432
2024-11-29 12:12:28 -05:00
Arun Raghavan
4c09451e77 spa: alsa: Fix key name suggestion in log message
We use api.alsa.pcm.card to look up the PCM's card if we don't know it
by other means.
2024-11-29 10:55:39 -05:00
David Härdeman
f33e1bc8c3 spa: alsa: autodetect supported iec958 codecs via ELD info
The alsa/acp code already supports getting a user-friendly monitor name
using the EDID-Like Data (ELD) information available from cards that follow
the Intel HDA specification.

This patch adds support for also parsing the SAD fields of the ELD, and
exposing the results as a "iec958.codecs.detected" property on the
corresponding node, which should make it possible to provide more
user-friendly configuration UIs and defaults.

The default value will take effect if the session manager does not set a
different value.

Brief example:
test@test:~/checkouts/pipewire$ pw-dump | grep -E "(iec958.codecs.detected|iec958.codecs)\":"
        "iec958.codecs": "[\"PCM\",\"AC3\",\"EAC3\",\"TrueHD\"]",
        "iec958.codecs.detected": "[\"PCM\",\"AC3\",\"EAC3\",\"TrueHD\"]",

<after powering on my receiver>

test@test:~/checkouts/pipewire$ pw-dump | grep -E "(iec958.codecs.detected|iec958.codecs)\":"
        "iec958.codecs": "[\"PCM\",\"DTS\",\"AC3\",\"EAC3\",\"TrueHD\",\"DTS-HD\"]",
        "iec958.codecs.detected": "[\"PCM\",\"DTS\",\"AC3\",\"EAC3\",\"TrueHD\",\"DTS-HD\"]",

Big thanks to Pauli Virtanen <pav@iki.fi>, who also wrote large paths of the
code for this patch.
2024-11-28 09:18:07 +01:00
Pauli Virtanen
e08846dc9c alsa-card-profiles: move HDMI/AC3 profiles to separate profile set
These shouldn't be enabled by default, because they cannot be
autodetected, and if the configuration is not a supported one, they
produce loud BRRRT at 100% volume and ALSA errors.
2024-11-23 14:58:17 +02:00
Arun Raghavan
90075b838c spa: alsa: Try to initialise card_index from path if needed
If the PCM is loaded directly using only api.alsa.path,
state->card_index may never be initialised, and then we end up opening
the wrong ctl device. Let's try a fallback for this case.
2024-11-22 10:36:26 -05:00
Wim Taymans
1084cc24b6 alsa: handle the case where the driver is destroyed
When the driver node is destroyed (like when unplugging the cable) it
will drop/pause all of the follower ALSA nodes. This is something that
happens internally because of how the ALSA nodes work together, on the
PipeWire level, the nodes are still running and they will just be moved to
another driver.

The problem is that nothing will then start the nodes again after moving
it to the new driver. Fix this by keeping track of the desired target
state of the ALSA node and restoring that state when we detect that we are
paused when moved to a new driver.

Fixes #4401
2024-11-15 16:09:36 +01:00
Wim Taymans
d32ab4d8ea alsa: remove unused variable 2024-11-14 12:03:55 +01:00
Wim Taymans
6549e313ef alsa: clean up followers and our driver link in _clear
When we are going to be freed, make sure we remove ourself from the
driver list and also remove all the followers that we might still have.

Fixes #4355
2024-10-21 15:47:21 +02:00
Wim Taymans
fa1ec61cf0 profiler: add followerClock block
Add a new followerClock block in the profiler info. This is only set
when the follower could be a driver and it contains the clock info used
for following the driver, mostly the rate difference and delay.

Dump this info in pw-profiler -J

Make sure we always set the info in the clock, especially also when we
are following.
2024-10-09 11:31:54 +02:00
Wim Taymans
0db2171cd9 alsa: dynamically adjust the DLL bandwidth
Keep a running average and variance of the error. Use this to
periodically update the DLL bandwidth. When the variance gets smaller,
we update the DLL more slowly to stay closer to the ideal rate.

This seems to improve the rate stability.
2024-10-04 10:47:47 +02:00
Arun Raghavan
e6bcc415fc acp: Trim trailing whitespace in monitor name from HDMI ELD
The ELD ends with a \n and spaces to pad the length, but most drivers
except NVidia trim that out while presenting to userspace. While this is
being tracked upstream [1], let's deal with this locally.

[1] https://github.com/NVIDIA/open-gpu-kernel-modules/pull/715

Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4332
2024-10-02 17:02:11 +00:00
Barnabás Pőcze
1a549c02a5 acp: do not overwrite properties of PCM with that of the card
The properties of the card might overwrite those of the PCM.
For example, the cards's `alsa.id` will be set on the PCM too
since 37a51533e0 ("acp: add more properties for the card").

To avoid that, call `pa_alsa_init_proplist_card()` first
in `pa_alsa_init_proplist_pcm_info()` instead of last.

See #4135
2024-10-01 22:50:12 +02:00
Alper Nebi Yasak
d42bfa56b7 acp: sync the mixer after selecting the port
Otherwise we might sync the wrong port and end up muted.

Fixes #4084
2024-09-25 10:02:46 +02:00
Wim Taymans
99c23d5b0e acp: add api.alsa.disable-mixer-path
Don't use the api.alsa.soft-mixer option to disable the path selection
but make a new api.alsa.disable-mixer-path.

Disabling the path selection might leave cards unusable after suspend,
so a separate option is a better idea.

See #4311
2024-09-24 13:14:17 +02:00
Wim Taymans
322829cb2e acp: disable path_select when using soft-mixer
When using the soft mixer we should not use path_select because that one
will also touch the mixer and try to mute some switches.

Fixes #4311
2024-09-23 15:34:08 +02:00
Barnabás Pőcze
ab2907c699 spa: alsa: avoid potential uninitialized variable use
In both funtions `ctl_hndl` could be passed to `snd_ctl_close()`
while being unitialized if `this->device_info.change_mask` is zero.
2024-09-18 19:54:13 +00:00
Wim Taymans
e2991f6398 json: add helper function to parse channel positions
Use the helper instead of duplicating the same code.

Also add some helpers to parse a json array of uint32_t

Move some functions to convert between type name and id.
2024-09-18 09:54:34 +02:00
Wim Taymans
cd81b5f39a spa: add spa_json_begin_array/object and relaxed versions
Add spa_json_begin_array/object to replace
spa_json_init+spa_json_begin_array/object

This function is better because it does not waste a useless spa_json
structure as an iterator. The relaxed versions also error out when the
container is mismatched because parsing a mismatched container is not
going to give any results anyway.
2024-09-16 09:50:33 +02:00
Stefan Ursella
189f2ec95b alsa-pcm: unlink pcm when driver is changed to a different pcm
We have to unlink pcms when they are linked to a driver from
a different pcm.

When a playback and a capture pcm is linked and we start
the playback pcm and the capture pcm later this can leads
to a 'EPIPE' error on the capture device.

...
spa.alsa: hw:3,0c: snd_pcm_start: Broken pipe
...
2024-09-06 08:42:20 +00:00
Wim Taymans
01558bb9e9 alsa: improve midi port.name
The port.name should be something fairly unique and stable per node that
is also human readable.

Make sure we include the ALSA client name and port name in the
port.name but try to avoid double client names when the client name
is already in the port name.

There is also a api.alsa.disable-longname that is now set to true by
default. Setting this to false will include the unique client and port
id to the port.name.

This should make the midi port names much more presentable and more in
line with JACK1.
2024-08-26 13:42:09 +02:00
Arun Raghavan
9cd2bbc585 alsa-pcm: Lower the frequency of USB gadget rate updates
While the spec allows for 1ppm changes, our rate matching logic applies
these changes quite often, which can be spammy on USB. I haven't seen
hosts mind this, but it seems like it might be a problem at some point.

Additionally, if we also have bind ctls enabled, every pitch update is
also a wakeup for ourselves (whether or not we're listening for the
pitch ctls, since the mixer fd does not distinguish between ctls, those
are filtered after we wake up).

The 10ppm threshold is empirically tested as being not "too noisy" (i.e.
when updates happen, I can see them scroll by with `amixer events`).

If necessary, we can make this configurable in the future.
2024-07-31 12:00:07 -04:00
Wim Taymans
ce89ce304d alsa: fix compilation wirh -UFASTPATH 2024-07-30 09:53:14 +02:00
Wim Taymans
94bb5a2dd2 alsa: add UMP support
Use the new UMP alsa sequencer API to make it produce UMP packets.

Set the alsa sequencer to MIDI2.0, which will make it convert all
messages to MIDI-2.0 UMP automatically. We can copy this straight into
the control buffers.

This also solves some problems with large sysex messages that are now
nicely split into chunks with UMP.
2024-07-30 09:38:40 +02:00
Arun Raghavan
0dc17d8d88 spa: alsa: Fix stale function name in comment 2024-07-17 20:07:57 -04:00