I just got my new Sony WH-1000XM3 headset and would like to know how to properly connect it to my Ubuntu machine. It's an ANC headphone with integrated microphones - primarily to record ambience noise but they are also able to be used as an input. My machine of primary interest runs 18.04 LTS (work laptop) but I also run 20.04 LTS / 20.10 on my private computers.
When I first connected the headset to my computer, I was shocked how bad the sound quality was, but then I realized I had "Headset Head Unit (HSP/HFP)" selected under sound quality. I was able to choose "High Fidelity Playback (A2DP)" without problems and the output sound got better. The problem is: Whenever I enable "Headset - LE_WH-1000XM3" as input device over the laptop's internal microphone, the output jumps back to "Headset Head Unit (HSP/HFP)". Hoping this would help me, I installed LDAC support from a PPA: https://github.com/EHfive/pulseaudio-modules-bt/wiki/Packages#ppaeh5pulseaudio-a2dp but the problem of course persisted. Somewhere along the road I read that LDAC decoders (contrary to the encoder I installed) are not even freely available (source: https://habr.com/en/post/456182/) so trying to send microphone signals over LDAC was doomed to failure from the start.
What are my options to get acceptable microphone input and retaining good audio output (both better then HSP/HFP) from my newly bought headset? Somehow my Android device (LineageOS 15.1 - Oreo 8.1) does manage to keep decent in- and output quality and I want to have the same experience on my Linux machines.
Android stats according to Developer options:
Bluetooth AVRCP Version: AVRCP 1.4
Bluetooth Audio Codec: LDAC
Bluetooth Audio Sample Rate: 96 kHz
Bluetooth Audio Bits Per Sample: 32 bits/sample
Bluetooth Audio Channel Mode: Stereo
Bluetooth Audio LDAC Codec: Best Effort (Adaptive Bit Rate)
investigating a "Bluetooth HCI snoop log" (https://btcodecs.valdikss.org.ru/) yielded:
Connection:
XX:XX:XX:XX:XX:XX (Redmi Note 4) → YY:YY:YY:YY:YY:YY (WH-1000XM3)
Supported codecs:
Audio SBC (44100 48000 | Mono DualChannel Stereo JointStereo | block: 4 8 12 16 | subbands: 4 8 | allocation: SNR Loudness | bitpool: 2..53)
Audio non-A2DP (LDAC - 44100 48000 88200 96000, Mono DualChannel Stereo)
Audio non-A2DP (aptX HD - 44100 48000, Stereo)
Audio non-A2DP (aptX - 44100 48000, Stereo)
Audio MPEG-2,4 AAC
Used for audio:
Audio non-A2DP (LDAC - 96000, Stereo)
which is in accordance with Sony's information: https://helpguide.sony.net/mdr/wh1000xm3/v1/en/contents/TP0001703175.html
What can I do get this headset to work properly on Linux?
If I can't do anything, why?
If I can't do anything with this particular device, what properties do I need to look for if I want to buy a good wireless headset for Linux, and how do I find such a "Linux"-headset?
Are Bluetooth headsets just not a thing for Linux yet, and I need to stick to cable-bound headsets if I want a good experience?
I am aware of question How to keep the audio profile at A2DP while using a mic with Bluetooth headset? (Push-to-talk) and WIP: Bluetooth HSP and HFP profiles implementation via hsphpfd daemon but I think my question is not identical.
edit: add pactl
output
user@pc:~$ pactl list sinks
Sink #0
[...]
Description: Built-in Audio Analog Stereo
[...]
Sink #25
State: RUNNING
Name: bluez_sink.ZZ_ZZ_ZZ_ZZ_ZZ_ZZ.a2dp_sink
Description: LE_WH-1000XM3
Driver: module-bluez5-device.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Owner Module: 33
Mute: no
Volume: front-left: 34080 / 52% / -17,04 dB, front-right: 34080 / 52% / -17,04 dB
balance 0,00
Base Volume: 65536 / 100% / 0,00 dB
Monitor Source: bluez_sink.ZZ_ZZ_ZZ_ZZ_ZZ_ZZ.a2dp_sink.monitor
Latency: 36416 usec, configured 30804 usec
Flags: HARDWARE DECIBEL_VOLUME LATENCY
Properties:
bluetooth.protocol = "a2dp_sink"
bluetooth.a2dp_codec = "LDAC"
device.description = "LE_WH-1000XM3"
device.string = "ZZ_ZZ_ZZ_ZZ_ZZ_ZZ"
device.api = "bluez"
device.class = "sound"
device.bus = "bluetooth"
device.form_factor = "headset"
bluez.path = "/org/bluez/hci0/dev_ZZ_ZZ_ZZ_ZZ_ZZ_ZZ"
bluez.class = "0x240404"
bluez.alias = "LE_WH-1000XM3"
device.icon_name = "audio-headset-bluetooth"
device.intended_roles = "phone"
Ports:
headset-output: Headset (priority: 0, available)
Active Port: headset-output
Formats:
pcm
user@pc:~$ pactl list sources
Source #0
[...]
Description: Monitor of Built-in Audio Analog Stereo
[...]
Source #1
[...]
Description: Built-in Audio Analog Stereo
[...]
Source #37
State: IDLE
Name: bluez_sink.ZZ_ZZ_ZZ_ZZ_ZZ_ZZ.a2dp_sink.monitor
Description: Monitor of LE_WH-1000XM3
Driver: module-bluez5-device.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Owner Module: 33
Mute: no
Volume: front-left: 65536 / 100% / 0,00 dB, front-right: 65536 / 100% / 0,00 dB
balance 0,00
Base Volume: 65536 / 100% / 0,00 dB
Monitor of Sink: bluez_sink.ZZ_ZZ_ZZ_ZZ_ZZ_ZZ.a2dp_sink
Latency: 0 usec, configured 30804 usec
Flags: DECIBEL_VOLUME LATENCY
Properties:
device.description = "Monitor of LE_WH-1000XM3"
device.class = "monitor"
device.string = "ZZ_ZZ_ZZ_ZZ_ZZ_ZZ"
device.api = "bluez"
device.bus = "bluetooth"
device.form_factor = "headset"
bluez.path = "/org/bluez/hci0/dev_ZZ_ZZ_ZZ_ZZ_ZZ_ZZ_DA"
bluez.class = "0x240404"
bluez.alias = "LE_WH-1000XM3"
device.icon_name = "audio-headset-bluetooth"
device.intended_roles = "phone"
Formats:
pcm