SBC codec decrements bitpool value by fixed amount each time it is asked to
reduce output bitrate. This results in reduced audio quality with SBC codec.
Implement increase_encoder_bitrate for SBC codec by adding 1 to bitpool value
each time encoder bitrate needs to be increased to restore SBC audio quality.
While at it, remove bitpool decrement limit to use connection agreed value
instead as we will be able to restore quality later.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/474>
Bluetooth thread may ask encoder to reduce bitrate if writing is not keeping up
with inputs or writing to bluetooth socket takes too much time.
Assuming conditions leading to reduced bitrate are intermittent, allow periodic
attempts to increase encoder bitrate, by default at most twice per second.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/481>
Similar to the situation/comment in `endpoint_release` BlueZ does not
request any reply to `ClearConfiguration()` either; sending one results
in the same "0 matched rules" warning from dbus-daemon:
dbus-daemon[1309]: [system] Rejected send message, 0 matched rules; type="method_return", sender=":1.71" (uid=1000 pid=87548 comm="../build/src/daemon/pulseaudio -vvvv -n -F ../buil") interface="(unset)" member="(unset)" error name="(unset)" requested_reply="0" destination=":1.3" (uid=0 pid=1308 comm="/usr/lib/bluetooth/bluetoothd -d ")
Solve this by only creating a return message when an (othwise empty)
reply is solicited for, just like in `endpoint_release`.
Unfortunately we also have to make sure to not send any error back if no
reply is requested, but fortunately an argument parsing error here is
extremely unlikely.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/472>
We move the codec specific bits to their own respective files and now
make the codec specific initialisation use a GstBin, which the generic
GStreamer module now uses in the pipeline.
It is job of the codec specific function to add elements in the GstBin
and link the added elements in the bin. It should also set up the ghost
pads as a GstBin has no pads of it's own and without which the bin
cannot be linked to the appsrc/appsink.
Also, we now only initialise either the encoding or the decoding
pipeline and not both. The codec init API already gets passed the
for_encoding flag. We pass and use the same to codec specific init
functions.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/440>
As we now support codecs other than SBC, we might have codec which does
not have an encode or a decode capability. Specifically, in the case of
LDAC there isn't a known decoder implementation available. For such a
case, we should not register the corresponding endpoint.
In case of LDAC, as decoding cannot be supported, we should not register
a sink endpoint or vice versa in the other scenario.
To do this, we check if encode_buffer or decode_buffer entry for a codec
has been set in pa_a2dp_codec and accordingly prevent or allow it's
registration.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/440>
When it comes to codecs provided via GStreamer, we register all codecs
if GStreamer option is enabled for bluez5 via meson. However, the
GStreamer plugin required for the codec might not be present on the
system. This results in the codec being available for registration with
the bluez stack or selection by the user, but, trying to use the said
codec then fails.
To prevent the above, we now use the can_be_supported codec API to check
if the codec is usable and if not, we do not register the said codec and
also prevent users from switching to it.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/440>
This API internally checks if a requested codec can be supported on the
system. This is especially required for codecs supported via GStreamer
where the availability of a plugin decides if the said codec can be
supported.
This will be used to prevent registration of a codec which the remote
endpoint device might be able to support, but, PulseAudio can't as the
codec is not available on the system due to the absence of a plugin.
We can also prevent listing or switching to an unavailable codec.
Note that the codec negotiation happens with the bluez stack even before
a device is connected. Because of this, we need to make sure that gst_init
is called before checking for the availability of a plugin. Since
module-bluez5-device gets loaded only after a connection to the device
has been established, doing the gst_init in that or one of the bluetooth
modules is not feasible.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/440>
For example, using the following on the command line will return the
current codec for a bluetooth device
pacmd send-message /card/bluez_card.4C_BC_98_80_01_9B/bluez get-codec
where 4C_BC_98_80_01_9B is the bluetooth device.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/440>
This exposes the currently active codec on the source or sink via the
proplist and can be seen in output of pacmd list-sinks/list-sources.
Also set it on the card. In case of a bi-directional codec, the codec
for the sink and source could be different. For example, for aptX-LL,
the codec name on card, sink and source would be aptx-ll, aptx and sbc
respectively.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/440>
For example, using the following on the command line will return the
list of possible codecs for a bluetooth device
pacmd send-message /card/bluez_card.4C_BC_98_80_01_9B/bluez list-codecs
where 4C_BC_98_80_01_9B is the bluetooth device.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/440>
This adds a generic gstreamer codec module based on which other
bluetooth codecs viz. aptX, aptX-HD, LDAC and AAC can be supported.
The GStreamer codec plugins used here themselves depend on the native
codec implementation.
aptX/aptX-HD -> libopenaptx
LDAC -> libldac
AAC -> Fraunhofer FDK AAC
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/440>
This uses the messaging API to initiate a codec switch.
While a particular codec might be applicable only for a particular
profile, for eg. aptX can only be applicable for A2DP sink or source
and not for let's say HSP, the codec switching logic has not been
tied to the logic for switching profiles.
Codec can be switched by running the following on the command line.
pacmd send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez switch-codec{"ldac_hq"}
pacmd send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez switch-codec {"ldac_mq"}
pacmd send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez switch-codec {"ldac_sq"}
pacmd send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez switch-codec {"aptx_hd"}
pacmd send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez switch-codec {"aptx"}
pacmd send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez switch-codec {"sbc"}
Codec name passed above is matched against pa_a2dp_codec->name. Note that
the match is case sensitive. XX_XX_XX_XX_XX_XX needs to be substituted with
the actual bluetooth device id.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/440>
Instead of letting a codec with higher index have higher priority,
just use a lower index for high priority. This allows the for loop
iterating over the codecs to be written in a straightforward manner
and not have to iterate from the end. FWIW Pipewire does the same.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/440>
If the current active profile is off, it has no sinks and sources, and
if users plug a headset to the audio port, the profile including this
audio port becomes available and should be selected as active profile.
But with the current design, the profile_good_for_output() will return
false because the sources in off profile and target profile doesn't
match.
For example:
(Before users plug headset)
Profiles:
HiFi (Speaker): Default (sinks: 1, sources: 1, priority: 8100, available: no)
HiFi (Headphones): Default (sinks: 1, sources: 1, priority: 8200, available: no)
off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: off
(After users plug headset)
Profiles:
HiFi (Speaker): Default (sinks: 1, sources: 1, priority: 8100, available: yes)
HiFi (Headphones): Default (sinks: 1, sources: 1, priority: 8200, available: yes)
off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: off
Signed-off-by: Hui Wang <hui.wang@canonical.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/354>
Volume scaling in dB mode is broken if max dB is negative.
I have a Nobsound USB amplifier (1908:2220) that reports a dB range
of -127.07 dB to -128 dB in Alsa.
While this is likely a driver/device bug, in my naive imagination
userspace wouldn't bother too much with the absolute values and just set
out_dB(percent) = min_dB + (max_dB - min_dB) * percent
However, this is not what PulseAudio is doing, instead max_dB is used
as base_volume with which the desired software volume is multiplied
while min_dB does not seem to be taken into account.
The result is that with this device only a tiny portion of the volume
slider is usable.
Setting it to 97% already reaches min_dB which effectively turns any
(software) audio knob to an on/off switch.
To work around this, simply set the has_dB flag to false if max_dB is
negative.
This falls back to using raw Alsa values (ranging from 0 - 255), now
the settings in pavucontrol perfectly mirror those in alsamixer.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/447>
After applying the commit 0d50e787 ("alsa-card: improve the profile
availability logic"), we met an new issue. when system selects the
initial profile, the profile off is selected instead of a profile with
a valid output device on it. That is the issue we met:
Profiles:
HiFi: Default (sinks: 2, sources: 2, priority: 8000, available: no)
off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: off
Ports:
[Out] Headphones: Headphones (priority: 300, latency offset: 0 usec, not available)
Part of profile(s): HiFi
[Out] Speaker: Speaker (priority: 100, latency offset: 0 usec)
Part of profile(s): HiFi
...
I know the commit 0d50e787 really fixed something, but we still need
to fix the new issue, to do so, this patch introduces a priority bonus
for alsa profiles and separate the alsa profiles to 3 groups:
group a (will be granted priority bonus dynamically):
a profile has only output ports and at least one port is not unavailable
a profile has only input ports and at least one port is not unavailable
a profile has both input and output ports, and at least one output and
one input ports are not unavailable
group b (will be marked unavailable)
a profile has only output ports and all ports are unavailable
a profile has only input ports and all ports are unavailable
a profile has both output and input ports, and all ports are unavailable
group c
the rest profiles, their priority and availability is not changed.
With this change, the profile HiFi will become avaialbe:yes, and will
not be granted priority bonus if no input port is plugged.
The priority bonus provides a higher priority base to profiles, this
guarantees this patch doesn't break the fix of 0d50e787.
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/927
Signed-off-by: Hui Wang <hui.wang@canonical.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/355>
When an alsa source with fixed latency is used, the actual latency of the source
will only be one fragment size. This is not taken into account when the required
sink latency is calculated.
This patch fixes the issue.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/451>
While module-ladspa-sink is still being loaded and before pa_sink_put() is
called there may be an attempt to reconfigure master sink when avoid-resampling
is true. This breaks attempting to suspend ladspa-sink which is still in INIT
state.
Fix this by skipping pa_sink_suspend if PA_SINK_IS_LINKED is false.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/445>
This is seen at least on HP EliteDesk 800 DM and HP EliteDesk 800 SFF.
This is used by the analog-output-headphones-2 path, but all other paths
on the same sink need to handle the element too. The existing
configuration is inconsistent between files regarding whether headphone
outputs should be muted or not when not using them. I chose to be
consistent within files, which means that Headphone,1 handling is
inconsistent between files in the same way that the existing Headphone
and Headphone2 handling is. (My opinion is that unused paths should be
always muted, but I didn't want to do that policy change in this patch.)
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/272>
Previously both paths had description "Headphones", which I assume can
cause confusion with users who see two ports with identical names. I
don't have this kind of hardware myself nor have I heard complaints from
users, this is just something I noticed while reading the configuration
files.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/272>
On some Dell AIO machines, there is no internal mic, only a multi
function audio jack, so the only input devices are headphone-mic and
headset-mic, and they share the Jack with headphone.
When there is no headset plugged in that Jack, the headphone-mic
and headset-mic are off. And since there is no available port under
the analog input source, this source is unlinked (if there is
internal mic, the source will not be unlinked). so the only pa-source
left in the PA is analog-stereo-monitor.
After the headset is plugged, we need to let switch_to_port() handle
headset-mic and headphone-mic conditionally, this will guarantee the
source will be created if it is unlinked before plugging, and then the
input profile could be selected correctly.
Signed-off-by: Hui Wang <hui.wang@canonical.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/390>
We have at least one USB hardware which supports the 8
channels in one mixer element:
https://github.com/alsa-project/alsa-ucm-conf/pull/25
POSITION_MASK_CHANNELS define was added for the future extensions.
The override_map variable was changed from bool to mask (unsigned int).
The channel map override settings is handled for channels up to eight now.
Also added missing override-map.3 .. override-map.8 to the configuration
parser array.
The driver channel position was added to the override mask arguments
(syntax is driver:pulseaudio like left:all-left). If ommited, the ALSA's
channel positions are guessed by index.
Link: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/292
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/389>
Use safe values for the min_dB and max_dB fields when the position mask
is unset to avoid breakage for the upper levels.
If the range is incorrect, the volume range shown in pavucontrol shows
strange values.
(Thanks to Wim Taymans for the idea.)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/389>