Commit graph

1066 commits

Author SHA1 Message Date
Wim Taymans
c6745ed0d0 alsa: refactor read and write functions
Separate the sync logic from the read/write functions so that we can use
it in the wakeup logic as well.
2023-09-15 12:21:18 +02:00
Wim Taymans
e975cb16d3 alsa: add spa_alsa_prepare()
Split the spa_alsa_start() in a prepare and start function. Prepare
will then also reset state and prefill the playback buffer with silence.

This makes it possible to reuse the prepare function in recover().
2023-09-15 11:15:26 +02:00
Wim Taymans
a5d684af8a alsa: make sure we recalculate config when samplerate changes
The threshold depends on the samplerate and even when the graph rate or
quantum didn't change, the driver could be opened in a different
samplerate, which would cause the timeouts to be wrong and cause xruns.
2023-09-15 11:14:10 +02:00
Wim Taymans
99cf172bc7 alsa: improve debug
Use a new state variable to store the device name and direction so that
we consistently can debug those.
2023-09-15 09:09:04 +02:00
Wim Taymans
3c5da11706 alsa: set_timeout is only called when tsched is enabled.
We don't need to do an extra check.
2023-09-14 17:16:44 +02:00
Wim Taymans
4ffa7860bc alsa: update the clock name when we can
Update the clock name as soon as we get a io_clock. This way we can use
it to compare the clock name against the driver right away.
2023-09-14 17:15:06 +02:00
Wim Taymans
354ee6fd96 alsa: with IRQ we can use avail_update()
It does not need an ioctl because the driver already updated the info
before waking us up from poll.
2023-09-14 16:16:48 +02:00
Wim Taymans
b094057b0b handle NULL latency param
Fixes #3504
2023-09-13 11:13:48 +02:00
Wim Taymans
9c834427c6 alsa: small cleanup
We always try to write when we have data so we can make this code path
common.
2023-09-08 12:19:52 +02:00
Wim Taymans
016d15e598 ratelimit: missed -> suppressed
To avoid confusing with missed samples.
2023-09-08 12:18:23 +02:00
Wim Taymans
7c7dea890b alsa: redirect dict debug to log 2023-09-07 11:57:43 +02:00
Carlos Rafael Giani
8e6d070148 alsa-compress-offload: Add device object and udev based autodetection
As part of this, in alsa-udev.c, certain structures and variables referred
to as "device" are renamed to "card". Otherwise, there is ambiguity, since
"device" can mean a udev device, an SPA device, a compress-offload device,
a PCM device etc.

Also, replace "card id" with "card number" to emphasize that these integers
are not actually SPA object IDs.
2023-09-02 08:28:22 +00:00
Carlos Rafael Giani
ae4bff78a3 alsa-pcm-device: Minor logging improvements 2023-09-02 08:28:22 +00:00
Carlos Rafael Giani
61518e71fc alsa: Rename spa_alsa_device_factory to spa_alsa_pcm_device_factory
This makes it clear that this is specifically a factory for PCM nodes.
2023-09-02 08:28:22 +00:00
Wim Taymans
ccc591ae0f alsa: use target_rate from the position
We need to use the target_rate of the clock in the position io area to
get the next rate of the graph.
2023-09-01 10:02:28 +02:00
Wim Taymans
6fb53fc9f1 alsa: round to next power of 2 for max period_size
Prefer to make the period_size bigger rather than smaller because of
rate conversion.
2023-09-01 09:54:58 +02:00
George Kiagiadakis
af020bc425 alsa: report latency in the samplerate domain of the graph 2023-09-01 00:30:14 +03:00
Wim Taymans
21392d898e alsa: improve xrun clock field calculation
We're missing the delay in samples plus all of the extra samples of
silence we use to restart the device. This is in the samplerate of
the device.

Convert this to the time domain of the graph before adding it to xrun.
2023-08-31 14:28:56 +02:00
q66
aa11dbe10c alsa: get rid of non-portable isinf use
The isinf function returns -1 for negative infinity on glibc, but
the standard guarantees no such behavior (e.g. in C++ it always
returns a bool, on musl libc it's a macro that expands to a bool
expression), saying just that it returns a non-zero value.

This was added in pulseaudio around 15 years ago, and was never
fixed; pipewire then got the code from it. However, we can portably
check against -INFINITY instead (from math.h, already included).

Ref 045c1d6
2023-08-31 10:37:22 +00:00
Wim Taymans
d2c29760e9 alsa: scale the default period with the rate
The default period is based on the default rate and might be too small
when using high samplerates. Scale the rate with the samplerate and make
sure it's a power of 2 to avoid trouble.

Fixes #3444
2023-08-31 12:01:06 +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
6bf42e9bcd alsa: refuse quantum/rate changes when driving irq based 2023-08-29 10:14:43 +02:00
Wim Taymans
e90cab1cde node: add xrun counter in clock io
Add an xrun counter in the clock that accumulated the duration of
xruns. Fill this in in alsa-pcm.

A client could use this to dectect xruns (when it changes) and to align
the position and nsec after an xrun.
2023-08-29 09:22:45 +02:00
Wim Taymans
3685081fd1 alsa: add device.profile.pro property
It is set to true when the node is using a pro audio profile.
2023-08-29 09:22:27 +02:00
Wim Taymans
d08d05629b alsa: reflow some code
Move common code outside the if branches.
Only do the batch and timer stuff when using timers.
2023-08-23 13:56:20 +02:00
Roman Lebedev
4694b48b7b alsa-card-profiles: simplify adding custom profiles
It is sometimes useful to add a custom profile-set.
For that, e.g. `default.conf` needs to be modified.
(at least, i have not succeeded in just adding a new file)

But that change gets overridden when the package is updated,
which could be *extremely* dangerous, e.g. if said profile
changed the `volume-limit`.

By shipping an "empty" `9999-custom.conf`,
the update becomes less problematic,
because one can now use e.g. `dpkg-divert` on said file.

Refs. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1050293
2023-08-23 10:06:16 +00:00
Wim Taymans
091b5497a3 acp: try to set a verb before probing pro-audio devices
Some UCM devices need to be configured with a verb before we can try probing
the pcms. Find the highest priority verb and set that.
2023-08-07 12:56:24 +02:00
Wim Taymans
fd585baa88 alsa: don't change avail when unchanged
Only update the avail when we did a snd_pcm_forward(). Otherwise
we might think there is more available than there really is and we
might get xrun.

See #3395
2023-07-31 12:10:36 +02:00
Wim Taymans
dd78f3d5f7 alsa: disable htimestamp by default
It seems there are drivers that don't return a good values and we end up
with a lot of delay or automatic disable of htimestamp when the values
look too off.
2023-07-26 10:32:53 +02:00
Wim Taymans
dc07c2321b spa: add spa_ratelimit 2023-07-11 19:25:35 +02:00
Barnabás Pőcze
fe45786a5d treewide: add some examples for the spa_auto* macros 2023-07-11 14:23:53 +02:00
Wim Taymans
159fa7177a alsa: fix threshold sign
Be careful when converting the uint32_t to int64_t, first convert and
then flip the sign.
2023-07-05 12:01:08 +02:00
Wim Taymans
937a13d93f alsa: relax htimestamp threshold a little
Only assume an error when larger than 3 times the expected size. Clamp
to the threshold to not cause excessive delay compensation.
2023-07-05 11:46:19 +02:00
Wim Taymans
927eb64177 alsa: use get_avail() recover logic
Always use get_avail() and then only fetch the hires timestamp when
enabled to enhance the delay reporting. This way we also recover from
errors from snd_pcm_avail() instead of ignoring them.

This should make the recover after mmap_begin obsolete but we'll leave
that just to be safe.
2023-07-03 17:08:08 +02:00
Wim Taymans
2963e7fd4c alsa: disable htimestamp when it seems to error too much 2023-06-29 16:40:21 +02:00
Wim Taymans
f76191c792 alsa: add option to disable htimestamps
Add api.alsa.htimestamp to disable the use of hires timestamps.
2023-06-29 16:23:39 +02:00
Wim Taymans
3dab0091bb alsa: warn when the htimestamp seems wrong
The htimestamp should be close to the current_time, if it is further
away that the threshold, something is wrong.
2023-06-29 15:56:43 +02:00
Wim Taymans
b32715ba41 alsa: try to recover when mmap_begin fails
In case the get_avail call did not catch the device error, handle the
error and try to recover in the mmap_begin call instead.

See #3315
2023-06-27 13:25:47 +02:00
Guido Günther
88bb0bd7cc alsa: Allow to augment ucm port properties
Since UCM doesn't perform the path lookups of alsa-mixer all UCM devices
fall back to the card's properties for e.g. icons and hence usually show
the `audio-card` icon for all ports giving a confusing UI to users as
all ports show the same icon.

As ucm names are pretty standard augment some common port names with
icons.
2023-06-26 19:39:31 +00:00
Carlos Rafael Giani
d20fc2a8ec alsa-compress-offload-sink: Fix format renegotation
The have_format flag was not being properly processed, leading to
incorrect behavior when the format param was enumerated.
2023-06-24 16:54:15 +02:00
Arun Raghavan
de2d7a583b alsa: Actually write out pitch elem value during initial reset
Without this, we were assuming our inital rate of 1.0 was also what was
applied to the feedback endpoint, but that was not actually true.
2023-06-23 16:45:36 +00:00
Michael Olbrich
e808875d60 alsa: improve audio output to multiple devices
There are currently several issues when multiple alsa devices are
involved.

For alsa devices that are followers, all data is written via
impl_node_process(). Currently spa_alsa_write() is only called if a new
buffer was queued.
It can happen that all buffers are in the ready list (queued by previous
calls but not yet written because there was no free space in the kernel
ring buffer). In this case writing stalls indefinitely.
To fix this, also call spa_alsa_write() if no new buffer is queued but
there are still buffers in the ready list.

If the ready list of the primary device is not empty then only this
device is handled because spa_alsa_write() is called directly. The other
devices make no progress during this interval.
The clock drift calculation works by comparing the alsa delay with the
expected delay since the last wakeup. This only work if the alsa
ringbuffer was filled completly. If the ready list contains a partial
buffer then the ringbuffer is not filled and the timing calculation
during the next wakeup is incorrect.

To fix all this, remove the special case for the non-empty ready list
and just call spa_node_call_ready() every time.
2023-06-22 09:28:44 +00:00
Wim Taymans
f2ba4caaf0 alsa: silence ctl probe errors
ALSA seems to emit some errors to stderr when the ctl can not be opened.
Silence those errors, we handle and log the result ourselves.
2023-06-19 17:20:57 +02:00
Wim Taymans
1589506c7c alsa: ratelimit impossible timeout messages 2023-06-19 16:58:29 +02:00
Arun Raghavan
abb300750f alsa: Implement playback/capture rate control for USB gadgets
If we detect Playback/Capture Pitch 1000000, we can adjust those values
to update the feedback endpoint for the host. On the capture side, this
will instruct the host to adjust the rate at which data is being sent.
On the playback side, this will adjust the amount of data the USB gadget
driver sends out in each USB tick.
2023-06-17 08:56:41 +00:00
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
318d82e14f alsa: avoid division by 0
After we se the format, we negotiate the buffer size and period size.
When this fails, the period_size can be 0. Handle this case without
causing a floating point exception.
2023-05-08 16:49:33 +02:00