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).
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.
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.
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.
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.
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.
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.
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
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.
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.
Only try to round down the period_size to the lowest power of 2 when we
are resampling and scaling the period_size to match.
In all other cases, we should honour the requested quantum duration.
Fixes#5302
Commit b1b565339 ("sendspin: negotiate the first raw format") says that
FLAC and Opus are not supported yet. The receiver also only advertises
PCM formats in its player support.
Reject non-PCM stream/start codecs in the receiver. Otherwise
parse_player() accepts FLAC or Opus without setting client->stride,
while the receive path later uses client->stride as a raw frame size.
Signed-off-by: Wang Yu <wangyu@uniontech.com>