Commit graph

1287 commits

Author SHA1 Message Date
Pauli Virtanen
916896c1cc alsa: force IRQ scheduling for firewire in pro-audio profile
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
2025-09-07 18:23:31 +00:00
Pauli Virtanen
64aaf8a832 alsa: set minimum period count before automatic period size
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
2025-09-07 18:23:31 +00:00
Wim Taymans
0f6aae914f alsa: don't add MAX_LATENCY when using IRQ scheduling
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
2025-09-02 18:52:38 +02:00
Wim Taymans
9606b37776 alsa: use 3 periods in IRQ mode by default
3 seems to work better as a default for Firewire. It does not actually
add latency because we only keep 1 period filled with data at all times.
2025-09-02 17:29:26 +02:00
Wim Taymans
0095d79ef8 alsa: use 2 (or 3 for batch) periods in IRQ mode
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
2025-09-02 14:13:19 +02:00
alexdlm
b0b6b1fcc5 Map Razer BlackShark v3 ACP 2025-08-27 15:55:02 +00:00
Wim Taymans
e35a8554f8 control: improve UMP to Midi conversiom
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..
2025-08-19 18:33:59 +02:00
Wim Taymans
f562394596 alsa-seq: improve debug
Make it easier to change the event debug. Also add some more context
to the event debug.
2025-08-19 18:33:58 +02:00
Pauli Virtanen
618d60a1f2 alsa: show correct value in api.alsa.period-num 2025-08-09 12:53:41 +03:00
Wim Taymans
c9c7552fed alsa: clear port before adding to free list
If we clear the port after adding, we will destroy the links into the
list and cause crashes later.
2025-08-04 11:02:02 +02:00
Wim Taymans
4715e36a5c spa: don't free the mix_list ports
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.
2025-07-31 10:20:59 +02:00
Wim Taymans
a3da53f66e alsa: fix seq compilation 2025-07-30 18:54:16 +02:00
Wim Taymans
7f7b4be82d alsa: use the safer pod parser for control events 2025-07-30 18:43:34 +02:00
Wim Taymans
6d07eaea1f seq: rework port handling
Dynamically allocate ports as we need them.
Use port lists to iterate active ports.
2025-07-30 17:32:02 +02:00
Wim Taymans
685aed1de2 alsa: update resampler requested size before reading
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.
2025-07-22 16:48:43 +02:00
Karl Relton
9189b1d8b7 Add ACP for Logitech 407 USB PC Speaker set 2025-07-21 12:25:26 +00:00
Karl Relton
eac495f0e7 Option of analog or iec958 stereo output, both merging volume switches 2025-07-21 12:19:13 +00:00
Karl Relton
47e8984450 Upload New File 2025-07-21 12:17:40 +00:00
Wim Taymans
f2fb0b0aa5 alsa: update resample state in all cases
We need to manually recheck the resample state when the matching state
got updated.
2025-07-18 19:20:00 +02:00
Wim Taymans
ce2989891d alsa: init the bw_max value
Otherwise, rate matching doesn't work when it's left to 0.0.
2025-07-18 18:21:18 +02:00
Carlos Rafael Giani
c504851dca alsa-compress-offload-sink: Improve write_queued_output_buffers comments 2025-07-18 10:53:59 +02:00
Carlos Rafael Giani
48716a72b1 alsa-compress-offload-sink: Remove unused variable 2025-07-18 10:53:52 +02:00
Wim Taymans
328e101f37 alsa: don't try to activate resampling with unknown rates
If the driver or our rate is not known yet, don't assume we will need to
resample.
2025-07-15 15:06:24 +02:00
Wim Taymans
0be61add02 Revert "spa: alsa: Try to get driver rate before setting up matching"
This reverts commit 019b53ace8.

This is a result of a different problem, that the rates are compared
when they are unset.
2025-07-15 14:52:31 +02:00
Julien Massot
8aa836d588 alsa-pcm: add support for api.alsa.dll-bandwidth-max
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.
2025-07-07 10:40:11 +00:00
Arun Raghavan
019b53ace8 spa: alsa: Try to get driver rate before setting up matching
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.
2025-07-03 19:02:02 +00:00
Julian Bouzas
a8b9ce2050 alsa: add option to disable pro-audio profiles
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.
2025-07-02 08:11:48 -04:00
Harald Sitter
1541ce3368 Revert "alsa: add Teufel Cage Pro mapping"
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.
2025-06-26 09:19:09 +00:00
Wim Taymans
f3ff25c936 alsa: don't log unknown events with info
Debug is good enough
2025-06-20 15:49:17 +02:00
Wim Taymans
54923bf5bd alsa: remove UMP negotiation constraint
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
2025-06-18 10:10:10 +02:00
Harald Sitter
b57b87abbb alsa: add Teufel Cage Pro mapping 2025-06-17 11:33:38 +00:00
Wim Taymans
f2905c74ed alsa-udev: support alsa.use-ucm
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
2025-06-17 12:54:39 +02:00
Pauli Virtanen
3539374ba7 spa: alsa: fix some coverity warnings
NULL checks.

Change pa_x* malloc functions act like the pulseaudio ones: assert on
failure, as code assumes that.
2025-06-14 14:38:26 +03:00
Martin Geier
d04ee91714 plugins: alsa: increase follower write synchronization when htimestamps are enabled
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>
2025-06-13 22:14:34 +00:00
Wim Taymans
3fdcf0d34c alsa: reset alsa_sync when linked
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.
2025-06-11 13:06:54 +02:00
Wim Taymans
524da5962d alsa: reset dll in prepare
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.
2025-06-11 13:03:18 +02:00
Martin Geier
4976ac7ef9 alsa-pcm: add dsd bit order parameter
Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
2025-06-10 16:28:48 +02:00
Martin Geier
9afa0cd270 alsa-pcm: enable interrupts after alsa recovery
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>
2025-06-10 16:28:46 +02:00
Wim Taymans
9b36e576cb alsa: handle NULL io
It is possible that the port io is set to NULL when the node is
negotiating or destroying.

Fixes #4734
2025-06-10 10:54:36 +02:00
Sam James
2cec77e7df *: unify config.h handling
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.
2025-05-30 10:24:13 +00:00
Sam James
b943c31fd8
*: don't include standard C headers inside of extern "C"
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
2025-05-30 09:48:28 +01:00
Wim Taymans
f7fdafc203 loop: add method to run a function with the lock
Convert some _invoke to _locked
2025-05-29 10:17:16 +02:00
Wim Taymans
564c9b1ba5 Use "8 bit raw midi" for control ports 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.
2025-05-23 16:46:13 +02:00
Wim Taymans
f068e4ba85 alsa: rework the channel params
Avoid adding a None choice, just add one single value without a choice
when the min == max. In that case we can also add a channel position.
2025-05-08 18:17:45 +02:00
Wim Taymans
2d8080cbde alsa: only use default rate and channels when valid
Check the user provided rate and channels and only use them to limit the
rate and channels when they are valid.
2025-05-08 18:16:53 +02:00
Wim Taymans
ff0d6d5677 alsa: clamp audio.channels to MAX_CHANNELS
So that we don't end up trying to use too many channels later on.
2025-05-08 18:14:02 +02:00
Wim Taymans
b2695f86cf alsa-pcm: handle and warn about a driver bug wrt channels
If the driver returns a larger min than max channel count, log a warning
and swap the two numbers.

See #4687
2025-05-08 16:01:18 +02:00
Stefan Binding
7f07448a80 spa: acp: Allow Volume control which supports mute to be used as a hardware mute
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>
2025-05-05 07:40:29 +00:00
Wim Taymans
14f48c7a1c acp: probe max 192 channels
Thr 256 channel probe can cause overflows because we use uint8_t for the
channel count in some places.

Fixes #4669
2025-04-28 09:47:43 +02:00
Wim Taymans
7e4dd9524f alsa-seq: add the source only on success
Otherwise if we have an error with the timerfd, we have the source fd
added and we close the device.
2025-04-28 09:47:22 +02:00