Commit graph

279 commits

Author SHA1 Message Date
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
George Kiagiadakis
726234c82f audioconvert: always push out data when the out_offset reaches max_out
No matter if the input data (n_samples) is > 0, the code here should
flush out existing data if the output buffer is full
2024-11-04 20:36:12 +02:00
Wim Taymans
e2991f6398 json: add helper function to parse channel positions
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.
2024-09-18 09:54:34 +02:00
Wim Taymans
cd81b5f39a spa: add spa_json_begin_array/object and relaxed versions
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.
2024-09-16 09:50:33 +02:00
Wim Taymans
40cd8535eb audioconvert: only accept UMP on the control port 2024-07-30 09:38:40 +02:00
Wim Taymans
61dcd8dede audioconvert: set IO_Buffers only when buffers are negotiated
The IO_Buffers is used in the data thread to check if the port should be
scheduled or not. Make sure it is only set after we set buffers on the
port and cleared before the buffers are cleared.

Make sure we sync the port->io with the data thread.

See #4094
2024-07-29 18:15:06 +02:00
Wim Taymans
9d1d1fcbef impl-port: add port.group property
Can be used to group ports together. Mostly because they are all from
the same stream and split into multiple ports by audioconvert/adapter.

Also useful for the alsa sequence to group client ports together.

Also interesting when pw-filter would be able to handle streams in the
future to find out what ports belong to what streams.
2024-06-24 13:38:09 +02:00
Diego Viola
7410755c03 Fix typos
found them with codespell.

Signed-off-by: Diego Viola <diego.viola@gmail.com>
2024-05-22 09:19:34 +02:00
Wim Taymans
b97c6e2eac audioconvert: also clamp monitor volume to min/max
When we set a min/max value, also clamp the monitor volume to it.

Fixes #3962
2024-04-15 16:28:24 +02:00
Wim Taymans
ea524b158c audioconvert: add monitor.passthrough option
Add a monitor.passthrough option. This will pass all latency information
directly between the port and its monitor ports.

This is interesting when the adapter (and audioconvert) is used with a
null-audio-sink that simply forwards the data to a real sink/souce. In
that case, we want the sink/source latency to be passed unmodified.

Set the monitor.passthrough on the pulseaudio null-sink because
a passthrough virtual sink is the most likely use case for this.

Add some monitor.passthrough default config where it makes sense.

Fixes #3888
2024-03-11 16:20:27 +01:00
Wim Taymans
a82e95c37d audioconvert: handle invalid ports better
Keep track of the valid ports and don't emit port info for
invalid ports. When a listener is added while the ports are being
created, it is possible that the ports are still NULL or invalid.
2024-02-28 11:29:01 +01:00
Wim Taymans
86af9de739 adapter: remove factory.mode property
We can deduce this from the way the node is configured with the
PortParam now.
2024-02-23 16:28:11 +01:00
Wim Taymans
627f148665 audioconvert: also place resample output in rate_io
We can also place the estimated size that the resampler will produce in
the rate_io for output streams.

See #3750
2024-01-16 13:29:57 +01:00
Wim Taymans
63e283f377 audioconvert: update initial resampler rate match
When starting the converter, calculate the initial size needed by
the resampler to fill one quantum.

This makes it possible to get the requested amount of samples before
the first process call is made.
2024-01-15 15:03:54 +01:00
Pauli Virtanen
eaea03c26c spa: export log topic enumerations 2024-01-04 10:02:55 +00:00
Wim Taymans
c94d5d9d34 audioconvert: improve allocation
Don't try to allocate each time port buffers are set but only once
before we start procesing.

Also allocate enough temp buffers are there are ports. This saves us
quite a bit of memory in the normal case.
2023-10-13 18:05:42 +02:00
Wim Taymans
11320cf203 tweak number of buffers
In most cases we can use just 1 buffer.

The alsa-pcm-source needs at least 2 buffers so increment the min
limit.
2023-10-13 14:00:29 +02:00
Barnabás Pőcze
8256a2d5a6 spa: remove unnecessary indirection for some spa_log_topics
This results in shorter machine code since it removes one
pointer load and a NULL check.
2023-10-06 13:08:24 +00:00
Wim Taymans
14114a7386 audioconvert: warn -> debug 2023-10-03 20:39:40 +02:00
Wim Taymans
48e11c6fe0 audioconvert: handle realloc errors
The original pointer is untouched when realloc fails and returns NULL so
make sure we free the previous values.
2023-10-03 20:38:11 +02:00
Wim Taymans
c4944dad17 audioconvert: silence some debug info 2023-09-27 11:44:31 +02:00
Wim Taymans
016d15e598 ratelimit: missed -> suppressed
To avoid confusing with missed samples.
2023-09-08 12:18:23 +02:00
Wim Taymans
ebeae802ad audioconvert: improve tag and latency handling
Don't just forward the tag and latency events to the follower but let
the audioconvert aggregate and emit the updated tag/latency event
that is then configured on the follower.

When using the DSP mode of the audioconvert, this results in an
accumulated latency/tag from all the DSP ports instead of just
the last DSP port param update.

Put properties with media. prefix in tags in pw-cat.
2023-09-07 15:27:21 +02:00
Wim Taymans
41dcac0ecd Port: Add tag param
The tag param has a list of arbitrary key/value pairs. Like the Latency
param, it travels up and downstream. Mixers will append the info
dictionaries or do some more fancy merging.

The purpose is to transport arbirary metadata, out-of-band, through the
graph and it's used for stream metadata and other stream properties.
2023-08-29 14:22:13 +02:00
Wim Taymans
b9d78d5992 audioconvert: add queued input to the delay
The input that we have queued will also add to the resampler delay.

Fixes #3454
2023-08-22 13:06:10 +02:00
Wim Taymans
71262da6d7 audioconvert: remove requirement for data_loop
We just need to get a timestamp so that we can do the rate limiting, we
don't need anything accurate from the data_loop.
2023-08-01 18:20:04 +02:00
Wim Taymans
536129343a audioconvert: rate limit the out-of-buffer logging
See #3384
2023-08-01 15:06:28 +02:00