If you use multiple BT adapters, it's annoying that PW tries to
autoconnect to the device via all available adapters, and you end up
with multiple connections to the same device (which does not necessarily
work).
Avoid this by autoconnecting with only the first adapter that sees the
device.
We don't currently implement encoding for the duplex channel
for these codecs, so they are not fully functional as A2DP sinks,
and their main use is anyway with headphones.
Also, the number of endpoints in BlueZ appears to be limited, and
appears to be counted across all adapters. Unclear whether this comes
from AVDTP limitation, but currently plugging in a second BT adapter
causes the second media application registration to fail. This change
reduces the number of endpoints enough so that registration succeeds for
two adapters.
We need to manage our own flags based on the direction of the follower.
We also need to make sure we only clear the NEED_CONFIGURE flag
after we are actually configured, not just when we configured our
internal converter.
See #1548
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.
Add Format subtype and codec property.
Add codecs to include in the format codec property.
Add property to configure elements with supported codecs.
Add type info.
When in passthrough mode, use the position io to update the
io_rate_match fields for the follower. This makes it possible for the
follower to also provide the right amount of data when the converter
is not selected in passthrough.
Add an option to configure the converter in None port config where it
removes all the ports. We can use this when removing the converter to
make sure all it's ports are removed.
When we remove the converter, make sure we expose the follower ports
directly so we can use them for passthrough.
There doesn't seem to be a way to control the A2DP duplex microphone
HW volume gain, and devices sometimes have very low mic volumes.
Work around this by boosting the software volume scale by +20 dB. If it
causes clipping, the user can just reduce the volume to bring SW gain
below 1.0.
aptX-LL sink devices may send back mSBC encoded data corresponding to
microphone input. It appears to be enabled when the bidirectional link
is set in the caps, and the device also supports this.
Implement mSBC decoding in the duplex channel.
Tested to be working on Avantree Aria Pro.
For unknown reason the BT socket when working with A2DP "duplex" stream,
sometimes stops waking up poll when data arrives. Regardless, recv() can
read data packets from it.
To work around this, when A2DP source is in duplex mode, instead of
polling on data, we poll on a timer.
Some non-standard A2DP codecs (FastStream/aptX-LL) have "voice duplex
channel" that can be used to provide an A2DP duplex mode.
Add support for duplex channels, accounting for the fact that the two
directions may be encoded with different actual codecs.
This pushes the latency to 256 samples, which still seems to work
Latency of 128 seems to be too small. (NB. the number of input samples
is also the size of packets sent in bytes)
Since pipewire clients usually use powers of two, this may be the
smallest value that makes sense.
Support the low-latency variant of the aptx codec.
The magic mostly seems to be on the device side, since the stream is the
same as standard aptx, but latency is smaller even if stream/packet
sizes are the same.
Sound output latency is noticeably less than with the standard aptx.
Tested on Sennheiser HD 250 / Avantree Aria Pro.
The codec in principle also supports bidirectional duplex streams,
but that is not implemented here.
The codec IDs are user-visible properties.
Some codecs can have multiple endpoints (e.g. different caps struct, or
multiple possible vendor ids), so this detail should not leak to the
user.
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.
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.