Instead of aligning the buffers to 16 bytes, use the CPU max_align
value (32 on intel).
Move the mix function from a static global variable to a per client
member because this could change per client.
Make a property to pass a custom function pointer to create threads
instead of pthread_create.
Use this in jack instead of bypassing the thread utils create function,
which gives the wrong thread rt priority with rtkit.
Fixes#4099
Avoid freeing the old io Position area before the data loop has managed
to get a pointer to it. Queue a free operation that will be executed
from the main loop after the data loop has the io area.
Fixes a crash when stressing jack clients to switch between drivers.
We are not allowed to call free_link from the data thread because it
does free() and some pw_mem calls which should only be called from the
main thread.
To solve this, pause the core, queue a free_link operation on the data
thread, which will be scheduled after the previous remove_link operation
completes, free the link and then resume the core. Blocking and resuming
the core is necessary because we can't block for completion of the
invoke calls (the jack method is not allowed to block) and we must
ensure that nothing can happen with the memory (like reuse the mem_id)
before we have cleaned it up.
Fixes a crash in jack with create/destroy link stress.
The larger events need to be copied into the target buffer at the same
offset as the source buffer or else we overwrite the header and make
a corrupt buffer.
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
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.
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.
Otherwise, we will try to hide ports from JACK clients that suspend
(while still active).
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.
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.