I have a CEL-TEC F5A headset. The spec says:
Bluetooth 4.0, profiles: Headset, Hands free, A2DP, AVRCP/HSP/HFP
It plays nicely with High Fidelity Playback (A2DP sink) profile.
When I want to switch audio input to the headset's microphone, the output profile automatically changes to Headset Head Unit (HFS/HFP) and the quality is terrible - like 8bit sound or something. When I switch it back to A2DP, the input is back to desktop mic.
I've read few of other questions and seems A2DP is expected not to support input, right? But the HFP part in HFS/HFP is High Fidelity Playback I guess? That sounds like it could work as a headset and still not sound like 1950's phone.
How could I simplify switching between the profiles so that it is HFS/HFP when I talk and A2DP when I listen? E.g. as a push-to-talk.
Ubuntu 17.10, no sound customization IIRC, everything latest.
https://www.kabelmanie.cz/cel-tec-f5a-active-noise-bluetooth-stereo-sluchatka-s-mikrofonem/
My output:
$ pactl list cards
Card #0
Name: alsa_card.pci-0000_00_03.0
...
Card #4
Name: bluez_card.00_19_5D_25_6F_6C
Driver: module-bluez5-device.c
Owner Module: 30
Properties:
device.description = "F5A"
device.string = "00:19:5D:25:6F:6C"
device.api = "bluez"
device.class = "sound"
device.bus = "bluetooth"
device.form_factor = "headset"
bluez.path = "/org/bluez/hci0/dev_00_19_5D_25_6F_6C"
bluez.class = "0x240404"
bluez.alias = "F5A"
device.icon_name = "audio-headset-bluetooth"
device.intended_roles = "phone"
Profiles:
a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 10, available: yes)
headset_head_unit: Headset Head Unit (HSP/HFP) (sinks: 1, sources: 1, priority: 20, available: yes)
off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: a2dp_sink
Ports:
headset-output: Headset (priority: 0, latency offset: 0 usec, available)
Part of profile(s): a2dp_sink, headset_head_unit
headset-input: Headset (priority: 0, latency offset: 0 usec)
Part of profile(s): headset_head_unit
The problem here is not that the microphone does not work, but rather that the audio quality worsens when it is activated.
Ondra, there is a very long pulse audio merge request discussion that contains most of the information.
tl;dr; to get things working pulse audio, bluez and kernel need to be updated (not trivially). As well a separate daemon
hsphfpd
is necessary.Kernel updates are not progressing and user input to maintainers would be helpful in pushing things forward. Think about providing such. See here.
Without the kernel patches, using headphones' mic leads to terrible audio quality (HSP/HFP mode of operation).
But there is chance that only Pulse patches (and support from your headphones) can enable A2DP bi-directional audio which should be alright for most purposes.
And that patch is progressing well at the moment. More feedback on it shouldn't hurt.
Update: THings in above mentioned pull request escalated very quickly and seems like PulseAudio may never implement proper bluetooth support. Lets hope for Pipewire which already has some patches.
I was about to return the headset and wait for Bluetooth 5.0 headset, but then realized, that's the best functionality I can get with my BT 4.0 laptop. So I kept them.
Still, listening to a French guy over 16 bit 8000 Hz audio wasn't really the right way to have a meeting. For few days, I was switching between the two modes using Ubuntu's sound settings dialog, but that's really, really annoying as you can imagine.
So I wrote this script leveraging
pacmd
which toggles between the 2 modes:It is not polished, has some dead code, and I use my own phones ID's, but it may be an inspiration for your own script. Latest version here.
Hope this helps someone :)
Based on this article I fear that Bluetooth won't give me the pleasure of hearing a quality sound and speak over the headset at the same time. :/
Not accepting this answer though, I am still hoping someone will come up with some way to do so.
I suggest the use of a simple script for a toggle button https://gist.github.com/weslleyspereira/e8feeb9f1b7008ae1ffad2777e39d0dd together with the one from Ondra Žižka's :
The feature you are looking for is available in PipeWire (a replacement for PulseAudio) when using
pipewire-media-session
orwireplumber
as a session manager. The first one is the default and enabling automatic profile switching is achieved by settingin
~/.config/pipewire/media-session.d/bluez-monitor.conf
After restarting
pipewire-media-session
, the A2DP profile is used by default. Only when a sound input is detected, Pipewire will switch to HSP/HFP and back to A2DP when it ends.This is explained in the Arch Wiki as well as this blog article.
I came here with the same problem with my Poly Voyager Focus UC. Too bad the support in the bluetooth stack isn't there (yet). The Voyager Focus also comes with a usb dongle which can be used to connect it. With the dongle Linux sees the headset as a sound card, so the Linux BT stack is not involved, and bidirectional sound quality is good. The only minor problem is that if I switch the headset off Linux doesn't see that and doesn't switch audio playback back to the speakers, so I need to select the sound output device manually.
Elsewhere on the interwebs I read people also had succes with such a workaround by using a third party USB Bluetooth audio adapter and connecting their headset to that instead of the system bluetooth. Based on what I could find, for that to work both the headset and the bluetooth audio adapter need to both support "wideband speech" in their HSP (Headset Profile), which is optional. Wideband speech is only 16 kHz / 16 bit, but that's still a big improvement over the 8 kHz standard HSP channel. The Linux bluetooth stack does not yet support wideband audio. What I don't know is if my Voyager Focus dongle uses standard bluetooth with wideband speech, or if it uses some proprietary wireless protocol extension.
Many bluetooth headsets show up as 2 separate devices, one as headphone / speaker (no mic) and one as headset (with mic). Disabling the headset device will force the use of A2DP. This could also be scripted maybe in an easier way than the other examples in this thread.