Disable flush polling when we don't have data ready to write to the
socket (or socket send failed). This avoids entering into a poll busy
loop, which may result to rtkit killing the process.
Enable SBC-XQ by default, and move it at the end of the codecs list, so
that bluez does not connect to it automatically except when it is the
codec used previously.
When the codec is disabled by quirks, it won't appear in the codecs
list, and so can't be selected by user (and so won't be connected
automatically).
However, since SelectConfiguration does not carry information which
device is in question, we cannot prevent BlueZ connecting to the codec
even if it's disabled for a specific device. If the "impossible" occurs
regardless, we won't reject the connection and the profile will be shown
as the generic "A2DP" one. If the sound is garbled, the user can select
some other profile that works.
HF indicator 2 (see [assigned-numbers], Hands-Free Profile) is able to
report battery percentage at 1% intervals (in range [0, 100]), contrary
to the `+XAPL` `+IPHONEACCEV` extension which only supports 10%
increments. This does not guarantee increased granularity however, as
peers may still be limited to imprecise battery measurements internally
or round to coarser percentages.
Supporting both additionally broadens the range of devices for which PW
can report its battery level.
[assigned-numbers]:
https://www.bluetooth.com/specifications/assigned-numbers/
We need to do this or else newly plugged devices might not load.
It does not seem to harm UCM config on my machine, so this reverts
3d372424cc
See #1478
When we store the real_volume we get a hardware_volume as stored
in the mixer and a residual software_volume.
When we read the volume from the card, we need to compare this against
the hardware_volume we stored to check if something changed, not
against the real_volume that also contains the leftover software_volume.
spa_strstartswith() is more immediately understandable.
Coccinelle spatch file:
@@
expression E1, E2;
@@
- strstr(E1, E2) != E1
+ !spa_strstartswith(E1, E2)
@@
expression E1, E2;
@@
- strstr(E1, E2) == E1
+ spa_strstartswith(E1, E2)
Applied to the tree except for alsa/acp/compat.h because it looks like
that header is still mostly as-is from PA.
libfreeaptx is a fork of libopenaptx prior to the dubious licensing
situation was introduced to the library.
As it's fully API compatible, let's use that instead for those who
want to use aptX support.
The library source is available at https://github.com/iamthehorker/libfreeaptx
The ringbuffer can't be written to from multiple threads.
When both the main loop and data thread do _invoke, they both write to
the ringbuffer and cause it to be corrupted because the ringbuffer is
not multi-writer safe.
Doing invoke from the thread itself is usually done to flush things out
so we really only need to flush the ringbuffer and call the callback.
See #1451
To fix build warning about a variable being unused in LibCamera::stop():
[1/2] Compiling C++ object spa/plugins/libcamera/libspa-libcamera.so.p/libcamera_wrapper.cpp.o
../spa/plugins/libcamera/libcamera_wrapper.cpp: In member function ‘void LibCamera::stop()’:
../spa/plugins/libcamera/libcamera_wrapper.cpp:531:58: warning: unused variable ‘buffer’ [-Wunused-variable]
531 | for (const std::unique_ptr<FrameBuffer> &buffer : this->allocator_->buffers(stream)) {
| ^~~~~~
The SPA plugin is including a <libcamera/buffer.h> header file, but this
got renamed to <libcamera/framebuffer.h> to match the defined class name:
../spa/plugins/libcamera/libcamera_wrapper.cpp:52:10: fatal error: libcamera/buffer.h: No such file or directory
52 | #include <libcamera/buffer.h>
| ^~~~~~~~~~~~~~~~~~~~
Fixes#1435
If socket write results to EAGAIN/EWOULDBLOCK or rx data starts late,
spa_bt_sco_io_write may return 0, and we should give up and skip ahead
(and not loop in RT thread with very small timeout).
First calculate the size of the aligned payload and then check if
we can fit this aligned payload in the remaining space in the
ringbuffer.
Otherwise we might be able to fit the item + payload in the remaining
space but then place the alignment bytes at the begginning, which would
break alignment of the next invoke_item struct.
Also check if there is enough space to write the payload bytes.
We check if there is enough space for the invoke_item structure first.
Then we calculate how much bytes we need to use for the payload but we
fail to check if we can actually write that much data, risking
overwriting existing data from the ringbuffer and causing a crash later
when we try to jump to invalid memory.
Add some more comments.
The kernel-provided SCO write MTU is currently never the correct packet
size for writing, so don't try to use it. Some adapter firmware (eg.
BCM20702A0 0b05:17cb) appears in practice sensitive to the alignment of
the msbc frames, and writes with wrong packet size break things but only
on certain headsets. For other adapters, this doesn't appear to matter.
This is a bitfield, but it's unclear what it achieves since this is the
only member of a bitfield, so it may be more efficient to just make it a
bool.
Fixes a LGTM warning:
Bit field started of type int should have explicitly unsigned integral, explicitly signed integral, or enumeration type.
`sizes` members participate in multiplication and subsequent assignment
into port->bpf, which has size_t. So LGTM rightfully complains, there's
a chance the multiplication will overflow before the assignment happens.
Should have no influence on performance since 64 bit multiplication is
as fast, and since the struct is constified, a wise compiler should make
sure it doesn't take excess space either.
Fixes LGTM warning:
Multiplication result may overflow 'unsigned int' before it is converted to 'size_t'.
That was found by GCC fanalyze pass. Fixes warning:
../spa/plugins/audioconvert/resample-native.c: In function ‘resample_native_init’:
../spa/plugins/audioconvert/resample-native.c:385:9: warning: dereference of NULL ‘0B’ [CWE-476] [-Wanalyzer-null-dereference]
385 | spa_log_debug(r->log, "native %p: q:%d in:%d out:%d n_taps:%d n_phases:%d features:%08x:%08x",
Check if we are driving or following and only start the timers when we
are the driver of the graph.
Ready events from non-drivers are not really a problem because they are
ignored. They only cause unnecessary wakeups in the graph.