SysEx in UMP can span multiple packets. In MIDI1 we can't split them up
into multiple events so we need to collect the complete sysex and then
write out the event.
Fixes SysEx writes to ALSA seq by running the event encoder until a
valid packet is completed.
Also fixes split MIDI1 packets in the JACK API when going through the
tunnel or via netjack.
Add an option to add the MIDI2 flag on ports. This is disabled by
default because most JACK apps don't know about the flag and then
refuse to show the MIDI ports.
Fixes#4584
The transport update is set in the node properties. If one client tries
to start and another tries to stop we have two conflicting desired states
in the nodes.
Fix this by making the state update a one time property and remove it
from the sever and client properties after updating it. We then need to
keep the new state around and apply it once.
Keep the node driver state as it is unless there was a transport state
update.
Fixes#4543
The JACK2 maintainer would prefer to use a new port flag to mark the
MIDI2 capability of the port and keep the port type as MIDI. Add the
proposed flags to the API.
If we register a MIDI port with the MIDI2 flag, promote it to UMP.
Expose v1 MIDI ports with the MIDI DSP property again.
If we see an UMP port, set the MIDI2 flag on the port.
This is functionaly equivalent to what we have. Old jack midi ports will
now however not have the UMP DSP format but the old MIDI format so that
we can, in the JACK API, make a distinction between MIDI1 and MIDI2 ports.
`(n_items) + 1 * sizeof(*items)` is not the correct size to allocate
for `n_items + 1` count of objects each with size `sizeof(*items)`,
the `+ 1` should be inside the parentheses.
Fixes#4481
Fixes: 4baa94fce2 ("thread: make it possible to set a custom create function")
In our current world, it is possible to have a negative delay. This
means that the stream should be delayed to sync with other streams.
The pulse-server sets negative delay and the Latency message can hold
those negative values so make sure we handle them in the helper
functions as well.
Do the delay calculations in pw_stream and JACK with signed values to
correctly handle negative values. Clamp JACK latency range to 0 because
negative latency is not supported in JACK.
We should also probably make sure we never end up with negative
latency, mostly in ALSA when we set a Latency offset, but that is
another detail.
When we are asked to clear the mix io areas, actually do it, otherwise
the process thread might still be accessing the old memory and crash.
Also check that we have set io on the port before we decrement the
counter with active io or else we have a negative value and cause
problems later. This can happen when we susupend and set io to NULL but
there was never any io set on the port.
Fixes#4337
Free the client ports when closing.
Move the per client cached objects to the global cache.
Free the per-client cached mix and ports.
Add a destructor that frees the cached global objects.
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.
The bar can start from 0 in JACK.
Add bar_start_tick and ticks_per_beat to the io_segment_bar so that we
can losslesly store the complete jack BBT values.
See #4314
This gets the next key and value from an object. This function is better
because it will skip key/value pairs that don't fit in the array to hold
the key.
The previous code patter would stop parsing the object as soon as a key
larger than the available space was found.
Add spa_json_begin_array/object to replace
spa_json_init+spa_json_begin_array/object
This function is better because it does not waste a useless spa_json
structure as an iterator. The relaxed versions also error out when the
container is mismatched because parsing a mismatched container is not
going to give any results anyway.
JACK emits the bufsize callback from the processing thread while
jack_activate() is called. Do the same with a blocking invoke.
The GStreamer plugin relies on this and when it reives the bufsize
callback later, it will error out.
Fixes#4260
Use the pipewire header version for the minor/micro/proto in the
jack version. That way the jack version will increment and we can
easily see what pipewire version it was compied with.
Add 2 new port format extensions, one for OSC and another for UMP.
Make sure we convert the events from UMP/OSC/MIDI to jack events
depending on the port type.
Try to produce UMP by default.
jack_port_get_buffer() can be called with 0 frames, This is to restrict
the available space in the returned midi buffer after mixdown. While we
mixdown, we should not check timestamps so that all midi events are
added to the mixdown buffer.
Fixes qsynth.
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
This is the driver id that the client has received and is using right
now. We don't use this yet but it could be used in the future to check
if a client has the most up to date info.
Make sure newer clients can work with an older server:
- Add client and server versions in the activation
- On older server, clients needs to trigger peers without CAS of status
- On older server, jack transport is started with command.
- Use client version to know when to set the INACTIVE/FINISHED
state on the server instead.
- Async clients need to trigger peers on old server.
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.
Manage them like we do on the client and reuse logic. Make a node
function to safely add and remove a target.
Activate the targets from the process loop when we can be sure that we
can resume them. This avoids incrementing the pending state when we are
not going to be able to resume the nodes (like when the cycle is ongoing
and we have already been scheduled) and avoids glitches and xruns.
When a node is added to the poll loop, it can activate its own targets.
This is mostly for driver so that they have something to schedule and
can then activate the other targets.
Try to resume the target when it is removed and we are supposed to be
scheduled.
Also add targets to the target_list when the node is remote to make sure
the profiler can see the targets as well.
Keep the node in the INACTIVE state as long as the eventfd of the node
is not added to the loop. Skip nodes in the INACTIVE state from going to
the NOT_TRIGGERED status, which avoids scheduling the node.
Make sure we remove any local targets we have in a node when we export
it, we will receive new targets from the server.
This should eliminate any glitches when adding and removing nodes from
the graph.
See #4026, #2468
Atomically change the node status from TRIGGERED to AWAKE. Only trigger
the peer nodes when the node was previously in the AWAKE state.
When we remove a node from the graph or when we destroy a link, we need
to manually resume the peers. We can do this now by atomically setting
the node to FINISHED and checking if it was previously != FINISHED.
This ensures that removing nodes/links never leaves some nodes (and also
the driver) untriggered and cause a xruns.
Fixes#4026
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.
Instead of doing (cycle+1) & 1 for output ports, simply swap the io
areas depending on the port direction (0 = input, 1 = output) and
just to cycle&1 for all ports.