1
Fork 0
Commit Graph

4078 Commits

Author SHA1 Message Date
Pauli Virtanen 70ffbaed74 bluez5: fix node initialization to init all nodes
Now that we can have more than 4 nodes, so should init them all.
2024-01-09 08:07:33 +00:00
Pauli Virtanen f341dfed54 bluez5: lc3: prefer 7.5 ms frame duration
According to Intel people this is better for their hardware.

Link: https://github.com/bluez/bluez/issues/713
2024-01-09 08:07:33 +00:00
Jonas Holmberg 3b01205585 spa: Fix sign conversion in SPA_IS_ALIGNED
Fix the following compiler warning:
| In file included from /usr/include/spa-0.2/spa/utils/dict.h:14,
|                  from ../src/util_pipewire_objects.c:15:
| /usr/include/spa-0.2/spa/utils/defs.h: In function 'spa_ptr_inside_and_aligned':
| /usr/include/spa-0.2/spa/utils/defs.h:275:56: error: conversion to 'long unsigned int' from 'long int' may change the sign of the result [-Werror=sign-conversion]
|   275 | #define SPA_PTR_ALIGNMENT(p,align)      ((intptr_t)(p) & ((align)-1))
|       |                                                        ^
| /usr/include/spa-0.2/spa/utils/defs.h:276:42: note: in expansion of macro 'SPA_PTR_ALIGNMENT'
|   276 | #define SPA_IS_ALIGNED(p,align)         (SPA_PTR_ALIGNMENT(p,align) == 0)
|       |                                          ^~~~~~~~~~~~~~~~~
| /usr/include/spa-0.2/spa/utils/defs.h:308:13: note: in expansion of macro 'SPA_IS_ALIGNED'
|   308 |         if (SPA_IS_ALIGNED(p2, align)) {
|       |             ^~~~~~~~~~~~~~
2024-01-08 12:11:40 +01:00
Pauli Virtanen a154169942 bluez5: support multiple BAP transports per device
In multi-ASE configurations there can be multiple transports per device,
each corresponding to different channels.

Emit sink/source nodes for each BAP transport present.

Combine them into a single sink/source in the same way as we do for
device sets.
2024-01-08 10:09:13 +00:00
Pauli Virtanen d487dc0fc6 bluez5: bap: support ChannelAllocation parameter from BlueZ
For multi-ASE configurations, BlueZ does the channel allocation itself,
and passes us the result in the ChannelAllocation parameter.

If it is present, don't do the allocation ourselves but use that value
instead.
2024-01-08 10:09:13 +00:00
Pauli Virtanen caebeaa9b3 bluez5: lc3: workaround bad Supported_Max_Codec_Frames_Per_SDU
If Supported_Max_Codec_Frames_Per_SDU is less than what is required by
Supported_Audio_Channel_Counts, override its value assuming the device
actually supports at least that. Needed for Creative Zen Hybrid Pro.

Fix default value for channel count bitmask.
2024-01-08 10:09:13 +00:00
Pauli Virtanen b533b06b51 bluez5: backend-native: handle multiple commands in RFCOMM input
Do relaxed parsing of RFCOMM commands for AG & HF roles, allowing
multiple commands in same buffer.

Use same parser code for all HFP/HSP AG/HF. Parse input in relaxed way,
as some devices emit spurious \n
2024-01-06 15:42:20 +02:00
Wim Taymans a05a8eb8c6 spa: remove some references to unimplemented items
Fixes #3763
2024-01-05 10:07:58 +01:00
Wim Taymans e088dd2d2f journal: copy log level to chained logger
Make sure the log level on the chained logger is the same as ours.

Makes PIPEWIRE_DEBUG=3 make run print debug again.

This used to work because the log level was parsed and set before the
loggers were created and chained, and so they all got the same level.

Now that the level can be changed with metadata at runtime, we can't
really update all past loggers so let the journal logger copy the
level itself.
2024-01-04 13:57:26 +01:00
Pauli Virtanen 53ba3d0e4c spa: support: remove log pattern support
The log patterns are now handled by plugin host.
2024-01-04 10:02:55 +00:00
Pauli Virtanen 1197b581d9 spa: use only static log topics 2024-01-04 10:02:55 +00:00
Pauli Virtanen eaea03c26c spa: export log topic enumerations 2024-01-04 10:02:55 +00:00
Pauli Virtanen fc4dbcd033 spa: define symbols for log topic enumeration
Log topics are enumerated in an array of `struct spa_log_topic *`,
accessible via symbol `spa_log_topic_enum` pointing to a struct
spa_log_topic_enum in SPA shared libraries.

Add macros that use GCC section attribute to construct it with elf
magic.
2024-01-04 10:02:55 +00:00
Pauli Virtanen d099ceaff1 spa: spa_strbuf_init should null-terminate 2024-01-04 10:02:55 +00:00
Demi Marie Obenour 0227a30bcf spa: Bounds-check pointers before dereferencing them
Add a new overflow-safe function to check if region p2 of size s2 fits
completely in p1 of size s1 and, if it does, return the amount of bytes
in p1 that come after the end of p2.  Use this to bounds check the pod
iterators while ensuring that the pointer is bounds checked before being
dereferenced.

The spa_pod*_next() functions can still create an out-of-bounds pointer,
but this will not be dereferenced.  Fixing this requires either
additional complexity in these functions or forbidding POD structs,
objects, and sequences that have a length that is not a multiple of 8
bytes.

Fixes: 92ac9a355f ("spa: add spa_ptrinside")
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2023-12-26 16:05:24 +00:00
Barnabás Pőcze da7cf84f95 spa: utils: add `SPA_CONCAT()` macro 2023-12-26 16:03:29 +00:00
Mauro Carvalho Chehab d26916828d bluez5: update bluez-hardware.conf to ignore sbc-mq on Primark earbud
Primark True Wireless earbud doesn't support sbc-xq. Having it
enabled causes bluez to enter into a loop enabling/disabling
the device dozens of times per minute, making it unusable.
2023-12-26 16:02:22 +00:00
Wim Taymans 10d3c547d1 spa: add spa_ptrinside
Add a new overflow safe function to check if region p2 of size s2 fits
completely in p1 of size s1. Use this to bounds check the pod iterators.

Fixes #3727
2023-12-20 20:18:33 +01:00
Dmitry Sharshakov 5edd3f240b node-driver: open PHC as readonly
RW access is usually denied to a user unit. RO might be as well but it's more safe to make /dev/ptpX just user-readable
2023-12-20 09:35:22 +00:00
Dimitrios Katsaros 1d3013f0f9 ALSA: Remove alsa timer from IRQ scheduling
As part of the setup for IRQ based scheduling, a period event
was installed. Not only is a timer based polling unecessary for
IRQ scheduling, depending on the state of the system, the timer
could fire far enough from the IRQ, causing alsa wakeup events
with no data in the ring buffer. Pipewire would identify these
events as an "early wakeup", adding an extra quantum of time
to the next_time estimate, skewing the clock and causing issues
with apps that depend on precise timing.
2023-12-13 20:56:50 +01:00
Wim Taymans ad784ca5e6 audioadapter: improve state check
Update the started and ready state after we suspend/pause the node so
that we don't complain if scheduling happens between setting the fields
and actually stopping the follower.

Also only complain when the scheduling happens when the node is not
ready. It is possible that the node is scheduled before we manage to set
the started field.
2023-12-13 12:26:26 +01:00
Wim Taymans 27bed62e66 audioconvert: avoid bitfield data races
Move the driver and warned bits after the int field in the struct so
that they are placed in separate memory.

Otherwise, a write from the data thread might race with a write from the
main thread and leave the bits in the wrong state.
2023-12-13 12:15:11 +01:00
Wim Taymans 5980f6988a Revert "alsa: also use interpolated time as nsec in IRQ mode"
This reverts commit 49cdb468c2.

We should not do this, the nsec field should be relatable to the clock
monotonic time. If we use the estimated time, without actually using it
as a timer, we might end up with a wakeup time in the future compared to
the MONOTONIC clock time.

Instead, you can use the estimated current time simply by subtracting
the rate corrected duration from the next_nsec. This is really only
useful for some selected use cases (like in the JACK library).

This fixes some issues where in pro-audio mode, a client would try to
compare the current MONOTONIC time to nsec and find that it is in the
past.

This commit was done in an attempt to fix #3657 but it turned out the
real problem was something else.
2023-12-12 13:09:30 +01:00
Wim Taymans 283c215641 stream: make empty objects remove the PARAM
Make sure that NULL params don't cause -EINVAL but ignore them.

Don't add empty param objects. this makes it possible to clear all previous
params by setting an empty object.
2023-12-11 13:01:10 +01:00
Pauli Virtanen 7f2dd3531c bluez5: use only one input route
Don't have separate input route for A2DP and HFP, as it is generally not
necessary.

When in A2DP mode when there's also HFP possible, emit the input route
in SPA_PARAM_Route, even though there is no corresponding input node
emitted.

The host may then emit a loopback microphone node, and switch profiles
according to its status. Having the input route available at all times
allows to retain changes to volume settings made when there is no real
input node.
2023-12-09 14:05:50 +02:00
Kiran K 44df080482 bluez5: Add support for 32KHz for lc3 codec
Fixes: b69e089648 ("bluez5: Add support for 32KHz sampling frequency")
2023-12-08 19:15:50 +05:30
kirankrishnappa-intel b69e089648 bluez5: Add support for 32KHz sampling frequency 2023-12-08 08:34:09 +00:00
Pauli Virtanen 92f0815e4d bluez5: media-sink: keep one more buffer free
We delay the audio a bit to keep packet intervals equal, which keeps
some data in buffers.

In theory the calculation keeps one buffer free, but it doesn't
explicitly keep "extra" buffer space so in theory might flush too late
and next process() might not have free buffers.  However, as we encode
next packet right away this shouldn't really occur...

Try to keep one extra spare buffer free so that the flush time is
certainly early enough.
2023-12-05 18:37:36 +02:00
Pauli Virtanen a9ff282501 bluez5: drop queued data on node stop
Clear queued buffers when stopping consuming, to ensure that all buffers
are usable when we start again.

Do for A2DP as we already do for SCO.
2023-12-05 18:37:36 +02:00
Pauli Virtanen 81aaf0e204 bluez5: set io status properly when sink is not going to consume
When sink is not ready to consume buffers, set io and status to indicate
it already has data.
2023-12-05 18:37:36 +02:00
Wim Taymans 758805d65d alsa: fix rate matching in the sequencer
The alsa sequencer rate matching was not actually working correctly.
It would compare the previous queue time with the current time and
compare that to the quantum. This would include uncorrected errors from
jitter and would result in the timeouts being scaled in the wrong
direction forever.

Instead, calculate an ideal queue time and compare our current queue
time against that. We then use the correction to scale the timeout or
the next queue time prediction.

Also use the predicted time as the base time for the event timestamps.
this results in less jitter.

Fixes #3657
2023-12-05 15:12:27 +01:00
Wim Taymans c153f39720 alsa: reset dll when we reprogram the timers 2023-12-05 15:11:01 +01:00
Alper Nebi Yasak 7d2e824e97 acp: Disable active UCM profile before enabling Pro Audio profile
While switching to the Pro Audio profile from a UCM profile, the active
UCM profile is not disabled because the devices may need a UCM verb to
be set before being used. Then, switching away from the Pro profile to a
UCM profile is done by passing the Off profile as the old profile,
instead of the actually-still-enabled UCM profile.

This means the devices from the old UCM profile are kept enabled when we
try to switch to another UCM profile. And the devices to enable may be
conflicting with the still-enabled devices, which will cause failures.

To avoid this, we need to tell the UCM code to disable the profile when
switching away from it. Doing so disables UCM devices and the UCM verb.
Existing code sets the highest priority UCM verb before probing the Pro
profile, so manually enable the same one here as well, instead of
relying on unclean state from whatever profile that was last active.

Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak 9b9ce21b1d acp: Don't sync hardware volumes while UCM device is disabled
The hardware controls we track for volume and mute state can change as
part of enabling or disabling the UCM device. This then triggers a
re-sync of our state with the hardware controls, which can e.g. set our
volume to an unwanted value as the result of enabling the device, or set
a hardware control to a wrong value based on our volume while disabling
the device. So these UCM-triggered changes to enable/disable the device
will at best show up on user interfaces and cause confusion, but maybe
even will push the hardware into an unexpected state.

The volume and mute state we set from user interfaces only make sense
when the devices are enabled. They should not be kept in sync with
hardware for inactive UCM devices [1]. Skip the callbacks for reading
and changing volume and mute state if the UCM device is disabled. This
way, the volume/mute controls for sinks/sources are essentially detached
from the hardware controls until the UCM device is re-enabled.

[1] https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/772#note_1872757

Link: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/772
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak 0bdad320cd alsa-ucm: Replace port device UCM context assertion with an error
The pa_alsa_ucm_set_port() function is passed both a mapping context and
a device port, and both of these refer to their respective UCM device.
While switching over to having one port per mapping per UCM device, I
expected both of these to be the same device struct, so added an assert
checking so.

This assertion gets triggered when we have multiple UCM verbs declaring
the same UCM device name. The root cause here is that the ports' UCM
device references are set once while creating the ports for the card, so
they happen to be those of a specific verb and may not match those from
a different UCM verb's profiles' mappings.

Solving the root cause necessitates a larger refactor. What we actually
assume here is that name of the UCM device is same for both the port and
the UCM context, which ends up always true in practice. For now, replace
the assert with a check and error.

Link: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/802
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak 5b3dea6319 alsa-ucm: Check UCM verb before working with device status
Some versions of the ALSA libraries run into a segmentation fault when
we query a UCM device/modifier status without first setting a UCM verb.
It's not a reasonable thing to do anyway, so check for this case and
return an error. Also do the check in other helpers.

Link: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/801
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak a7e9f79cd0 alsa-ucm: Fix more instances of profile-verb conflation
The ucm_get_device_property() function adds to each UCM device's
playback_volumes (or capture_volumes) hash map an associated volume
mixer keyed with the UCM verb. These key-value pairs are then iterated
over in various places which assume the key is a profile name. This
assumption is no longer true since we can generate multiple profiles to
use conflicting devices.

A previous commit 45278904167f ("alsa-ucm: Stop conflating profile name
with UCM verb name") fixes some instances of this assumption, but misses
the relation explained above. Fix more instances of misleading
"profile"s where the UCM verb name is actually meant.

Link: 7005eafee3
Fixes: 57295beee1a6 ("alsa-ucm: Stop conflating profile name with UCM verb name")
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak d2046adcd1 alsa-ucm: Consider devices using the same PCM as incompatible
Although it's a valid UCM configuration to have multiple devices using
the same PlaybackPCM or CapturePCM, it's unclear how PulseAudio should
handle the cases where multiple of these devices are enabled. Some
options I can think of are:

- Merge all devices sharing the same PCM into the same mapping, open
  only one PCM substream for this mapping, and add 'combination ports'
  that enable combinations of the devices. This has been the case until
  recently, although the combination port logic was broken. A problem
  with this is that we can't independently control device volumes. We
  most likely cannot use hardware volumes either.

- Have one mapping for each device in the same profile, and open one PCM
  substream for each mapping. This is the current state, and it fails
  when there are fewer substreams than devices. Otherwise it works, but
  it's still confusing, as sound directed to a device-specific mapping
  might end up playing at multiple devices.

- Make multiple profiles each with combinations of upto-substream-count
  devices, and have one mapping/substream per device. This still causes
  the confusion mentioned above. And it's likely that the substream
  count will almost always be one, where this case degenerates into the
  last one.

- Have one mapping for each device in the same profile, but open only
  one PCM substream. I assume this is possible with software mixing, but
  it is still confusing like the above, and probably less performant.

- Generate multiple profiles each with one of the shared-PCM devices,
  again with one mapping/substream for that one device. The trade-off
  with this is that we can't use multiple of these devices at the same
  time. However, this doesn't have the output device confusion,
  combination port's volume problems, or the substream count limitation.

This patch takes a short-cut to achieve the last option, by considering
shared-PCM devices implicitly conflicting with each other.

Link: 45509ff9bc
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak cff0ef13c1 alsa-ucm: Disable old modifiers when switching profiles of same verb
While switching profiles of the same UCM verb, existing code first
disables devices that are only on the first profile to avoid conflicts.
However, it only disables devices, not modifiers. Even worse, modifiers
which have PlaybackPCM/CapturePCM are incorrectly treated as devices and
result in a segmentation fault.

Check what we are disabling, and call the appropriate disable function
for both devices and modifiers. Modifiers are disabled before devices,
because _dismod calls fail when the modifier's supported devices are
disabled.

Link: b74269016c
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak 905241c4a1 alsa-ucm: Add enable, disable, status helpers for modifiers
These are mostly the same as the device helpers added in c83b34516929
("alsa-ucm: Add enable, disable, status helpers for devices"), but for
modifiers instead.

Link: b382a00f8b
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak d99e0586b0 alsa-ucm: Create multiple profiles per verb for conflicting devices
Right now we try to add all UCM devices of a verb to a single profile.
But if some devices using different PCMs are configured as conflicting
with one another, we will only be able to utilize one of them, chosen
seemingly based on the order in the UCM config file.

This is not a problem with conflicting devices sharing a PCM, as they
are assigned to the same mapping and the ports mechanism only enables
one of them to be active at a time.

To utilize all devices in a UCM verb even when there are conflicting
devices using different PCMs, calculate subsets of devices which
can be simultaneously used and create a profile for each such set.

Link: 5dd411190d
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak 63a44038d2 alsa-ucm: Disable old devices when switching profiles of same verb
While switching profiles, it was enough to switch UCM verbs since that
disables all enabled UCM devices and every profile had a distinct verb.
However, switching to the current verb does not disable any devices.

To support multiple profiles for a verb we need to explicitly disable
the old profile's devices, since they might be conflicting with the new
profile's devices and will prevent them from being enabled. Compare both
profiles' mappings, and disable the devices not in the new mappings.

Link: e49da7bcd6
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak 6b46909083 alsa-ucm: Make mapping UCM contexts have only one modifier
After previous patches, we should be generating no combination ports, so
we don't need to store multiple modifiers per mapping. Simplify the code
based on this.

Link: 4821a0569e
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak bc42a617a4 alsa-ucm: Make mapping UCM contexts have only one device
After previous patches, we should be generating no combination ports, so
we don't need to store multiple devices per mapping. Simplify the code
based on this.

Link: 084d70a1e2
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
[Wim: Apply to acp add_profiles() and acp_card_set_profile()]
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak b8361cc568 alsa-ucm: Make ports store only one device
After previous patches, we should be generating no combination ports, so
we don't need to store multiple devices per port. Simplify the code
based on this.

Link: bf1708213b
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak 0fc80db7fe alsa-ucm: Remove combination port generation logic
A previous commit makes mapping names depend on the UCM device name.
Since UCM device names are unique, this means a mapping will at most
have one port and thus no combination ports can be generated.

This removes the dead code in the pa_alsa_ucm_add_ports_combination()
function, unrolls the remaining code in its helper functions that it
used, and renames it to pa_alsa_ucm_add_port() to signal that it no
longer generates combinations.

Link: 0789a8fb76
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
[Wim: Apply to acp add_profiles(), acp_card_set_profile(), compat.h]
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak 833c86d35b alsa-ucm: Make one input/output mapping per UCM device
PulseAudio combines UCM devices that have the same PlaybackPCM or
CapturePCM value into a single mapping with multiple ports. It also
creates ports in the same mapping for each valid combination of those
UCM devices.

Since mappings are the things we put in profiles, we can put in a
profile either all devices of a joint mapping or none of them. This
causes some complications with device conflicts. For example, a
different UCM device might be marked as conflicting with some (but not
all) of the devices in a joint mapping. In this case we can do one of
three things:

- Include all devices in one profile, and hope the conflicting device
  isn't chosen as the mapping's active port. We shouldn't do this as it
  puts conflicting devices in the same profile.

- Make one profile with the joint group, and one with the other device.
  This is somewhat acceptable as we have no conflicts, but we sacrifice
  some compatible combinations of devices.

- Do not group the devices into the same mapping, and make one profile
  for each compatible combination of devices. This appears to be the
  best option, one where we can always have the maximum number of
  working devices.

This patch chooses the third option and makes one input and/or output
mapping per UCM device, by using UCM device names instead of PCM device
strings in the mapping names.

Link: a50330a4a5
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak d93e96b666 alsa-ucm: Split out helpers for device set name, description, priority
Combination port logic calculates some useful properties for device
groups that we could reuse while generating multiple profiles to support
conflicting devices. Split them into their own functions.

Link: e8e2f4320c
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak 943967b826 alsa-ucm: Fix device conformance check
Right now this check is rejecting devices whose UCM config specifies
neither a conflicting device nor a supported device list, and accepting
devices which specify both. However, a device without neither list is
actually unrestricted, and a device with both lists is a configuration
error. Fix the check to accept the former.

Furthermore, this is missing another case where an already selected
device might have a supported devices list that doesn't have the
candidate device. Make this function also check against that, and also
make it accept devices already in the set.

Link: 5245117781
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00
Alper Nebi Yasak d7591edc25 alsa-ucm: Rewrite conformant device group generation with idxsets
The existing code meant to generate device groups for combination ports
is tightly coupled to port creation. Similar functionality would be
useful to generate nonconflicting device groups for multiple profiles as
well, so this tries to rewrite it into a more reusable state.

Several things (e.g devices, mapping contexts) use idxsets to store a
device selection. This also switches this conformance check and device
group generation to using idxsets to make it easier to work with those,
with the eventual aim to unify device group representations.

Also try to adjust users of these functions to use idxsets these will
need/return, without causing too much interference.

Link: 0f26022843
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
2023-12-04 15:34:48 +00:00