spa_alsa_read is called from the source process function when we are a
follower and no buffer is ready yet.
Part of the rate correction was performed by the ALSA driver when it
woke up but now, the resampler has updated the requested size and we
need to requery it before we can start reading samples.
Otherwise, we end up with requested samples from before the rate update
and we might not give enough samples to the resampler. In that case, the
adapter will call us again and we will again try to produce a buffer
worth of the requested samples, which will xrun.
Make a new alsa.use-ucm option that sets api.alsa.use-ucm on the device
it creates (when set).
There is some documentation floating around (thr arch wiki) with this
property.
See #4755
When a linked node needs to be resynced we actually never clear the
flag or reset the dll. Move the code around so that it still does
the reset of the flag and dll without actually doing the resync in
the ringbuffer when it is a linked node.
When we do_prepare, always reset the dll. We already set the alsa_sync
field but that is only used by followers to resync in some cases.
When reseting the dll, we also reset the next_time and base_time values,
we however need to do this before calculating the error in update_time
when we are the driver in IRQ mode or else we get some crazy error
that distorts the rate estimation.
Interrupts are disabled in alsa_irq_wakeup_event -> playback_ready method
to not produce another wakeups when waiting for a new data. Interrupts are
enabled again when a new data arrives in a method spa_alsa_write.
In rare cases, when there is multiple streams providing data and one of
them is disconnected, a new data fails to be delivered and the spa_alsa_write
is not called. Not providing data produces underrun and alsa-pcm invokes
recovery process. Recovery process starts a new playback, but without interrupts
enabled is graph not triggered and new data are not delivered (to enable
interrupts). Recovery process keeps running in loop.
Now the interrupts are enabled again after the recovery and the starvation
should not occur.
Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
Don't set the UMP type flag on the format. Use the negotiated types flag
to decide what format to output. Add support for output to old style
midi.
Set the UMP type flag only on the new mixer and JACK when UMP is
enabled.
This ensures that only new (or explicitly requesting) apps get UMP and
old apps receive old midi.
This makes JACK running on 1.2 in flatpaks work with midi again.
There is no need to encode the potential format in the format.dsp of
control ports, this is just for legacy compatibility with JACK apps. The
actual format can be negotiated with the types field.
Fixes midi port visibility with apps compiled against 1.2, such as JACK
apps in flatpaks.
SysEx in UMP can span multiple packets. In MIDI1 we can't split them up
into multiple events so we need to collect the complete sysex and then
write out the event.
Fixes SysEx writes to ALSA seq by running the event encoder until a
valid packet is completed.
Also fixes split MIDI1 packets in the JACK API when going through the
tunnel or via netjack.
Check midi client version after setting it, to see if it was really
successfully set. Old kernels without UMP don't know about the midi
version fields, so snd_seq_set_client_midi_version() appears to fail
silently there.
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.
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.
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.
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.
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.
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.
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.
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>
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>
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>
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.
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.
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.