Parse the audio.position spec completely so that we have the right
number of channels but only store the first max_position channels.
Also rename some field to make it clear that this is about the max
number of channel positions.
Add a function that accepts the size of the position array when reading
the audio positions. This makes it possible to decouple the position
array size from SPA_AUDIO_MAX_CHANNELS.
Also use SPA_N_ELEMENTS to pass the number of array elements to
functions instead of a fixed constant. This makes it easier to change
the array size later to a different constant without having to patch up
all the places where the size is used.
Disabling dB volumes for max_dB < 0 was added in Pulseaudio in 2021,
based on a device which had -128..-127.07 range. However, negative
max_dB is valid value for USB devices, and there are devices that have
it.
Eg. Microsoft LifeChat LX-3000 has
numid=6,iface=MIXER,name='Speaker Playback Volume'
; type=INTEGER,access=rw---R--,values=2,min=0,max=151,step=0
: values=150,150
| dBminmax-min=-28.37dB,max=-0.06dB
and the dB range seems to be OK. Web search for "The decibel volume
range for element" also gives other hits with seemingly OK looking
ranges.
Don't disable dB volume unless both the max is negative and the range is
suspiciously small. This should still disable it for the device this
check was originally added for.
Link: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/447
Link: 10ac01a206
Some ALSA devices have minimum HW volume value that is muted. ALSA
indicates it with SND_CTL_TLV_DB_GAIN_MUTE = -9999999 dB/100 volume dB.
When rounding down to HW volume, we may get this muted value.
When determining splitting of volumes to mixers and soft volume, we
don't want HW mixers to set volume to muted, unless the target volume is
actually muted.
Fix by adding element_ask_unmuted_dB_vol() that rounds up if the asked
rounding mode resulted to mute.
This fixes mic getting muted at low volume despite ALSA reporting the dB
values correctly.
Fixes#4890
Configure the headroom to be equal of the minimum allowed period size for
the configuration.
This is desirable when the ALSA driver's hw_ptr is 'jumpy' due to
underplaying hardware architecture, like SOF.
In case of SOF the DSP firmware will burst read at stream start to fill
it's host facing buffer and later settles to a constant pace. The minimal
period size is constrained by the driver to cover the initial burst and
settling time of the hw_ptr.
Guard this mode of working with a new boolean flag, which is only enabled
for SOF cards, kept it disabled for other cards to avoid any unforeseen
side effects.
Even if the use-period-size-min-as-headroom is set to true, the manual
headroom configuration will take precedence to allow experimentation.
Link: https://github.com/thesofproject/linux/issues/5284
Link: https://github.com/thesofproject/sof/issues/9695#issuecomment-2569033847
Link: https://github.com/thesofproject/sof/issues/10172
Link: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4489
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Replace force_rate with force_quantum. We use force_rate when we need
to play an IEC958 or a DSD format but it does not make sense to just
force the rate without also forcing the duration.
This is also what happens when doing IRQ based scheduling, we then force
both the duration and rate of the graph so we can reuse this logic.
Also when forcing a quantum, take into account the suggested duration
and rate of the graph and scale that with the currently configured rate
for the period size. This gives a quantum that will match the requested
rate better. This is important for the DSD, where rate are very high and
we want the period size to be something reasonable relative to the
selected graph rate.
For batch devices (and when using a timer) we also configure a period
size that is half the duration of the quantum, to make sure we get some
headroom. We however need to force the full duration as the quantum, so
keep track of this scaling and apply when calculating the duration.
Some drivers (emu10k1) appear to not necessarily support more than 2
periods.
Don't fail start if snd_pcm_hw_params_set_periods_min() fails, then we
just set nearest possible periods and buffer sizes.
Based on testing, ALSA FireWire drivers introduce additional latency
determined by the buffer size.
Report that latency.
Pass device.bus to the node, so it can recognize firewire.
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>