Connect the playback stream before the capture stream since the capture
stream can otherwise trigger playback_process() before the playback node
has been activated.
Modules echo-cancel, filter-chain and loopback may print errors if no
applicable target nodes exist when they start up. For our products this
is not considered error/warning worthy, since the issue will resolve
itself once the target nodes exist.
Add a target.delay.sec property to module-loopback that uses a
ringbuffer to further delay the signal to the requested value. This
also takes into account the graph delay to get an end-to-end delay.
Add a -d property to pw-loopback to control this.
Implement latency_msec on the pulse module with this new property so
that it behaves similar to pulseaudio.
First go over all the input and collect pointers and the size that we
need to copy. Then go over all destinations and copy the source or
clear the buffer memory.
This fixes the problem where extra planes in the destination would get
a 0 size, which would make the converter produce 0 output. It also
ensure that the output size is consistent.
It's possible that the stream is sent an error when the session manager
can't link the node (because, for example, the sink/source is not
available yet). We should not stop but just log this error.
When the session manager actively kills the stream (when it is
reconnected while the DONT_RECONNECT flag is true) we will end up in the
UNCONNECTED state and that's when we can unload the module.
Make sure the node name is something unique for the capture and playback
part of filter-chain and loopback so that volumes can be remembered
separately.
Fixes#1983
If not otherwise set, the media.name will be the name used when
pw_stream_new(), which is the same for all loopback streams.
This makes the session manager restore the same volume for all
loopback streams.
Do something more clever and use the node.name + suffix to make
the name unique per stream if no media.name was given.
Fixes#1942
The trigger flag adds an extra dependency on the node so that it does
not automatically get scheduled. A manual scheduling is required with,
for example pw_stream_trigger_process().
This can be used to create an artificial dependency between a sink
stream and a source stream, like when using loopback or filter-chain.
Normally those streams are not linked in the graph but they have an
internal dependency. Without any such dependency, the source part of the
chain will be scheduled first and then the sink part and we get a
cycle of delay (with possible quantum change etc).
With this patch, the sink part will be scheduled first and its process
function will trigger the 'downstream' source stream explicitly. The
sink and source stream will stay in sync and will use the same quantum.
This reduces the latency and glitches because of quantum changes.
Fixes#1873
The node.link-group property marks streams that are internally linked
together in some way. It is used to relate the input and output streams
of some of the module streams.
This also brings the advantage that all tools, examples, modules, components
can also be compiled standalone out-of-tree using libpipewire from the system
Just like the real free() we should just ignore a NULL pointer, makes the
caller code easier for those instances where properties are optional.
Patch generated with concinelle with a few manual fixes.
SPA_MEMBER is misleading, all we're doing here is pointer+offset and a
type-casting the result. Rename to SPA_PTROFF which is more expressive (and
has the same number of characters so we don't need to re-indent).