Not waiting for HFP when no HFP backend should be checked via
adapter_connectable_profiles in spa_bt_device_check_profiles where the
relevant logic is.
Cleanup by moving the checks there.
When starting the converter, calculate the initial size needed by
the resampler to fill one quantum.
This makes it possible to get the requested amount of samples before
the first process call is made.
Unknown transports visible in DBus usually belong to a different
sound server instance that is talking to BlueZ.
Explain this in the warning message that we log, so that people can more
easily understand why things are not working.
When freewheeling we will immediately schedule a new graph cycle when we
get a process call because the graph completed.
When the process call is not done, because of some xrun or
because some node was removed that causes the graph to fail completion,
The next cycle will happen after a timeout.
This timeout was calculated as the ideal wakeup time (after a quantum of
time) and would accumulate for each timeout. The result is that the
timeout ended up far in the future and would stall the freewheel driver
for a long time.
Fix this by always setting the next timeout to wakeup time + freewheel.timeout
seconds. Also add a config property for the timeout (10 seconds, like
jack2 by default).
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)) {
| | ^~~~~~~~~~~~~~
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.
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.
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.
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
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.
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.
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>
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.
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
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.
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.
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.
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.
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.
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.
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.
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
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>
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>