Commit graph

305 commits

Author SHA1 Message Date
Wim Taymans
13b8c23767 Don't use SPA_AUDIO_MAX_CHANNELS directly
Make a MAX_CHANNELS define and use that one in code. This makes it
easier to change the constant later.
2025-10-21 09:43:06 +02:00
George Kiagiadakis
2aa725e4fe audioconvert: accept prop params that are encoded as Long in the pod 2025-10-10 13:48:10 +03:00
Gabriel Golfetti
df2f36ad8f Add support for mappable buffers in mixer-dsp 2025-10-04 10:04:50 +00:00
Wim Taymans
2385aa18e1 audioconvert: handle filter-graph setup better
Force filter graph reconfiguration in setup_convert.

When adding/removing filter-graphs, only perform setup when we were
already setup, otherwise we will do this in setup_convert later.

Don't do channelmix_init when we were not setup.

Deactivate the filter-graphs when we suspend.

Fixes #4866
2025-08-27 17:56:14 +02:00
Wim Taymans
e35a8554f8 control: improve UMP to Midi conversiom
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..
2025-08-19 18:33:59 +02:00
Wim Taymans
ec5d2d2a29 audioconvert: rework the stage recalc a little
Use bits to capture the work that is needed. We clear the bit when
we added the stage, when all bits are cleared we have nothing more to
do. This avoids having to check multiple bookleans.

Make a helper function to calculate the destination buffer. When all
bits are cleared, we can use the output buffer.
2025-07-18 12:10:30 +02:00
Wim Taymans
8babd0bc4e audioconvert: remove unused field 2025-07-18 12:02:28 +02:00
Arun Raghavan
a328e0ae28 spa: audioconvert: Avoid reading past filter-graph param name end
Ensure we have at least a `.` after `audioconvert.filter-graph`, so we
don't try to read past the end if it does not exist.

Also document in the param name that an index is expected.
2025-07-09 15:20:09 +00:00
Wim Taymans
653e1578a1 audioconvert: use faster clear when dealing with empty buffers
When we are converting an empty buffer, use the more efficient
clear function.
2025-07-02 10:34:00 +02:00
Wim Taymans
a9cece3c2e audioconvert: remove unused field 2025-06-25 10:37:56 +02:00
Wim Taymans
8a09bacdf6 audioconvert: map buffers with right prot 2025-06-25 10:31:39 +02:00
Wim Taymans
bcb9ff20fd audioconvert: mark output as not empty when draining
When we are draining, we use an empty input buffer but then we push out the
remaining samples out of filters and we can't assume they are empty.
2025-06-25 10:31:24 +02:00
Wim Taymans
cad0523617 audioconvert: refactor volume ramping
We don't actually have to store the ramp parameters so allocate them on
the stack and then use them to generate the sequence.

Make it possible to generate a sequence into a custom buffer as well.

Make sure we use the right rate (the graph rate) to calculate the number
of samples when converting from time to samples.
2025-06-19 11:16:34 +02:00
Wim Taymans
8047a37b02 spa: remove control type from formats
We just want to negotiate the control stream, we don't really care
about what is in the control stream.
2025-06-18 15:23:16 +02:00
Wim Taymans
f7fdafc203 loop: add method to run a function with the lock
Convert some _invoke to _locked
2025-05-29 10:17:16 +02:00
Wim Taymans
564c9b1ba5 Use "8 bit raw midi" for control ports again
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.
2025-05-23 16:46:13 +02:00
Wim Taymans
218f25088c convert: place the right id in the portconfig format 2025-05-14 18:21:39 +02:00
Wim Taymans
093b3eea21 audioconvert: implement graph latency reporting
Keep per graph latency. Sum all the graph latencies together and keep
this around as the process-latency.

Refactor the port latency setter. Make a function to recalculate the
latency of all other ports. Take into account the graph latencies.

Update the port latencies when the total graph latency changes.
2025-05-14 09:21:31 +02:00
Wim Taymans
c334bfb0bb audioconvert: do params after init of the node
First do the essential properties to set up the node, then set up the
node and then parse the params. The params might do some setup that
relies on a completely configured node, such as emit events.
2025-05-14 09:19:17 +02:00
Wim Taymans
37bf571db3 audioconvert: keep the graph latency around 2025-05-13 15:27:17 +02:00
Wim Taymans
2420c3a8c8 convert: refactor node_set_param functions
Move them to their own function to make the main function shorter.

Also make sure we emit the new ports first and then the node info.
2025-05-12 11:39:02 +02:00
Wim Taymans
8dfa086c3c audioconvert: refactor params
Move the param enumeration code out of the main enum function.

Emit node events after completion of the set_param functions to ensure
we only emit things once.
2025-05-12 11:39:02 +02:00
Kenny Levinsen
558721efc2 audioconvert: Increase param length limit to 4096
Parameter values read into a 512 byte long buffer, which is insufficient
for medium to long filter-graph parameters.

Increase the buffer to 4096 bytes to give some wiggle-room.
2025-04-11 20:03:25 +00:00
Wim Taymans
b501290bd5 audioconvert: support DYNAMIC data again
Because we advertize on out ports that we support DYNAMIC data, we need
to read the data pointer directly from the buffer and only fall back to
our cache (mmaped) pointer when it is NULL.

With DYNAMIC data, the peer element (mixer-dsp) directly copies the
input data pointer into the buffer data in the processing loop in order
to avoid a memcpy when there is no mixing needed.
2025-03-27 17:00:11 +01:00
Wim Taymans
328718f958 audioconvert: add support for buffer data mmap
When there is no data and the buffer is mmapable, try to mmap it. Unmap
again when clearing the buffers.

Use the mmaped data pointer of the buffer when processing.
2025-03-27 15:37:19 +01:00
Wim Taymans
ea7cfb9e94 audioconvert: make sure the converter is in None mode
The audioconverter starts in Convert mode, so make sure it goes to the
None mode before we attempt to reconfigure ourselves.

Also remove the ports on audioconvert when going to None mode. This used
to somewhat work because we configured it in DSP mode without any
params, which is like None without ports.
2025-03-26 10:26:41 +01:00
Wim Taymans
de54cfc475 audioconvert: improve tmp buffer allocation
Use per port allocated memory so that we can easily increase the size
and add more buffers. This is necessary when we add filter-graphs that
require more ports.
2025-03-21 15:18:54 +01:00
Wim Taymans
bcde5cbd8a audioconvert: rework the filter-graphs a little
Use a simple free/active linked list for the filter-graphs and insert
the new filters in the right position in the list. Then simply copy the
list to an array for the processing thread.

when reconfiguring, set up all the filters again because the number of
channels might have changed.
2025-03-19 17:53:05 +01:00
Wim Taymans
de2ab7cac9 filter-graph: add support for channel positions
Make it possible to define a channel position in filter-graph.
Use the channel positions to perform the final channelmix.
2025-03-19 17:53:05 +01:00
Wim Taymans
f1ed12fc8d audioconvert: PortConfig only needs channels and position 2025-03-14 13:25:45 +01:00
Wim Taymans
f0e09ae363 filter-graph: make the filter-graph ports dynamic
When parsing the graph, parse the input and output port names into
a separate string array. This was we can keep them around when
setting up the graph.

Instead of setting up the graph right after loading it, do the graph
setup when we activate the graph. This makes it possible to pass the
input channels to the filter-graph and let it create the right amount of
plugins and ouput channels.

When setting up the graphs in the audioconverter, pass the current
number of channels as the input to the graph and keep track of the
channels that each filter produces.

This way we can also load a custom upmix or downmix graph, for example.
2025-03-14 10:10:18 +01:00
Wim Taymans
76619eaa1d audioconvert: fix the filter-graph samplerate
The filter graph runs before or after the resampler depending on the
direction of the conversion.
2025-03-14 10:03:44 +01:00
Wim Taymans
badd8691bd audioconvert: remove some unused fields 2025-03-11 11:52:52 +01:00
Wim Taymans
d43fb09ea1 audioconvert: configure resample channels correctly
Depending on the direction of the conversion, we run the resampler
before or after the channelmix. This means we need to use the channel
count before or after the channelmixer instead of always using the
channels after channelmixing.

Fixes #4595
2025-03-11 11:50:48 +01:00
Wim Taymans
98b6469b88 audioconvert: handle rate_scale in both directions
We need to take the direction of the conversion into account when
deciding if we should apply rate scaling.
2025-02-11 11:58:55 +01:00
Arun Raghavan
e57a01594e audioconvert: Only use rate_scale when working at DSP rate
In convert mode, we will be resampling directly to the output rate, so
don't try to scale to driver rate.
2025-01-21 08:50:43 -05:00
Wim Taymans
d2c2276088 adapter: pass follower direction to converter
Partially revert 86af9de739

The PortParam does not give enough information to derive the direction
of the converter. If the converter is configured in convert/convert
there is just no way to know when to output a quantum or not.

Fix this by doing a quick probe of the follower and then pass the
direction to the converter.

See !2227
2025-01-21 11:43:11 +01:00
Pauli Virtanen
5f21ee8669 audioconvert: add delay_frac to spa_io_rate_match
Report the "fractional" part of the resampler delay in
spa_io_rate_match::delay_frac, in nanosamples (1/1e9 sample) at node
rate.

The delay values are best reported in units where it is clear what the
clock domain is, so report the value in fractional samples instead of
nanoseconds. Conversion to ns is also just dividision by the appropriate
rate.
2025-01-19 17:11:13 +02:00
Wim Taymans
85c5d65c97 audioconvert: only consume from input what the resampler used
Keep track of the consumed samples from the input and use that to update
the in_offset. The resampler can tell us how much samples were used.
2025-01-17 12:20:06 +01:00
Wim Taymans
f914cf9327 audioconvert: the delay of the resampler is in input rate
The resampler needs ntaps/2-1 (delay) input samples to produce 1 output
sample so the delay is measured in input rate.
2025-01-15 17:02:39 +01:00
Wim Taymans
0913b3ef7b audioconvert: report delay in input rate
The delay is always expressed in samples at the output rate of the
resampler. For input streams we need to convert this to the expected
input rate.

Make the delay reporting in playback streams more accurate.
2025-01-15 15:25:49 +01:00
Wim Taymans
049ab37a6d audioconvert: only deactive old filter when new filter loaded
When we fail to load the new filter, keep the old filter active or else
we will cause a crash when we clean up the old graph.
2025-01-13 16:58:28 +01:00
Wim Taymans
73e11eea46 audioconvert: add wav stage only when needed 2025-01-13 15:39:32 +01:00
Pauli Virtanen
7d8657b7f4 audioconvert: recalculate stages on volume change
Volume changes may change mix passthrough status, so force stage
recalculation when they are done.
2025-01-11 16:13:11 +02:00
Wim Taymans
48416b32ad audioconvert: improve Buffer params
Make sure we only make the buffer for the follower larger when we
downsample because then we need to ask for more data from the follower
to fill up a quantum.

Never try to make the follower buffer smaller than the quantum limit.
The reason is that the graph rate could be decreased dynamically and
then we would end up with too small buffers.

See #4490
2025-01-09 11:30:02 +01:00
Wim Taymans
3a65472e9e audioconvert: add support for filter-graphs
Load multiple graphs with audioconvert.filter-graph.N where N is the
order where the graph is inserted/replaced. Run the graphs before the
channelmixer.

Graphs can be added and removed at runtime.
2025-01-07 13:20:31 +01:00
Wim Taymans
1f4e8b96c2 audioconvert: fix remap stages
Merge remap with convert to simplify some things.
2025-01-07 12:58:59 +01:00
Wim Taymans
c00df67c12 audioconvert: schedule work offline
Instead of recalculating what to do every cycle, we can prepare a
static schedule and just run that. We only need to reevaluate it when
something changes.
2025-01-07 12:58:55 +01:00
Wim Taymans
3fbf84f612 audioconvert: run resampler depending on direction
For input streams, first run the resampler and then the channelmix. This
ensures that the channelmix is run with the rate of the graph instead
of the rate of the input. This is nicer because rate and quantum align
with the graph and the sample accurate volume ramps will work as
intended.

For output streams, leave the resampler after the channelmix for the same
reasons.
2025-01-07 12:03:59 +01:00
Wim Taymans
68877dcee7 audioconvert: only output when there is something to output
Or else we get 0 sized output buffers.
2024-11-06 09:28:09 +01:00