FireWire ALSA driver latency is determined by the buffer size and not the
period. Timer-based scheduling is then not really useful on these devices as
the latency is fixed.
In pro-audio profile, enable IRQ scheduling unconditionally for these
devices, so that controlling the latency works properly.
See #4785
Some devices (FireWire) fail to produce audio if period count is < 3,
and also have small buffer size. When quantum is too large, we might
then get too few periods and broken sound.
Set minimum for the period count in ALSA, to determine the maximum
period size we can use. If smaller than what we were going to use, round
down to power-of-2.
See #4785
The Max latency property only works for timer based scheduling so that
we don't select a quantum larger than we can handle in our buffer.
With IRQ based scheduling this does not make sense because we will
reconfigure the buffer completely when we change quantums and so the
currently selected buffer size does not limit the latency in any way.
Fixes#4877
Some drivers (Firewire) have a latency depending on the ALSA buffer size
instead of the period size.
In IRQ mode, we can safely use 2 (or 3 for batch devices) periods
because we always need to reconfigure the hardware when we want to
change the period and so we don't need to keep some headroom like we do
for timer based scheduling.
See #4785
Improve the spa_ump_to_midi function so that it can consume multiple UMP
messages and produce multiple midi messages.
Some UMP messages (like program changes) need to be translated into up
to 3 midi messages. Do this byt adding a state to the function and by
making it consume the input bytes, just like the spa_ump_from_midi
function.
Adapt code to this new world. This is a little API break..
We can't move the mix_list ports to the free_list like that because the
elements in the list use a different list to link together. Also, we
don't need to free those ports at all because they will be freed when we
move the port_list to the free_list.
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.
In USB Audio Class 2 (UAC2) setups, pitch control is handled by
feedback endpoints. The host adjusts its data rate accordingly.
When pitch control is active (pitch_elem), applying the default
delay-locked loop (DLL) bandwidth can lead to instability and
oscillations around the target rate.
This patch adds a new parameter, api.alsa.dll-bandwidth-max, to
configure the maximum DLL bandwidth. It introduces a new field
in the ALSA state to store this value.
By default, it uses SPA_DLL_BW_MAX, but when pitch control is in
use, setting it to a lower value (e.g. 0.02) helps ensure better
stability, based on empirical testing.
In some cases, it is possible that the follower shares a clock with the
driver, but the driver rate is not known when the follower is assigned
to the driver. If this happens, then state->driver_rate is 0, and when
setting the format, we might think that we need to resample (because
follower rate != driver rate). This can cause us to incorrectly halve
the period size for the node.
This was introduced in commit 0b67c10a9c,
which forces reevaluation of matching status on driver change.
To avoid this, let us also probe for the driver rate when updating the
matching status, so we can make the update more accurate.
Some devices might have nonfunctional 'Pro Audio' sound. This patch adds a
new 'api.acp.disable-pro-audio' option to disable pro-audio profile entirely.
This reverts commit b57b87abbb.
It turns out this device is subtily different and doesn't work with the
current profile configurations. A UCM profile was added to alsa-ucm-conf
instead.
Otherwise we won't be able to negotiate with a port that only wants old
style midi.
Instead just negotiate the control link, conversion to old style midi
will be done in the control mixer for the old client.
Fixes#4759
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
alsa_write_sync can insert or remove some data from alsa when
resynchronization is needed.
Avail and delay are equal when high precision timestamps are not allowed.
When the high precision timestamps are enabled, the delay is avail
adjusted to current_time.
Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
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>
config.h needs to be consistently included before any standard headers
if we ever want to set feature test macros (like _GNU_SOURCE or whatever)
inside. It can lead to hard-to-debug issues without that.
It can also be problematic just for our own HAVE_* that it may define
if it's not consistently made available before our own headers. Just
always include it first, before everything.
We already did this in many files, just not consistently.
Including C headers inside of `extern "C"` breaks use from C++. Hoist
the includes of standard C headers above the block so we don't try
to mangle the stdlib.
I initially tried to scope this with a targeted change but it's too
hard to do correctly that way. This way, we avoid whack-a-mole.
Firefox is working around this in their e21461b7b8b39cc31ba53c47d4f6f310c673ff2f
commit.
Bug: https://bugzilla.mozilla.org/1953080
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.
Some devices have a hardware volume control, but not a dedicated
hardware mute control. In some of these cases, the volume control is
described as having a hardware mute when volume is 0. This is described
in the TLV information of the volume control, when the
SNDRV_CTL_TLVD_DB_SCALE_MUTE flag is set in the TLV structure.
If set, alsa-lib will set the minimum dB value to -99999.99dB, which
can be detected inside PipeWire.
PipeWire can then use this hardware volume control to apply hardware
mute, when set.
In order to be able to set volumes and mutes separately, changing the
volume whilst muted will save the value, but not write it to the
hardware. When the device is unmuted, the saved value will be restored.
Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>