Commit graph

15543 commits

Author SHA1 Message Date
Torkel Niklasson
65a5fa0250 audioconvert: allocate port buffers dynamically
The port buffer table was embedded in struct port as a fixed array
buffers[MAX_BUFFERS] of struct buffer, each holding datas[MAX_DATAS]
(MAX_DATAS == SPA_AUDIO_MAX_CHANNELS == 64). This reserved ~17 KB per
port regardless of the actual buffer/channel count, multiplied by every
active port.

Allocate the buffer table and the per-buffer data-pointer pool in a
single calloc in port_use_buffers(), sized to the real number of
buffers and blocks, and release it in clear_buffers(). free_dir() now
clears each port so the allocation (and any mmapped buffer data) is
released on node destruction. This mirrors the dynamic-allocation
approach already used for the channelmix matrices and preserves a lot
of memory in the common low-channel-count case.

Co-authored-by: Copilot copilot@github.com
2026-06-12 18:19:35 +00:00
Wim Taymans
b5555cc3f6 port-config: add internalFormat to PortConfig
Use the Format for all possible formats on the
EnumPortConfig and the configured external format on PortConfig.

Make a new internalFormat that contains the configured format of the
adapter follower.

Make pw-top use the PortConfig internalFormat in the FORMAT view and fall
back to Format, when not available (for older clients).
2026-06-12 17:50:46 +02:00
Wim Taymans
d780f4f535 Reapply "pw-top: use PortConfig to get the node format"
This reverts commit 91bc0adc07.
2026-06-12 14:36:09 +02:00
Wim Taymans
91bc0adc07 Revert "pw-top: use PortConfig to get the node format"
This reverts commit 5553d30f94.

Accidentally commited, it's a little too soon for this. The PortConfig
Format is not correctly set yet in all cases.
2026-06-12 14:28:14 +02:00
Wim Taymans
f3edb59c78 doc: add more sections in the left side index 2026-06-12 13:28:14 +02:00
Wim Taymans
5553d30f94 pw-top: use PortConfig to get the node format
A node can have multiple port groups and the PortConfig can hold the
current format for each group, so use that in pw-top.
2026-06-12 13:10:58 +02:00
Wim Taymans
7798fb8b16 audioadapter: place (Enum)Format in (Enum)PortConfig
Enumerating the Format on a node does not make sense, this is a port or
stream only property.

Move the enum of the formats to the portconfig param, where it is used
to configure the port group.

This also makes it possible later to have multiple port groups on a node
and have the session manager configure and link them individually.
2026-06-12 13:10:58 +02:00
Wim Taymans
b93c4f933d props: add group name PropInfo and Props
Some objects might aggregate properties from multiple other objects.
Make sure they are grouped together with the group property.

This makes it possible to get per port group properties, for example.
2026-06-12 13:03:25 +02:00
Wim Taymans
d7f32af545 keys: add follow-suspend passive mode to keys docs
Add the missing follow-suspend values for the passive modes.

Make the string to passive mode conversion a bit more explicit about
true and false.
2026-06-12 11:59:36 +02:00
Wim Taymans
cf72a5945b spa: add port config group name
Make a portconfig group name. All ports from the same group have the
same port.group property and can be configured with the corresponding
PortConfig.
2026-06-12 11:17:29 +02:00
Carlos Rafael Giani
4eed79ee81 spa: utils: add SPA_MACHINE_USES_TWOS_COMPLEMENT macro 2026-06-11 20:34:22 +02:00
Carlos Rafael Giani
bb90fdf03b spa: utils: Add SPA_ROUND_UP_POW2_32 and SPA_ROUND_UP_POW2_64 macros 2026-06-11 20:34:22 +02:00
Martin Geier
fa9eb6320a combine-stream: fix incorrect compensate samples on playback restart
update_delay is called primarily when the stream format or latency changes,
and from playback thread, if stream reports different delay as before.
This function calculates the number of compensate samples for each stream
based on the latencies of other streams (which must be in a streaming state).

During the first playback on a new format, update_delay is called multiple times
due to format or latency changes. The delay is calculated only from streams
that are currently streaming. If some streams are not yet streaming, their
latencies are ignored, and the delay is updated later in the processing
thread. The processing thread also stores the stream delay in a local variable
(accessed only from that thread, thus requiring no locking).

On a subsequent playback using the same format, update_delay is still called a
few times, and the delay is updated based on the currently streaming streams.
If some streams are not streaming, their latencies are ignored.
However, this time, the processing thread fails to update the delay for the
previously non-streaming streams. Because the format didn't change, the streams
delay matches the last stored delay from the previous playback. As a
result, the compensate samples are not recalculated.

To properly update the compensate samples, update_delay must also be called
when a stream's state changes to streaming (avoiding the need to clear the
thread-buffered value, which would require locking in the processing
thread).
2026-06-11 20:34:22 +02:00
Martin Geier
32fe4dbda3 bluez: introduce media.min-latency-ms for media source
Target number of samples stored in buffer is calculated by
target = SPA_CLAMP(SPA_ROUND_UP(SPA_MAX(spike * 3/2, duration),
		SPA_CLAMP((int)this->rate / 50, 1, INT32_MAX)),
			duration, max_buf - 2*packet_size);
At beginning of the playback is spike == 0, so the target is set to
duration. Our BT is not able to maintain such low latency and drops
so spike is increased. This can happens multiple times until playback
is stable.

This strategy causes few dropouts at the beginning of a new playback,
in my case on each new track.

Add min-latency-ms property to reduces spikes and the likelihood of
dropouts at the beginning.
2026-06-11 20:34:22 +02:00
Carlos Rafael Giani
943bce9c85 node-driver: Add sync.force-tracking property
This property is useful for forcing tracking behavior even if the clock
can directly be used by timerfd.

This can be useful in cases where the clock is for example the realtime
clock and can shift and change during playback unexpectedly. The node
driver can handle this without a DLL. But, in some cases, graphs can
experience a more stable behavior if the DLL is used and it manages
the readjustment to the updated time.

This is also useful for testing and debugging the DLL's behavior.
2026-06-11 20:34:22 +02:00
Martin Geier
0a8ddba3e9 node-driver: report discontinuity flag when resyncing position
module-rtp-sink is sending data timestampted with clock provided from
a driver. When driver jumps (for example due ptp master change) rtp sink
has to jumps too. Rtp sink is checking for difference between expected and
actual position and is big enough the jump is done. As resync value in
driver is not equal to diff between positions, sink could ends with
not precise timestamps up to 1 quantum.
Emit discont flag when driver jumps, so sink can be reinitialized without
its own heuristic.
2026-06-11 20:34:21 +02:00
Carlos Rafael Giani
0550537ce0 node-driver: Increase DLL speed by using SPA_DLL_BW_MAX
This allows the DLL to react faster to clock pace changes.
2026-06-11 20:34:17 +02:00
Carlos Rafael Giani
3ce1f6e454 node-driver: Reinitialize DLL if error is too large
If the error is very large (after a big discontinuity in the timestamps
for example), the DLL has a hard time compensating, and a full restart
of the DLL without the old measurement history is more appropriate to
get the synchronization back on track faster and with fewer oscillations.
2026-06-11 20:34:12 +02:00
Carlos Rafael Giani
cc1cc27c34 node-driver: Factor on_timeout execution delay into current_time 2026-06-11 20:34:07 +02:00
Julian Bouzas
3a9ffbb56d alsa: acp: emit route param updates when card properties change
When jack state changes cause port properties to be updated, mark EnumRoute and
Route params as changed and call emit_info() so that the device re-emits the
route parameters with the updated port properties.
2026-06-11 11:08:44 -04:00
sirmbcode
593c5d5b07 copied all entity strings to add to descriptor 2026-06-10 23:40:01 -07:00
hackerman-kl
8966d62606 milan-avb: demote periodic MSRP/gPTP/stream dumps from info to debug 2026-06-09 14:28:30 +00:00
hackerman-kl
2eb7fc4588 milan-avb: prefill talker ring with one quantum to kill return-to-zero notches 2026-06-09 14:28:15 +00:00
hackerman-kl
bd17904bbe milan-avb: don't arm SPA_IO_IN on the talker (STREAM_OUTPUT) socket 2026-06-09 14:26:48 +00:00
hackerman-kl
7262d0f34c milan-avb: ensure the pw streams match the milan AVB stream format and derives correct strides,
also fix crash in entity parser when not available
2026-06-09 12:53:38 +00:00
Wim Taymans
25203c5293 acp: avoid segfault when removing a card
Fixes #5255
2026-06-09 09:23:10 +02:00
Wim Taymans
64d3ed4710 acp: make hard and soft volume limit
Make a hard volume limit property that is configured with the config and
can never be changed.

Make a soft volume limit property that can be changed at runtime.

The used volume limit is a combination of the soft and hard limit.
2026-06-08 17:09:06 +02:00
Wim Taymans
1a534cd907 acp: add min and max volume properties
This way, the min/max volume can be updated and saved in the same way as
the volume is updated.

Also add support for this in audioconvert channelmix.
2026-06-08 16:47:13 +02:00
Wim Taymans
fb74ab9054 alsa: add volume limits
Add 3 levels of volume limits.

1. Add api.acp.min-volume and api.acp.max-valume on the ACP devices that
   is applied to all noded from this device
2. Add api.acp.device.<node-name>.min-volume and
   api.acp.device.<node-name>.max-volume that is applied to all nodes
   from the device with the given node-name.
3. Add api.acp.port.<port-name>.min-volume and
   api.acp.port.<port-name>.max-volume that is applied to all ports
   from the device with the given port-name.

The volume settings on an ALSA nodes can either go through the device on
the Routes (ports) to control the hardware mixer volumes and then the
remainder is performed on the nodes in software by the channel mixer.

We need to set the limits on the channel mixer when the hardware mixer
does not have routes.

This is not an easy way to set the volume limits but it provides a
static configuration option to enforce the limits. An easier
configuration option will also make it easier to change/bypass the
limits, which these options can guard against.

See #5266, #4323, #1517
2026-06-08 10:46:56 +02:00
Wim Taymans
1272f77eb5 alsa: fix warning
warning: the address of ‘dev_id’ will always evaluate as ‘true’ [-Waddress]
2026-06-06 21:24:47 +02:00
Arun Raghavan
cb327e5762 spa: alsa: Detect ports for HDMI AC3 profiles
Because the a52 plugin (being an ioplug) does not proxy snd_pcm_info for
its slave PCM, we need a different way to figure out the card associated
with the device. It turns out we do have access to the card index
already in the caller, so let's pass that index down as a fallback.

This is done as a fallback rather than replacing the existing lookup in
case there are situations where they might be mismatched. We could
possibly just replace the existing lookup, but the cost seems low enough
to not merit the risk of changing this.
2026-06-05 19:05:47 -07:00
Arun Raghavan
bb634fb0f9 spa: alsa: Use some #defines instead of raw strings
Makes it easier to find instances where these keys are used.
2026-06-05 12:10:08 -07:00
hackerman-kl
a6ad8b3b62 milan-avb: keep the last-known gPTP grandmaster across transient ptp4l management-query timeouts so the ADP does not flap to advertising self-as-GM 2026-06-05 07:31:43 +00:00
hackerman-kl
024f7201cb milan-avb: revert own-LeaveAll registrar aging — it tears down active SRP reservations on a spec-compliant bridge (802.1Q-2018 8.8.7 Dynamic Reservation Entry); talker disconnect-reset to be redone via the listener explicit MSRP Leave on UNBIND 2026-06-05 07:31:43 +00:00
hackerman-kl
95f796f08c milan-avb: age MRP registrations on the node own LeaveAll so a talker resets its STREAM_OUTPUT on ACMP disconnect — fire the shared MSRP/MVRP/MMRP LeaveAll timer periodically (prime + re-arm, RX_LVA no longer resets it) and transition the registrar IN->LV on TX_LVA, so a departed Listener ages LV->MT -> NOTIFY_LEAVE -> listener_observed=false (802.1Q-2018 10.7.5.20) 2026-06-05 07:31:43 +00:00
hackerman-kl
2bcec2f3f0 milan-avb: bit-perfect AAF audio path — avb.sink/avb.source self-driven drivers (drive_timer + trigger_process), 4-quanta ring (no per-quantum overwrite), rate_diff=1.0 coherent talker drive (no pw-cat resample), monotonic PHC-anchored AVTP timestamps, listener sample-lock driven at recovered mc.rate 2026-06-05 07:31:43 +00:00
hackerman-kl
5b8fa0a9b6 milan-avb: UNSUPPORTED_FORMAT per-PDU vs current format from descriptor 2026-06-05 07:31:43 +00:00
hackerman-kl
5fe0a7e575 milan-avb: pace the talker flush timer on the RT data loop 2026-06-05 07:31:43 +00:00
hackerman-kl
895e3a4fa1 milan-avb: ACMP listener self-heal, CBS-exclusive egress, per-iface MVRP, Milan MaxFrameSize + channel-strict RX 2026-06-05 07:31:43 +00:00
hackerman-kl
90114c9839 milan-avb: AAF media-clock recovery estimator + play-loop actuator + io_changed, SET_CLOCK_SOURCE switch, skip CRF audio data plane 2026-06-05 07:31:43 +00:00
hackerman-kl
66959ca678 milan-avb: read gPTP PHC time for talker/listener via NIC PHC mapped onto CLOCK_MONOTONIC_RAW, decoupled from system clock 2026-06-05 07:31:43 +00:00
hackerman-kl
afc7724070 milan-avb: stabilization extras - MRP registrar-before-notify, scoped-fd cleanup, VLAN sub-iface RX, SET_NAME validation, entity/firmware/8ch, MEDIA_UNLOCK 100ms + seq-settle, MRP Leave on teardown, reset STREAM_INPUT counters on bind 2026-06-05 07:31:43 +00:00
hackerman-kl
93e4957959 milan-avb: msrp: scope Domain re-adjust to matching sr_class_id 2026-06-05 07:31:43 +00:00
hackerman-kl
f3071aa549 milan-avb: msrp: set Listener AskingFailed on RX TalkerFailed 2026-06-05 07:31:43 +00:00
hackerman-kl
7c4fc7027b milan-avb: mrp: do not apply RX_LVA to own attributes when transmitting LeaveAll 2026-06-05 07:31:43 +00:00
hackerman-kl
1f969b51a8 milan-avb: stream: stop bumping STREAM_INTERRUPTED on ringbuffer overrun 2026-06-05 07:31:43 +00:00
hackerman-kl
e9e5bb72a6 milan-avb: acmp: preserve talker entity_id across BIND_RX -> CONNECT_TX round-trip 2026-06-05 07:31:43 +00:00
Barnabás Pőcze
ed951081b1 treewide: avoid unitialized spa_dict::flags
In multiple cases the `flags` member of `spa_dict` is left unitialized,
so try to avoid that. For example in `fill_node_info_proplist()` it is
accessed in `spa_dict_lookup_item()`.

This also modifies `collect_props()` to not depend on a partially initialized
`dict` parameter.
2026-06-04 21:35:47 +02:00
Barnabás Pőcze
bb073d8250 pipewire: introspect: copy SPA_DICT_FLAG_SORTED
When making a copy of the dictionary, copy the sorted flag
as well since the order is preserved.
2026-06-04 21:35:45 +02:00
Barnabás Pőcze
797dbd3d40 spa: param: spa_{param_dict,tag}_info_parse(): update size as well
In both functions the loop can break early, meaning that the true number
of valid items is `n`, and that should be reflected in the updated `*dict`.
2026-06-04 21:35:44 +02:00