Make a node implementation and export it, just like we do for the
stream. This way we can use the node to implement set_active().
Tweak the draining logic like pw_stream.
When we're using the peaks resampler, allow resampling, even when it is
disabled in the config.
The peaks resampler is just for GUI and would not really change the
signal, so we can allow this.
Add a new JACK sink/source pair that translates to a single JACK
client.
The JACK playback port appears as PipeWire source and is processed
directly, synchronously, through the complete pipewire graph into
the PipeWire sink that is then made available on the JACK capture
ports.
Because all this happens in the same JACK cycle with no delay, the
latency is 0. A jack_iodelay on the JACK server has exactly the same
latency as the jack_iodelay on the PipeWire side.
The PipeWire sink and source are forced into the same rate and
buffer_size as the JACK server and can't dynamically change.
This only supports Audio for now.
When we consumed all the buffer data, don't clear all the fds but only
those that were already consumed in the message. It is possible that we
already have fds for the next message and we don't want to discard
those.
Fixes some intermittend memory map errors.
Calculate the stats at the start of the new cycle. The results will be
about the previous cycle but this gives more accurate results because
we can also include awake and finish times of remote nodes.
Make sure not to change the status of the activation in the ready event
so that we don't overwrite the status of the last cycle yet.
This means we can always set the AWAKE and awake_time, the remote node
might update it when triggered but that's ok.
After processing we can update the FINISHED state for non-remote nodes,
the remote nodes will update it after they complete the process
function.
Handle the update of the activation status before calling resume_node()
because we can call this when starting a cycle or when completing
a node.
Only set the AWAKE status and time in process_node when not exported or
not driving. For an exported driving driver, the server will have
already updated the values before it triggered our last process and then
completed the graph. If we update again in the client, the server will
read wrong values.
Because there is not really a way yet to get the finish time of the remote
driver the awake and finish times are too early. We might be able to fix
this later by making the stats at the start of the cycle from the
previous values.
Keep 2 extra variables to record the driver start and previos driver
start values. This way we can measure the period. This used to be done
with a little hack, using the finish_time of the driver, which was set
previously in resume_node().
For exported driving nodes, the TRIGGERED time is set in the remote-node
before it writes the eventfd to trigger the node_ready event. For
non-exported nodes, we need to set this ourselves.
For non-driver nodes that trigger node_ready, mean that they did an
async resume of the node. This means the node is finished and we can set
the finish_time accordingly.
Pass the ready status to the client-node using the state array.
Don't just SPA_STATUS_HAVE_DATA on the server side but use the value
from the client.
This avoids some potential extra work when a driver sink pulls in data
with the NEED_DATA ready callback but then the server performs the
actions (tee) as if it were SPA_STATUS_HAVE_DATA.
Do BAP audio location selection properly in SelectProperties, now that
BlueZ provides the supported locations there. Remove a previous
workaround.
The audio location in SelectProperties determines the audio channel
allocation, which determines the channel positions.
Add more properties to sink/source to make them always process and
have the right priorities. Make sure the sink has higher priority than
the source so that we can pull in samples through the graph.
Only trigger the graph cycle when driving the graph.
Make sure to return something from process to signal that the graph can
continue processing.
Use a new boolean to check if the follower is allowed to emit a ready
event. This can be done right after negotiating.
Set the started field to true after we finish setting the state of the
converter and follower. This fields is used to block calling into the
process function before we complete the setup.
This avoid a crash in always-process nodes when the node is scheduled
before the audioconverter completes setup.
Propagate stream errors and check for successful negotioation or error
in _prepare(). This will return an error from _prepare() if there is no
target node to link to (unless PIPEWIRE_AUTOCONNECT=false).
It would be preferable to also set PW_STREAM_FLAG_INACTIVE to not start
processing until _start() is called but then it would not be possible to
signal successful negotiation.
When we move a node from one driver to another, don't move the rate
and quantum because this tricks the new driver into thinking it's
already in the correct rate and it will skip doing a complete rate
switch.
This causes some nodes to fail to switch to the new rate, like in this
scenario:
1. mpv (node.always-process = true) appears and is added to the dummy
driver with rate/quantum of 48000/512
2. mpv is linked to an equalizer, linked to a sink, nodes are moved
to the new sink, target rate/quantum is copied to the new sink.
3. sink and followers are started in 48000/512, all is good. The sink
is now configured in 48000/512.
4. mpv is stopped, sinks and eq (input, not output) suspend
5. mpv appears again with 44100/512 and is added to dummy driver, which
is then configured in 44100/512
6. mpv is linked again to eq, nodes are moved, the sink rate/quantum
is copied and the sink thinks it's in 44100/512
7. sink and followes are started but no rate switch is happening because
rate/quantum was copied in step 6. Some followers are not suspended
and don't apply the rate change correctly (eq output).
By eliminating the rate/quantum copy when moving drivers, the sink will
correctly perform the rate change on all nodes.
Fixes#3159
Port added before activate should trigger a port_register callback when
the client is activated.
When calling jack_deactivate, the port_register callback should be
called.
See #2638
The duplex polling issue was due to spa_loop_add_source failing
when source and sink were both using the same fd. We now dup, so the
issue no longer exists.
Remove the now unnecessary workaround, and check the return values from
spa_add_source.
There are core errors that should not trigger a shutdown, like invalid
or destroyed proxy replies. Only do shutdown when we get EPIPE, which is
when the server is stopped.
See #3070