Commit graph

84 commits

Author SHA1 Message Date
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
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
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
Barnabás Pőcze
934ab3036e treewide: use SPDX tags to specify copyright information
SPDX tags make the licensing information easy to understand and clear,
and they are machine parseable.

See https://spdx.dev for more information.
2023-02-16 10:54:48 +00:00
Wim Taymans
f472fd736d fix includes
Only include debug we need. We usually only need the debug types.
2023-01-18 13:12:16 +01:00
Wim Taymans
97aafe2234 fix use_buffers checks
We can set 0 buffers even if there is no format.
Return -ENOSPC when too many buffers are set.
2023-01-10 12:30:25 +01:00
Wim Taymans
5b2b93f915 alsa: add period-size, period-num and headroom in props
Add the currently configured alsa hw_params in the properties for
easier access.
2022-09-06 20:16:29 +02:00
Wim Taymans
9123710971 spa: clean up some port io checks
We should not generate a warning.
2022-09-01 15:39:34 +02:00
Pauli Virtanen
df2c5d6a14 alsa: fix uninitialized variable 2022-07-06 14:36:22 +00:00
Wim Taymans
0f62d3442c alsa: handle driver bugs better
Use the NEAREST flag when setting a format. This only works for raw
formats and will update the format with the nearest accepted rate
or channels. We can then query the real configured format and use that
for the converter.

This makes things work when a driver tells us it can do 44100Hz but then
refuses and changes the rate to 48000.

See #2197, #2457, #2455, rhbz#2096193
2022-06-23 10:20:49 +02:00
Wim Taymans
16f1d6349d alsa: don't crash on NULL params 2022-05-25 15:33:18 +02:00
Wim Taymans
c48a4bc166 pw-cat: fix DSF playback again
Make the DSD buffers a little bigger because we scale down the rate.
Read an interleaved number of samples to fill one quantum.
2022-04-28 12:32:08 +02:00
Wim Taymans
1647c169b2 alsa: improve latency update 2022-03-04 17:21:17 +01:00
Wim Taymans
bcdd1ea811 alsa: set better ranges on properties 2022-03-04 17:21:14 +01:00
Wim Taymans
5010125452 alsa: make internal latency configurable with params 2022-01-18 11:46:08 +01:00
Wim Taymans
c8d4cef2d2 alsa: remove unused properties and hardcoded values 2022-01-12 17:51:49 +01:00
Wim Taymans
776b52749f Use configured quantum_limit instead of hardcoded value
Parse the quantum_limit parameters and use this to scale the buffers so
that they can contain the maximum allowed samples instead of the
hardcoded 8192 value.

See #1931
2022-01-12 17:50:12 +01:00
Wim Taymans
50ce9a794f alsa: relax the max latency requiremen
Our max latency is based on the buffer_size / 2, one part is playing and
another part is filling.
2022-01-12 17:20:42 +01:00
Wim Taymans
03f069c35b alsa: handle extra propinfo in all cases
When we don't have iec codecs, increment the result.index to iterate
the remaining properties.
2022-01-03 16:16:16 +01:00
Wim Taymans
35cbe4e939 buffers: make alignment optional
Make the alignment parameter optional when negotiating buffers.
Default to a 16 bytes alignment and adjust for the max cpu
alignment.
Remove the useless align buffer parameter in plugins, we always
set it to 16 anyway.
2022-01-03 12:32:26 +01:00
Wim Taymans
e31f9aa0f2 alsa: don't set id in PropInfo for params
The id is useless when dealing with props params, we need to use the
name of the property as the key. Also the id can clash with other ids
of other plugins.
2021-12-02 11:35:12 +01:00
Wim Taymans
d673158db1 alsa: expose all config options as params
Add PropInfo for all the params that we can configure at construct
time and also add them as PROP_params.

This way you can configure the headroom at runtime with this:

pw-cli s <id> Props '{ params = [ "api.alsa.headroom" 1024 ] }'
2021-11-30 17:43:07 +01:00
Wim Taymans
8995129e6c alsa: refactor property parsing
Move the common property parsing to the init function.
2021-11-23 12:27:36 +01:00
Wim Taymans
25bfc9c63d alsa: refactor a bit
Make spa_alsa_close() do spa_alsa_pause() first and also clear the
format.
2021-11-23 12:20:27 +01:00
Wim Taymans
13923416e0 alsa: keep track of rate in card object
Expose the card object and always obtain one per pcm.

Keep the configured format in the card object.

Add a api.alsa.multi-rate property. When multi_rate is disabled,
only allow the last configured card rate on all PCMs.

This works around drivers that can't handle multiple samplerates
on their PCMs.

With this patch it should be mostly safe to configure multiple
sample rates in pipewire.conf

See #1547
2021-11-23 11:44:26 +01:00
Wim Taymans
7eee45ff41 alsa: remove stray log line 2021-11-17 10:52:43 +01:00
Wim Taymans
dfdd9a6b3b alsa: don't prefix NAME, log topics are enough 2021-10-03 08:05:40 +02:00
Peter Hutterer
e9d869b46f spa: implement a log topic for alsa 2021-09-28 09:35:39 +02:00
Wim Taymans
1b5d02dd31 alsa: add enumeration of DSD formats 2021-09-21 10:50:44 +02:00
Wim Taymans
349324b9a6 alsa: pass AES bits to S/PDIF devices
This is the right thing to do and might even fix output to some
devices.
2021-09-14 12:42:03 +02:00
Wim Taymans
435de99428 Increase pod buffer size
The props of a 64 channel node are at least 2048 bytes long so make sure
we can build and filter them.

Fixes #1574
2021-09-06 15:09:28 +02:00
Wim Taymans
e5886b7bc6 alsa: pass POD_Long as (long) varargs 2021-09-02 15:17:36 +02:00
Wim Taymans
ab3e265b2c alsa: emit param changes correctly
Use the param user field to tag changes in the params.
codec changes emits an EnumFormat and Props change.
Accumulate various param changes and emit them together.
2021-09-01 13:22:47 +02:00
Wim Taymans
01f640709e alsa: always list PCM as iec958 codec
Always put PCM as the supported format for iec958.
Only accept iec958codecs for iec958 capable nodes.
2021-09-01 13:22:39 +02:00
Wim Taymans
437275460c alsa: add set_format for iec958 formats 2021-08-23 11:31:52 +02:00
Wim Taymans
9dfe35b17c alsa: add enumeration of iec958 format
For hdmi and iec958 devices, enumerate the iec958 formats and
codecs. Initially only PCM is supported as a codec but with
a property or an init option, the list of codecs can be dynamically
configured.
2021-08-23 11:31:52 +02:00
Wim Taymans
c39d374ca8 alsa: hook up latencyOffsetNsec in ALSA sink/source
This property is exposed on the device Route and forwarded to the
nodes. It then configured the process_latency.ns field, which
influences the reported port latency.

This makes it possible to change the internal port latency on the
sink and source with pavucontrol and tweak the synchronization to
compensate for internal latencies in the device.
2021-08-17 11:57:12 +02:00
Wim Taymans
a2083d12d4 alsa: add params to set default internal latency 2021-08-17 10:15:40 +02:00
Wim Taymans
6d196b1d11 alsa: use ProcessLatency param to get and set internal latency 2021-08-17 10:04:12 +02:00
Wim Taymans
4c09eb227f alsa: rename indexes into port and node params 2021-06-24 10:03:41 +02:00
Wim Taymans
8cf5927e95 alsa: keep track of input and output latency
track and report both input and output latency.
2021-06-24 09:59:48 +02:00
Huang-Huang Bao
8c42e6aecb alsa,bluez5: handle SPA_PARAM_Latency in port_set_param
Simply return 0 instead of -ENOENT.

Fixes #1262
2021-06-05 17:52:40 +00:00
Wim Taymans
35e81fbfdc alsa: rework UCM open
Use _alibpref to check if a device needs a UCM local config. Mark
the device as such and use this to set the OPEN_UCM property on
the device.
Open the UCM for a card when the device has the property set. Use the
same logic for loading the UCM as the acp code.

See #1251
2021-06-02 17:25:21 +02:00
Wim Taymans
e3d3f04780 alsa: if we are passed a UCM device, make sure to open UCM
UCM devices can require local data from use_case_mgr_open() but since
we do that in a separate process, make sure we reopen the use case
manager in case we are passed a UCM device so that the config is
available.

See #1251
2021-06-02 13:23:08 +02:00
Wim Taymans
b9b89b92b2 spa: add some latency helpers
Add more fields to the latency object.
Add methods to create, parse and process latency info.
2021-05-27 15:26:09 +02:00
Wim Taymans
1cd6d7b01d spa: Implement latency reporting
Implement latency reporting in alsa
Implement latency reporting on audioconf by passing on the latency
from the follower to outside of the adapter.
2021-05-27 15:26:09 +02:00
Wim Taymans
46ef88e520 spa: save the old change_mask and restore when emitting full
When we add a new listener to an object, it will emit the full state
of the object. For this it temporarily sets the change_mask to all
changes. Restore the previous state after this or else we might not
emit the right change_mask for the next listener.

Consider the case where one there are two listeners on an object.
The object emits a change and the first listener wants to enumerate the
changed params. For this is adds a new listener and then triggers the
enumeration. If we set the change_mask to 0 after adding the listener,
the second listener would get a 0 change_mask and fail to update
its state.
2021-05-27 15:21:44 +02:00
Wim Taymans
39a2636c9b alsa: clean up port and node params 2021-05-21 11:08:52 +02:00
Peter Hutterer
cdfd50e166 spa: add spa_atob() to convert a string to a boolean
This replaces the manual check for "true" and some (inconsistent) return value
of atoi. All those instances now require either "true" or "1" to parse as
true, any other value (including NULL) is boolean false.
2021-05-18 22:18:56 +10:00
Peter Hutterer
95a84e797a treewide: replace !strcmp() with spa_streq()
This change is only done in source files for now, header files will be done
separately.
2021-05-18 22:10:27 +10:00