nframes in the midi buffer should be set to the current cycle
buffer_size and it should restrict the timestamps that can be set on the
midi events.
Keep the last max_frames around in a globals so that we can use it to
set the midi buffer to the default size.
Return NULL when we do jack_port_get_buffer() with larger nframes than
the current cycle buffer_size, just like JACK. Otherwise this could
result in a crash when we try to mix more than the available buffer
space.
Check and reset the midi buffer better. Check if the MAGIC is still ok.
jack_midi_reset_buffer() should restore the MAGIC and other values.
The output buffer size is always the current cycle buffer_size.
The size that is give by the JACK API is only used to restrict the
number of mixdown samples or midi offsets.
Fixes#3892
On the midi input ports, do the same trick as on the output ports:
first convert the midi to JACK and then copy the whole buffer to the
port specific storage.
This makes it possible to have a different midi buffer per port and
allow multiple threads to get the buffer concurrently.
Fixes#3901
node.sync-group can contain a list of strings. When a node in the graph
sets node.sync = true, it will be scheduled with all of the other nodes with
common node.sync-group strings. By default all nodes are placed in
group.sync.0 except the freewheel and dummy driver.
Use this to ensure that all nodes are grouped under the same driver
(that is not the freewheel and dummy driver) as soon as the transport is
started so that the transport is visible to all nodes from the same
sync-groups. We also don't deactive the sync-group anymore for the node,
even if the transport is stopped, to avoid driver changes and transport
jumps.
When the node that activated the sync/transport is destroyed, things are
restored to their original state. Note that this is different from JACK
where starting the transport outlives the application and always needs
to be explicitly stopped again. We can't really do this (by default) because
it leaves the graph in an unnatural state with all devices in sync.
The reason for the node.sync-group is that it is possible to still have N
different subgraphs with a separate transports by manually specifying
the node.sync-group.
It's also slightly different from the node.group, that is always active.
The sync-group is something you only want to enable in specific cases
because it groups drivers together and enables adaptive resampling etc.
It's also possible to place this option in the jack.conf file to
automatically sync all devices and apps as soon as a jack app is started.
Fixes#3850
Don't just overwite the node.group property when changing the freewheel
thate but append the frewheel group and remove it again to preserve
the original node.group.
Keep track of the active number of mixer ports and update the global mix
io in sync with the data thread because that is where we will check the
state of the global mix io.
This is mostly important for output ports. When removing all links from
an output port, we first will clear all the mixer io and then remove the
global mixer with client_node_port_set_mix_info(). If we don't clear the
io before that, the data thread will be using that buffers as they are
cleared.
See !1915
When we clear the port io, pause the core until the invoke call
completed. This way we don't start processing other messages until we
have safely removed the port io.
Normally, when clearing a link on a port, first the mix io will be set
to NULL and then the format will be cleared, which clears the buffers
as well. By delaying the processing of the format clear until the io
is removed from the data thread we avoid taking away the buffer memory
from the processing thread prematurely.
When creating a link, first the format and buffers are configured and
then the io is set, which should be safe in all cases.
See !1915
Make a rtprio-server and rtprio-client option. Leave the server
priority by default to 88 but lower client priority to 83. JACK
does something similar by setting clients to rtprio-server - 5.
Make module-rt use the client priority by default and bump the server
priority explicitly in the config file.
Leave the pulse-server to the default rtprio-client, there is no reason
to lower this any further because it is really just a regular client.
Bump the ffado packetizer thread to rtprio-server + 5 because that is
also what JACK does.
88 is still much higher than the value of 60 that JACK uses in
Fedora but now this is at least configurable.
Add a new property that controls how connections between other ports are
handled. This can be used to block jack apps from connecting or
disconnecting port they don't own.
We already checked if a node is_jack when it appeared in the registry
with the client.api property, so don't check again with ALWAYS_PROCESS
when the node properties changed.
When we get a node info about our own state, we can use the active state
of the node to decide if we are running or not.
See #3794
We should not use nsec from the clock as the current_usec because
current_usec is supposed to be an idealized time when the wakeup would
have happened and nsec is when it actually happened.
Instead use next_nsec and subtract the rate corrected period from it to
get the idealized current_usec.
We can still use nsec to calculate the elapsed time since the wakeup and
be sure that it is always in the past.
Some JACK clients place OSC messages in MIDI buffers. Try to detect the
OSC messages and mark the control as OSC.
Also allow OSC control to be converted to JACK MIDI.
This should make things work better with native PipeWire clients that
handle MIDI and OSC.
Ardour calls jack_port_get_buffer() from multiple threads. For audio
buffers this will result in mixing the input samples into the target
buffer and there is no window for having a corrupt buffer.
For MIDI, there is a problem because we need to convert from and to
PipeWire MIDI and while we do that from multiple threads, the midi
buffer can be incomplete or corrupt.
Fix this by building the intermediate POD to a thread-local scratch area
and then copy it to the target buffer. If this is done from multiple
threads there is no moment where incomplete data can be seen in the
target buffer.
Make the complete midi-scratch buffer thread_local so that we also avoid
a race when converting midi data from a foreign port.
When we write into the scratch buffer when mixing and converting input
midi data, we also avoid a race there.
Fixes#3632
Avoid reading from the activation directly to get cycle times but copy
the relevant fields of the clock when the cycle starts. Use the unique id
to get a consistent copy of the data.
This avoids some stay frames and values in jack_showtime.
Improve get_buffer debug.
Add some extra checks for the type before we try to use the object as a
port.
Set latency range to 0 when called with wrong port. Ardour seems to call
into us with ports from a previous jack_client..
When we get a midi buffer directly from one of our peer ports, we need
to convert it to a jack midi buffer.
Note that this previously returned NULL because of the size check of the
midi buffer, which was likely much smaller than the frames argument.
This fixes midi event recording preview in ardour.
PW_VERSION_NODE is 3 while PW_VERSION_NODE_EVENTS is 0, I am unsure if
it could have caused issues. Same thing with PW_VERSION_PORT &
PW_VERSION_PORT_EVENTS.
I have not seen code checking this version number.
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
do a sync when starting up client and sync when creating a new proxy so
that we get all the proxy updates before the client is opened.
This ensures all ports are enumerated correctly.
Fixes#3618
Don't set the port io to NEED_DATA in prepare_output because this
might be called when we get the data from an input port that is linked
to out output port.
See #3514
We can directly use the port io, which is always available. This ensures
the mix->io status is set to NEED_DATA even when there is no global
mix.
This reverts part of 56786aedc4
See #3514
Some jack clients will take a lock before doing IPC and then will
take the same lock in a notify callback. This prevents the IPC from
progressing and causes a deadlock.
Make a separate thread to dispatch the notify so that we don't block the
IPC in any case.
Fixes#3585
Some jack clients like to lock the process function and so we can't be
sure we will deadlock while we try to wait for the data-loop.
Instead, don't sync with the data-loop when setting the mix-io, it will
happen later when it is possible. Queue a free operation of the memmap
after the mix_set_io if we need to clean up.
See #3585
This reverts commit 6fefd49a8a.
We can't use PRIVATE because mmap docs say that we then might not see
changes in the data anymore from other processes.
Fixes#3575
Do a do_sync after setting the metadata to ensure the messages are
flushed to the server and processed. Fixes an issue where jack_property
would exit before the messages are flushed and so nothing happens.
Change the shellcheck job so that we configure the build and check the
preprocessed versions of the scripts, not the bare ones, which might not
be syntactically valid yet.