Commit graph

216 commits

Author SHA1 Message Date
Wim Taymans
6b6f3432fe alsa: htimestamp needs an operation to sync with hw
So use snd_pcm_avail
2023-06-05 17:15:30 +02:00
Wim Taymans
29e6544bae alsa: enable htimestamp mode
Use snd_pcm_htimestamp to get both the available space and the timestamp
when this was calculated. We can then use this to get a better estimate
of the delay in the device against the graph start and get a more
reliable delay between capture and playback.
2023-06-05 16:49:58 +02:00
Wim Taymans
90e2f4a139 alsa: fix impossible timeouts
Use the avail and read_size to calculate the next timeout, not delay and
target, which could give a negative value and impossible timeout.
2023-06-05 16:49:02 +02:00
Wim Taymans
61ce16b19f alsa: decouple delay from avail
Use separate values for the number of available samples in the
ringbuffer and the delay in the device.

When using htimestamp we can use the tstamp to get a more accurate delay
value against the graph start time.
2023-06-05 16:33:12 +02:00
Wim Taymans
0333ddff45 pod-builder: move some code around to help gcc 13
Make sure to pop the frame before returning errors to stop gcc13
from complaining with -Wdangling-pointer

Fixes #3171
2023-04-20 17:52:27 +02:00
Wim Taymans
381283ad81 alsa: handle old alsa version
Out Ubuntu CI seems to have an older alsa version that doesn't have
snd_pcm_channel_area_addr so include it here.
2023-04-14 19:25:51 +02:00
Wim Taymans
ea7781d7d0 alsa: fix area pointers
We should use the first and step fields to get to the first byte in the
area.

See #3069
2023-04-14 17:52:26 +02:00
Wim Taymans
261fb64849 alsa: separate max_error and max_resync
Use a separate variable to hold the maximum amount of drift we allow
between driver and follower. Ensure this value is smaller than the max_error
and period size so that we have at most 1 period of drift.
2023-04-10 16:28:55 +02:00
Wim Taymans
30657abf28 alsa: also set period size when using IRQ mode
Use the graph duration as the period size even when we are not using
a batch device.
2023-04-10 16:07:24 +02:00
Wim Taymans
d59e1094cd alsa: fix capture timings and drift
Don't reschedule a timeout when we have less samples available than the
target but only reschedule when we have less that the required amount we
need to read. This ensures that we hover around the target level and the
timeouts/rate matching adapts correctly. Previously we would only rate
match if the have at least the target amount of samples, which would
then always result in a possitive rate adjustment and cause drift.

For capture, make sure that there is at least 32 samples of headroom
when we are not using IRQ mode to handle jitter in the timer wakeup.

For capture of batch devices this results in (for a 1024 quantum) a
target buffer fill level of 1024 + 512, and we will read if there are at
least 1024 samples available.

For non-batch devices we aim for a target buffer fill level of 1024 + 32
and read if there are at least 1024 samples available.
2023-04-10 15:02:29 +02:00
Wim Taymans
501a80b247 alsa: fix rate match when using IRQ
When using the IRQ, we are woken up based on processed samples so
compare expected and current clock times to rate match the clock.

Fixes #3144
2023-04-10 13:18:25 +02:00
Wim Taymans
108715ebfb alsa: add tsched use to info log
Fixes !1580
2023-03-30 17:50:35 +02:00
Wim Taymans
a163f29a43 improve logging 2023-03-30 15:03:21 +02:00
Wim Taymans
5ae73fccdd alsa: only update alsa sources when added to the data loop 2023-03-29 15:31:21 +02:00
Wim Taymans
b16b80601d alsa: start playback right away in IRQ mode 2023-03-29 15:13:00 +02:00
Wim Taymans
354836075d alsa: setup sources from the data thread
For IRQ based scheduling we might otherwise be woken up after we only
added one of the fds to the poll loop and then we get an error when we
try to update it afterwards. Instead, add the fds from the data thread
to get things nicely in sync.
2023-03-29 12:21:23 +02:00
Wim Taymans
8c264d2dcb alsa: in IRQ mode, disable sources while we wait
In IRQ mode, disable the ALSA fds while we wait for the graph to produce
data. Otherwise we will wake up very quickly over and over.

When we get more data, we activate the sources again to start the next
cycle.
2023-03-29 11:30:40 +02:00
Wim Taymans
dc5aa21c87 alsa-pcm: use full period size in IRQ mode
We can simply wake up every period and check the timers there is no need
to tweak the period size.
2023-03-29 11:29:43 +02:00
Wim Taymans
aa0d9c5b41 alsa: add disable-tsched to params 2023-03-28 18:27:53 +02:00
Arun Raghavan
26e37b6575 alsa: Implement period-based wakeups
Provides configuration to disable timer-based scheduling. This can be
useful at low latencies, for example, where period-based interrupts
might be more reliable than timers.
2023-03-28 16:22:53 +00:00
Wim Taymans
3698593481 spa: reuse code to clear the timers
We have set_timeout and enable_flush_timer functions to disable the
timers so use those.
2023-03-24 17:55:15 +01:00
Wim Taymans
7b6680ba57 plugins: simplify target_ handling
Drivers should only read the target_ values in the timeout, update the
timeout with the new duration and then update the position.

For the position we simply need to add the previous duration to the
position and then set the new duration + rate.

Otherwise, everything else should read the duration/rate and not use
the target_ values.
2023-03-24 11:36:15 +01:00
Wim Taymans
1bdd5eee69 alsa: update rate/duration from target
Also reorganize some things to reuse more code.
2023-03-23 18:04:36 +01:00
Wim Taymans
2adf8d38d5 node: add target_rate and target_duration in io_clock
Place the target rate and duration in the io clock area.

The driver is meant to read these new values at the start of the cycle
and update the position rate and duration.

This used to be done by the pipewire server when it received the ready
callback from the driver but this is in fact too late. Most driver would
start processing and set the next timeout based on the old rate/duration
instead of the new pending ones.

There is still a fallback for the old behaviour (with a warning) when
the driver doesn't yet update the position.
2023-03-23 17:57:16 +01:00
Wim Taymans
a7322d5043 alsa: improve target delay in ALSA
Don't just limit the max delay of samples we keep in the ALSA ringbuffer
to the buffer_size but to half of it. Make this into a max_delay
variable.

If we have a buffer size of 8192 samples and a headroom of 8192 samples,
when capturing, we would wait for the ringbuffer to contain at least
8192 samples, which would always xrun. When we limit the size to
half, we can still read the data without xruns.

Fixes #2972
2023-03-03 14:59:38 +01:00
Wim Taymans
8ffb74c8e2 alsa: keep more headroom when rate matching
When we are rate matching, keep some more headroom to make sure we
have enough data for the adaptive resampler.

Fixes crackling when following the dummy node and probably also when
following another capture device.
2023-02-02 20:06:58 +01:00
Wim Taymans
1d9640af5a spa: Fix audioconvert overflow when scaling
Add SPA_SCALE32_UP that scales a uint32 without overflow.
Use this for scaling the threshold in ALSA.
Fix the scaling in audioconvert of the buffer size, the scaling was
wrong and it was also causing an overflow resulting in choppy sound in
some cases.

See #2680
2023-01-16 18:28:31 +01:00
Wim Taymans
32a7c85c84 alsa: guard against some invalid values
Avoid division by 0 and other strange things when invalid values
are detected.

Fixes #2953
2023-01-16 16:05:17 +01:00
Wim Taymans
e5ac60b2b2 alsa: increase target for a52 and dca
For encoded format, we need to send bigger chunks to make the encoder
happy. Add a new min_delay variable with this info so that we never
leave less than that amount of samples in the ringbuffer.

Fixes #2650
2022-12-14 12:41:22 +01:00
Jonas Holmberg
6d6a5e2dbb alsa-pcm: avoid an expected resync warning
Log resync message as info when reassigning follower.
2022-12-13 14:47:04 +01:00
Wim Taymans
f44d55f6c2 handle read from timerfd correctly
When reading the timerfd gives an error, we should return right away
because the timeout did not happen.

If we change the timerfd timeout before reading it, we can get -EAGAIN.
Don't log an error in that case but wait for the new timeout.
2022-12-09 17:30:31 +01:00
Wim Taymans
b46d8a8c92 alsa: force playback start when buffer is full
When we try to play data but the ringbuffer is full, we need to start
the device or else we will stay in this situation forever and stay
silent.

Fixes #2830
2022-11-16 20:45:38 +01:00
Jonas Holmberg
22a1e5b848 alsa-pcm: Start playback when there is data
Do not start the playback device until there is data to play. Otherwise
time consuming configuration of other nodes (such as setting hw params
of a capture device) may be done after playback has been started, which
may cause xrun.
2022-10-17 15:21:49 +02:00
Wim Taymans
d22feab92a spa: add macro to simplify array iterations some more
uint32_t i;
	for (i = 0; i < SPA_N_ELEMENTS(some_array); i++)
		.. stuff with some_array[i].foo ...

   becomes:

	SPA_FOR_EACH_ELEMENT_VAR(some_array, p)
		.. stuff with p->foo ..
2022-09-30 16:24:26 +02:00
Jonas Holmberg
dacbeca77e alsa-pcm: Change resync warning logic
Log follower resync messages with info level until there has been a
successful read or write to get rid of the initial warning when starting
a stream.
2022-09-21 16:42:37 +02:00
Wim Taymans
ef39576150 alsa: rate limit some warnings 2022-09-21 15:52:24 +02:00
Wim Taymans
903f831b2d alsa: scale min value back to nominal rate 2022-09-07 23:39:51 +02:00
Wim Taymans
7057cca05e alsa: adjust min and max rates
Use the DSD scaler and interleave factors to calculate the min and
max rates.
2022-09-07 21:58:32 +02:00
Wim Taymans
955815b468 alsa: only scale DSD samplerates 2022-09-07 21:42:45 +02:00
Wim Taymans
68581235ae alsa: fix min dsd rate
We just need to allow from DSD64 onwards. Remove some unused fields.
2022-09-07 20:23:53 +02:00
Wim Taymans
72b6788c68 alsa: don't set impossible rates
When the max rate is smaller than the min rate, don't add the DSD
format at all because it is not possible to play it.

See #93
2022-09-07 19:58:30 +02:00
Wim Taymans
23522651f9 alsa: dsd rates are expressed in byte rate
DSD64 would be a rate of 44100 * 64 / 8. When packed in U32_BE, we would
negotiate 44100 * 8 / 4 (88200) with the device, this means all rates
from 88200 and up are allowed for DSD64 in U32_BE.
2022-09-07 19:54:09 +02:00
Wim Taymans
2054dcf36f alsa: Improve format negotiation
When the device is not running but has a format, close/open the
device to get all the available formats again. Do the same when
setting a format.

Otherwise, the configuration space of the device is restricted to the
current negotiated format and we can't query the other possibilities
or change it.

Fixes #2625
2022-08-31 10:03:39 +02:00
Wim Taymans
54b499b1cf alsa: do the right log level checks
spa_log_level_enabled does not work when a custom log level has
been set. Use spa_log_level_topic_enabled instead.
2022-08-05 15:03:22 +02:00
Wim Taymans
73073eb33f alsa: redirect alsa output to log file
Make a custom snd_output object that redirects output to the log
file.
2022-08-05 14:01:37 +02:00
Wim Taymans
0dc5a08bfd alsa: debug hw_params 2022-08-05 13:00:44 +02:00
Wim Taymans
34c1c1614e alsa: add some more debug
See #2614
2022-08-04 14:25:24 +02:00
Wim Taymans
e22e522ab8 alsa-pcm: limit the target to the buffer size
Don't try to wait for more samples than can fit in the ringbuffer.

See #2603
2022-08-03 12:22:38 +02:00
Wim Taymans
52281b9a7e alsa: check the offset against the size of the buffer
We need to check the last offset against the size of the buffer, not the
remaining size in the buffer.

When the writing is split, this could cause the buffer to be reused
wrongly.

See #2536
2022-07-13 09:37:01 +02:00
Carlos Rafael Giani
7e44909741 alsa: add lower rate bound for DSD playback
This prevents errors when trying to play at a rate
that's lower than DSD64 (the lowest rate available).
2022-07-05 16:56:50 +00:00