Commit graph

5312 commits

Author SHA1 Message Date
Barnabás Pőcze
d3368ee0d5 spa: utils: cleanup: fix __has_attribute() usage
Unknown preprocessor symbols are replaced with 0 in preprocessor
conditionals, so if `__has_attribute()` is not supported, then
the condition will be the following:

  if 0 && 0(__cleanup__)

which is syntactically incorrect.

So split the condition and only check `__has_attribute()` if
it exists.

Fixes: 65d949558b ("spa: utils: add scope based resource cleanup")
Fixes #4962
2025-11-02 19:10:25 +01:00
Wim Taymans
95fb03c8e3 spa: add some more POD tests
Check if the pod size is at least big enough to hold 1 item when getting
array or choice items.

Check that the number of choice values is at least enough to handle the
given choice type. Remove some redundant checks.
2025-10-31 11:39:41 +01:00
Wim Taymans
e9a89822f8 adapter: only recheck formats when convert EnumFormat changed
Instead of always renegotiating a new format and buffers when the
driver changes, only renegotiate when the converter notifies us
of an EnumFormat change. It's possible that changing the driver does
not actually change the result of EnumFormat and then we would simply
renegotiate to the same format and buffers for nothing.

In the audioconvert, check if the target_rate of the new driver has
changed. We keep the last value in our own clock so that we don't
renegotiate when we are removed from a driver (which sets our own
clock as the position). The target rate influences the result of the
EnumFormat params when we are resampling and so we need to emit a
EnumFormat change.
2025-10-30 17:41:24 +01:00
Wim Taymans
ff0bc22cb1 modules: support audio.layout where we can 2025-10-30 12:29:31 +01:00
Wim Taymans
8ba08f3029 spa: add audio.layout property
Makes it possible to define audio channels and position with a
predefined layout string.

It is easier and less error prone to say "5.1" than to spell out
[ FL FR FC LFE RL RR ].

AUX channels have a special syntax. AUX<N> will make <N> AUX
channels. Easier to say AUX128 than to write an array with the
128 AUX channels.
2025-10-30 12:28:07 +01:00
Wim Taymans
056f257058 spa: fix max_position check 2025-10-30 11:26:32 +01:00
Wim Taymans
7706ca6361 spa: fix Cube layout define 2025-10-30 10:10:10 +01:00
Wim Taymans
a837dcd40b audioadapter: renegotiate when driver changes
The renegotiated format can depend on the clock rate of the new
driver.

See #4933
2025-10-28 08:32:03 +01:00
Rui Matos
752de866ae spa: node-driver: Expose the clock id as param properties 2025-10-28 07:18:59 +00:00
Rui Matos
ec11859a48 spa: Add predefined properties for clock identifiers 2025-10-28 07:18:59 +00:00
Wim Taymans
94d0d8bc09 spa: add spa_json_init_relax
spa_json_init assumes that we start in an object and always requires a
key/value pair. If the last part is a key, it returns and error and does
not want to return the key value.

This causes problems when parsing AUX0,AUX1,AUX2 or any relaxed array
withand odd number of elements.

Make a new spa_json_init_relax that takes the type of the container
we're assuming we're in and set the state of the parser to array when we
are parsing a relaxed array.

Fixes #4944
2025-10-27 13:32:03 +01:00
Pauli Virtanen
c6d0b364ab spa: param: add size checks for spa_audio_info* structs
In the API that take struct size for spa_audio_info*, also check the
struct size.
2025-10-26 18:23:17 +02:00
Pauli Virtanen
8a23b13798 spa: param: pass correct struct size to spa_format_audio_raw_ext_parse/build 2025-10-26 17:44:03 +02:00
Pauli Virtanen
68dc45cc62 audioconvert: simplify volume ramp generation
Don't use floating point accumulators, interpolate from sample position.
2025-10-26 14:12:19 +00:00
Pauli Virtanen
b0e308e0dc spa: examples: fix getopt usage + typos in adapter-control 2025-10-26 14:12:19 +00:00
Pauli Virtanen
fe2c62b9b1 meson.build: set project cc flags also for native builds
Use the build flags also for all native build targets.
Avoids spurious warnings in spa-json-dump
2025-10-26 14:12:19 +00:00
Pauli Virtanen
3febf09b85 alsa: fix typoed braces in condition + assign 2025-10-26 14:12:19 +00:00
Pauli Virtanen
93495d3a75 spa: param: infer raw audio channels from position if unset
The behavior before b8eeb2db45 was that spa_audio_info_raw_update()
always sets audio.channels when audio.position is updated.  The new
behavior does not set audio.channels when parsing audio.position.

This breaks things e.g. when combine-sink and loopback nodes are created
with only audio.position specified.

Restore the previous behavior.
2025-10-26 15:47:48 +02:00
Wim Taymans
88c65932d8 acp: use global max channels if defined 2025-10-24 17:16:03 +02:00
Wim Taymans
c8d4de5e77 acp: bump max channels to 128 2025-10-24 17:00:42 +02:00
Wim Taymans
c4244a6cf3 string: use spa_strbuf instead of snprintf magic 2025-10-24 17:00:11 +02:00
Wim Taymans
f7c3d37969 fmt-ops: allocate shaper memory dynamically
It is based on the number of channels so allocate it dynamically.
2025-10-24 12:46:38 +02:00
Wim Taymans
aa0272f6f3 treewide: remove some obsolete channel checks
The spa_audio_info can not be parsed with too many channels so there
is always enough space for the positions.
2025-10-24 10:31:45 +02:00
Wim Taymans
78219471ff spa: remove some obsolete functions
The spa_audio_info array now always holds enough positions for all
channels and we don't need to wrap around.
2025-10-24 09:35:59 +02:00
Wim Taymans
6d74eee874 spa: bump channels to 128 again
Remove the SPA_AUDIO_MAX_POSITION define and use the
SPA_AUDIO_MAX_CHANNELS again.

Make a compile time define to override the default max channels of 64.

Make sure we compile the SPA library with the default 64 channels. If
you use the SPA library on a spa_audio_info you will get 64 channel
support, like before. If you want more channels, you will need to make
a padded structure or redefine the MAX_CHANNELS before you use the
spa_audio_info structures. You can use the padded structure with the
new functions that take the structure size.

With the extra checks in the parsing code, we avoid making a
valid spa_audio_info with too many channels that don't fit in the
structure. This means that code that receives a spa_audio_info can
assume there is enough padding for all the channels.
2025-10-24 08:53:21 +02:00
Wim Taymans
be29ae4ef6 audioadapter: add some more debug info when parsing fails 2025-10-23 18:05:22 +02:00
Wim Taymans
b8eeb2db45 spa: make it possible to extend the spa_audio_info struct
Add functions that take the size of the spa_audio_info struct in various
functions. We can use this to determine how many channels and channel
positions we can store.

Error out if we try to use more channels than we can fit positions. This
is probably the safest thing to do because most code will blindly try to
get the positions without checking the channel count.

Make sure we also propagate errors to the callers.
2025-10-23 17:59:51 +02:00
Wim Taymans
c5533b3c32 spa: add all channel positions to the params
Pass all the positions of all channels to the format param, even when
there are more channels then positions.
2025-10-22 13:26:52 +02:00
Wim Taymans
11f1298f53 spa: make a function to make a channel short name
Make a function that can generate and parse a short name for
the positions that are not in the type list, like the AUX channels.
2025-10-22 13:04:53 +02:00
Wim Taymans
7177f8269d bluez: use function to get the channel position from a name 2025-10-22 12:54:30 +02:00
Wim Taymans
6465a63bf6 spa: parse the audio.position completetly
Parse the audio.position spec completely so that we have the right
number of channels but only store the first max_position channels.

Also rename some field to make it clear that this is about the max
number of channel positions.
2025-10-22 12:47:00 +02:00
Wim Taymans
ae50bb5dc0 audio: don't limit channels to max positions
We can have more channels than we have positions.
2025-10-22 09:39:15 +02:00
Wim Taymans
99bbac9cbf spa: increase SPA_AUDIO_MAX_CHANNELS to 128
This should now not change the ABI because the position array size is
now controlled with the SPA_AUDIO_MAX_POSITION constant.
2025-10-21 17:01:31 +02:00
Wim Taymans
f19b075306 spa: add SPA_AUDIO_MAX_POSITION
Add a new SPA_AUDIO_MAX_POSITION constant with the maximum number of
channel positions that can be kept in the various audio_info structures.

Repurpose the SPA_AUDIO_MAX_CHANNELS as a suggestion for applications
for the max allowed number of channels in the system. Make it possible
to make this a compile time constant.
2025-10-21 16:08:24 +02:00
Wim Taymans
dbc5c81e4a spa: avoid using SPA_AUDIO_MAX_CHANNELS
Use SPA_N_ELEMENTS instead of the array we try to handle.
2025-10-21 16:05:33 +02:00
Wim Taymans
818d1435ce treewide: access the position information using helpers
Make sure we don't access out of bounds and that we use the helpers
wherever we can to access the position information.
2025-10-21 13:06:25 +02:00
Wim Taymans
8bbca3b8f3 spa: add spa_audio_parse_position_n
Add a function that accepts the size of the position array when reading
the audio positions. This makes it possible to decouple the position
array size from SPA_AUDIO_MAX_CHANNELS.

Also use SPA_N_ELEMENTS to pass the number of array elements to
functions instead of a fixed constant. This makes it easier to change
the array size later to a different constant without having to patch up
all the places where the size is used.
2025-10-21 09:59:13 +02:00
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
Wim Taymans
eb096bfb62 spa: provide information about channels > SPA_AUDIO_MAX_CHANNELS
Define some rules for how the position information works for channels >
SPA_AUDIO_MAX_CHANNELS. We basically wrap around and incrementing the
AUX channel counters. Make a function to implement this.
2025-10-21 09:40:08 +02:00
Wim Taymans
ede13a8cb5 spa: don't add more channels than we have positions 2025-10-20 18:31:35 +02:00
Wim Taymans
f453b1545d audio: don't use SPA_AUDIO_MAX_CHANNELS in some places
When we know the max size of the array, just use this instead of the
SPA_AUDIO_MAX_CHANNELS constant.
2025-10-20 18:31:17 +02:00
Wim Taymans
c94aff8cae Revert "audio: bump max channels to 128"
This reverts commit c91f75ae2e.

This change causes a subtle ABI change and also breaks the Rust
bindings.
2025-10-20 09:17:26 +02:00
Pauli Virtanen
da2cecf074 alsa: acp: don't disable dB if negative max unless range is small
Disabling dB volumes for max_dB < 0 was added in Pulseaudio in 2021,
based on a device which had -128..-127.07 range. However, negative
max_dB is valid value for USB devices, and there are devices that have
it.

Eg. Microsoft LifeChat LX-3000 has

numid=6,iface=MIXER,name='Speaker Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=151,step=0
  : values=150,150
  | dBminmax-min=-28.37dB,max=-0.06dB

and the dB range seems to be OK. Web search for "The decibel volume
range for element" also gives other hits with seemingly OK looking
ranges.

Don't disable dB volume unless both the max is negative and the range is
suspiciously small. This should still disable it for the device this
check was originally added for.

Link: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/447
Link: 10ac01a206
2025-10-15 21:37:06 +03:00
Pauli Virtanen
c89acd3e1c alsa: acp: fix volume rounding down causing mute
Some ALSA devices have minimum HW volume value that is muted.  ALSA
indicates it with SND_CTL_TLV_DB_GAIN_MUTE = -9999999 dB/100 volume dB.
When rounding down to HW volume, we may get this muted value.

When determining splitting of volumes to mixers and soft volume, we
don't want HW mixers to set volume to muted, unless the target volume is
actually muted.

Fix by adding element_ask_unmuted_dB_vol() that rounds up if the asked
rounding mode resulted to mute.

This fixes mic getting muted at low volume despite ALSA reporting the dB
values correctly.

Fixes #4890
2025-10-14 08:02:23 +00:00
Pauli Virtanen
91702975f7 bluez5: media-sink: cleanup ISO rate matching
Move accounting for pending ISO packet to the reference time.  Make sure
rate matching is reset on start, and reset matching on resync properly.

Allow resync on first cycle, ok since iso_io->now is valid immediately.
2025-10-14 07:59:55 +00:00
Pauli Virtanen
4e3a5d9e6f bluez5: iso-io: initialize stream->size, now when setting cb
Ensure size and now have valid values after exiting
spa_bt_iso_io_set_cb(), so data may be provided already on first cycle.
2025-10-14 07:59:55 +00:00
Pauli Virtanen
4ca1d70979 bluez5: media-sink: fix silence padding for ISO stream resync
Silence padding larger than ISO packet may be needed for resync when
quantum is large. We can't insert silence by adding data to encoding
buffer, as the encoding buffer may be then too small and it may also be
partially filled.

Fix by inserting silence from flush_data() just before buffers would be
consumed.

Fixes ISO stream alignment at playback start.
2025-10-14 07:59:55 +00:00
Pauli Virtanen
8bf8600e59 bluez5: if Acquire results to NoReply, try to clean up with Release
If BlueZ doesn't reply, it may consider the operation still active.
Try to Release the transport to get to a known state.

This can happen if device doesn't respond to operations in reasonable
time and BlueZ doesn't have its own timeout which is the case for BAP
currently (which is a bug there).
2025-10-11 20:52:59 +03:00
Wim Taymans
4da25df986 filter-graph: accept String param values
We parse the string as a float and if that works, set the value.
2025-10-10 15:03:04 +02:00
Jonas Holmberg
16ce5a2ccf filter-graph: Accept params of type Long
Integer numbers in lua are sent over protocol-native as Longs so make
sure to handle them.
2025-10-10 10:53:03 +00:00