Improve the spa_ump_to_midi function so that it can consume multiple UMP
messages and produce multiple midi messages.
Some UMP messages (like program changes) need to be translated into up
to 3 midi messages. Do this byt adding a state to the function and by
making it consume the input bytes, just like the spa_ump_from_midi
function.
Adapt code to this new world. This is a little API break..
config.h needs to be consistently included before any standard headers
if we ever want to set feature test macros (like _GNU_SOURCE or whatever)
inside. It can lead to hard-to-debug issues without that.
It can also be problematic just for our own HAVE_* that it may define
if it's not consistently made available before our own headers. Just
always include it first, before everything.
We already did this in many files, just not consistently.
There is no need to encode the potential format in the format.dsp of
control ports, this is just for legacy compatibility with JACK apps. The
actual format can be negotiated with the types field.
Fixes midi port visibility with apps compiled against 1.2, such as JACK
apps in flatpaks.
Make a function that can initialize raw audio info from a dict and fill
in the defaults. We can use this in many of the modules when the audio
format is parsed.
Use the helper instead of duplicating the same code.
Also add some helpers to parse a json array of uint32_t
Move some functions to convert between type name and id.
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.
Only set use the graph rate and duration when the ffado.sample-rate
and ffado.period-size properties are set to 0. Othersize use the
configure values.
Without this patch, it would just ignore the settings and always use the
graph rate.
Unloading the module on stream errors is a bit too much because a
suspend can clear the stream error again (or the error might not be
fatal)
This can happen for example when negotiation fails on some stream ports
(wireplumber tries to link the midi ports to audio ports) and it's
better to not completely fail on that.
Fixes#4121
When for some reason we don't manage to transfer data from the source
or to the sink (timeout, scheduling problems..), try to do it when we
get a timeout to avoid xruns.
Expose the acquire_loop/release_loop functions and use them in the
modules.
Make sure the nodes created from the module use the same data loop as
the module. We need to ensure this because otherwise, the nodes might
be scheduled on different data loops and the invoke or timer logic will
fail.
Rework some things so that we can actually completely close and reopen
the driver when suspending. Leaving the device opened but not streaming
causes trouble when ffado-mixer changes the settings in between.
Do this by first doing a probe to get the ports and streams and then
link those to the actual buffers when we start streaming.
Follow the graph rate and quantum so that we open with the right
settings, this makes pw-metadata work on the quantum and rate. It
requires a driver reopen so it might be slower.
Try to handle some errors better.
See #3558
When the midi message does not fit in the current cycle, save it in a
buffer and send it in the next cycle.
Incomplete midi messages will be received in the next cycle and need to
be sent out at timestamp 0 of the cycle.
Detect dropped and incomplete messages and give a warning.
Try to close/open the ffado device when streaming_start() fails. This
seems to be the case after suspend/resume or a cable disconnect.
Unfortunately, ffado seems to be stuck in an unrecoverable state,
though, to make it really work...
Clean up port buffers when the filter is destroyed.
The FFADO source needs to be the driver and the sink the follower so
that captured data can flow to playback without delay.
Instead of starting a new thread for FFADO, use a timer and the data
loop to wait for FFADO. This is not so nice because we do blocking waits
on the data thread but then we can schedule the source and sink without
a context switch from FFADO. We use a timer so that we can set a timeout
period before starting the graph and catch xruns. The timer will be
restarted immediately when the graph completes and we can go back into
the FFADO wait.
FFADO Xrun should result in a new wait() call.
Handle channels better, use AUX for the channels when they don't match
the given positions.
Silence playback when we don't have a sink or sink data.
Stop and start FFADO when the sink/source pause/resume.
PIPEWIRE_CONFIG_NAME=client-rt.conf pw-cli -m load-module
libpipewire-module-ffado-driver '{ ffado.period-size=32 ffado.period-num=2 }
now gives 4.722ms latency measured with jack_iodelay, equal to JACK.
See #3558
JACK current_msec can be in MONOTONIC_RAW or MONOTONIC, depending on how
JACK was compiled (but it's likely MONOTONIC_RAW). PipeWire requires the
nsec field to be in MONOTONIC so take some time snapshots from both
clocks and apply a translation.
Also make sure we only get the nsec time from streams that exist.
See #3886
Make a method to get the current time to compare agains the pw_time-now
field. This is currently CLOCK_MONOTONIC but make this into a method
so that we can more easily change it later.
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.
Remove some includes of private.h
Add some methods to get the mempool of client and context so that we can
remove direct access.
Move some things around.
Use methods to get pw_loop variables.
See #3243