If you’re shopping for the best noise-cancelling headphones for programmers and your laptop runs Linux, the codec list on the box matters more than the review score. The same headphones can stream LDAC on one distro and plain SBC on another, because Fedora and Ubuntu package PipeWire’s codecs differently. You want a pair that cancels open-plan noise, lasts a workday and sounds as good on Linux as on your phone.
Below are four picks for coding, calls and focus work, each matched to what Linux can stream to it. The headphones were not paired in our lab, so every spec comes from the maker’s page, the live Amazon listing and an independent review. The Linux side was tested: I checked the codec plugins in October 2026 on Fedora 45 (PipeWire 1.6.9, BlueZ 5.87) and Ubuntu 26.04.1 LTS (PipeWire 1.6.2, BlueZ 5.85), so the codec plugins each distro ships are tested and the codec a headset lands on is inferred.
Pick your headphones by how you work
Start from your desk, not the spec sheet. A developer who lives in video calls needs something different from one who wants four hours of silence. Find the line that sounds like your day:
- You want the best sound Linux can stream wirelessly on both Fedora and Ubuntu: the Sony WH-1000XM6 is the best overall, because LDAC works on both.
- You’d rather plug in a cable than think about codecs: the Bose QuietComfort Ultra Headphones (2nd Gen) take digital audio over USB-C.
- You forget to charge things: the Sennheiser Momentum 4 Wireless is rated for 60 hours with noise cancelling on.
- You want LDAC without paying flagship prices: the Soundcore Space One Pro is the budget pick.
If two lines fit you, let your distro break the tie. A stock Fedora install has AAC but no aptX, and a stock Ubuntu install has aptX but needs one extra package for AAC, so a headset that leans on one of those codecs can sound different depending on which machine it’s paired with. The comparison table below spells that out per model.
See how these headphones were chosen and tested
Headphones for programming fail in a few predictable ways on Linux. The codec you paid for isn’t in your distro’s PipeWire build, the microphone drops the music to phone quality the moment you join a call, or the battery dies halfway through a release day. So every candidate had to clear four checks:
- You can confirm the Bluetooth codecs, battery rating and wired options on the maker’s own spec page or support site.
- You can buy the exact model new on Amazon US today, sold by Amazon or the brand itself.
- An independent review (RTINGS, SoundGuys or Tom’s Guide) backs up the claims or names the flaw.
- At least one codec better than SBC is present in the stock PipeWire build on Fedora or Ubuntu.
The Linux half of the testing ran on two fresh lab VMs, one Fedora and one Ubuntu, with the desktop audio stack installed from each distro’s own repositories. We listed the codec plugins PipeWire loads, checked which libraries each one links to, read the BlueZ defaults for LE Audio and loaded a WirePlumber codec config to make sure it parses. The VMs have no Bluetooth radio, so nothing here is a listening test or a measured latency figure.
The Sony WH-1000XM5 is the obvious name missing from this list. It’s a good headphone, but none of its Amazon US listings had an Amazon-sold buy box for a new unit when we checked, and Sony has replaced it with the XM6. If you find one new and discounted, it streams the same LDAC as the XM6 and skips LE Audio.
Compare codecs, battery and wired audio side by side
Two columns decide most purchases for a Linux user: the best codec your distro can send to that headset, and whether there’s a wired digital fallback. The codec cells are worked out from the lab’s plugin lists and each headset’s published codecs, not from a paired session. The battery figures are the maker’s ratings with noise cancelling on, and weights come from the maker or the cited review where the maker doesn’t publish one:
| Headphones | Bluetooth codecs (maker or review) | Expected codec on Fedora 45 | Expected codec on Ubuntu 26.04 (AAC package added) | Wired options | Battery, ANC on | Weight | Price band |
|---|---|---|---|---|---|---|---|
| Sony WH-1000XM6 | SBC, AAC, LDAC, LC3 | LDAC | LDAC | 3.5 mm analog only | 30 h | 254 g | about $450 |
| Bose QC Ultra (2nd Gen) | SBC, AAC, aptX Adaptive | AAC | AAC | USB-C digital, 2.5 mm analog | 30 h | about 250 g | about $450 |
| Sennheiser Momentum 4 | SBC, AAC, aptX, aptX Adaptive | AAC | aptX or AAC | USB-C digital, 3.5 mm analog | 60 h | 293 g | about $200 |
| Soundcore Space One Pro | SBC, AAC, LDAC | LDAC (app toggle) | LDAC (app toggle) | 3.5 mm analog only | 40 h | 286 g | about $140 |
Read the two codec columns together. The Sony and the Soundcore get LDAC on either distro, so you can move between a Fedora laptop and an Ubuntu workstation without hearing a difference. The Bose and the Sennheiser are built around aptX Adaptive, which no PipeWire build supports, so they fall back to whatever lesser codec your distro happens to ship. On a default Ubuntu install the Bose drops to SBC, because the AAC plugin isn’t installed and no review lists classic aptX for it. Adding one package (covered in the codec section) brings it back up to AAC.
Treat the Sennheiser’s Ubuntu cell with some care. Sennheiser’s own page lists only aptX Adaptive, AAC and SBC, while SoundGuys also lists classic aptX. If the headset doesn’t offer classic aptX to your laptop, Ubuntu will pick AAC with the extra package installed, or SBC without it. The end of the WirePlumber section shows how to check which one won once you’re paired.
Get the Sony WH-1000XM6 for LDAC on any distro
Who it suits: you switch between Fedora and Ubuntu machines, or you just want the best wireless sound Linux can give you without thinking about it. Sony lists SBC, AAC, LDAC and LC3 for the WH-1000XM6, and LDAC is the one that matters here, because both distros ship the LDAC encoder in their stock PipeWire build.
Sony rates the battery at 30 hours with noise cancelling on and 40 hours with it off, which is enough for most of a working week of meetings and focus blocks. It runs Bluetooth 5.3, weighs 254 g, folds into its case, and connects to two devices at once after you switch that on in the Sound Connect app. That multipoint toggle is worth setting up on day one, so your laptop and phone can share the headset without re-pairing. Sony does not say whether LDAC stays active with two devices connected, so if you need both, check it while you can still return the headphones.
LC3 support is the reason the XM6 shows up in every LE Audio conversation, but don’t buy it for that on Linux yet. Sony’s help guide says LE Audio is off from the factory, turns on only after you switch the app’s connection quality to low latency on an Android phone, and disables some headset functions while it’s active. Sony documents no Linux flow, and PipeWire’s own LE Audio support is still experimental, which the codec section below covers.
Skip it if you want a wired digital connection. The only cable input is a 3.5 mm analog jack, so a USB-C cable charges it but does not carry audio. The price is the other catch: it sits around $450 on Amazon (check the live price), more than double the Sennheiser.
Choose the Bose QuietComfort Ultra for USB-C audio
This one suits you if you spend most of the day at one desk and you’d rather solve the codec problem with a cable. The Bose QuietComfort Ultra Headphones (2nd Gen) accept digital audio over USB-C, which takes Bluetooth codecs out of the picture entirely and lets you listen while the headset charges.
Bose’s spec page confirms Bluetooth 5.4, one USB-C input, one auxiliary input (a 2.5 mm jack with a 3.5 mm cable in the box) and up to 30 hours of battery. It does not list codecs at all. RTINGS and SoundGuys both report SBC, AAC and aptX Adaptive, and RTINGS confirms two-device pairing. SoundGuys weighs it at 250 g.
Over Bluetooth, Linux gets the short end. Neither distro’s PipeWire can speak aptX Adaptive, so you should expect AAC on Fedora, and on Ubuntu too once you add the AAC package. That’s a step down from what you pay for, which is why the cable matters on this one. Bose doesn’t publish Linux support for USB-C audio, so plug it in on the day it arrives and confirm it shows up as an output in wpctl status before the return window closes.
Pass on it if you mostly listen wirelessly, because you’d be paying flagship money for AAC. It’s around $450 (check the live price), the same as the Sony, and the Sony gives you LDAC on both distros for that money.
Buy the Sennheiser Momentum 4 for 60-hour battery life
Pick this one if you work long days, travel to client sites and want to charge your headphones once a week. Sennheiser rates the Momentum 4 Wireless at up to 60 hours with noise cancelling on, double the Sony and the Bose. Ten minutes on the charger gives you six hours back.

It also gives you the wired fallback the Sony lacks. Sennheiser lists wired Hi-Res audio over USB-C plus a 1.2 m analog cable in the box, along with Bluetooth 5.2, four beamforming microphones for calls and the Smart Control Plus app. SoundGuys weighs it at 293 g, the heaviest here, and confirms two-device multipoint. Sennheiser does not document USB-C audio on Linux, so test the cable on day one, the same way as with the Bose.
The codec story is the same as the Bose. Its headline codec is aptX Adaptive, which PipeWire doesn’t support, so Fedora streams AAC and Ubuntu streams classic aptX if the headset offers it (otherwise AAC with the extra package, SBC without). Sennheiser has also launched the Momentum 5 with aptX Lossless, and RTINGS now lists the Momentum 4 as replaced. That isn’t bad news for you: aptX Lossless isn’t in PipeWire either, and the older model now sells at about $200 (check the live price), well under its original list price.
Look elsewhere if you want LDAC, or if a heavier headband bothers you after a few hours. Like the Bose, its Linux codec depends on which distro you run, and Fedora users get AAC and nothing better from the stock repositories.
Save with the Soundcore Space One Pro and keep LDAC
Who it suits: you want LDAC on Linux and decent noise cancelling for well under the flagship price. The Soundcore Space One Pro lists SBC, AAC and LDAC and runs Bluetooth 5.3. It sells for about $140 on Amazon (check the live price). That gets you the same LDAC result as the Sony on both distros for less than a third of the money.
Soundcore rates it at 40 hours with noise cancelling on and 60 hours off, and RTINGS rates its noise isolation highly. It weighs 286.2 g, folds flat, and takes a 3.5 mm cable when the battery runs out. There’s no USB-C audio, and the case is a soft pouch rather than a hard shell.
The part that trips people up is how LDAC gets switched on. Soundcore’s support article says you enable it in the soundcore app on an Android phone, that it can’t be combined with the Dolby audio effect, and that with LDAC on the headphones can’t connect to two devices at once. A Linux-only buyer should borrow an Android phone once to flip that setting before expecting LDAC from PipeWire. So you choose: LDAC to your laptop, or your laptop and phone both connected at SBC or AAC. If you hop between a call on your phone and music on your desk all day, that trade is worth thinking about before you buy.
It’s the wrong pick if you need LDAC and multipoint at the same time, or if you travel enough that a hard case matters. For everyone else, it’s the easiest recommendation on this list.
Check which Bluetooth codecs your Linux distro ships
PipeWire loads one plugin per Bluetooth codec, so the plugin directory tells you exactly what your machine can stream before you spend a cent. On Fedora the plugins live under /usr/lib64; list them first:
ls -1 /usr/lib64/spa-0.2/bluez5/
Fedora 45 shows AAC, LDAC and LC3 plugins, plus the call codecs, and no aptX file at all:
libspa-bluez5.so
libspa-codec-bluez5-aac.so
libspa-codec-bluez5-faststream.so
libspa-codec-bluez5-g722.so
libspa-codec-bluez5-hfp-cvsd.so
libspa-codec-bluez5-hfp-lc3-a127.so
libspa-codec-bluez5-hfp-lc3-swb.so
libspa-codec-bluez5-hfp-msbc.so
libspa-codec-bluez5-lc3.so
libspa-codec-bluez5-ldac.so
libspa-codec-bluez5-opus-g.so
libspa-codec-bluez5-opus.so
libspa-codec-bluez5-sbc.so
That missing aptX file is not an accident. Fedora’s pipewire.spec builds with bluez5-codec-aptx=disabled, and a dnf repoquery for the aptX plugin returned nothing from the stock repositories. RPM Fusion packages it separately as pipewire-codec-aptx, which the next subsection comes back to. Ubuntu keeps the plugins under the multiarch path:
ls -1 /usr/lib/x86_64-linux-gnu/spa-0.2/bluez5/
On a default Ubuntu 26.04 install the list flips: aptX is there and AAC isn’t.
libspa-bluez5.so
libspa-codec-bluez5-aptx.so
libspa-codec-bluez5-faststream.so
libspa-codec-bluez5-g722.so
libspa-codec-bluez5-hfp-cvsd.so
libspa-codec-bluez5-hfp-lc3-a127.so
libspa-codec-bluez5-hfp-lc3-swb.so
libspa-codec-bluez5-hfp-msbc.so
libspa-codec-bluez5-lc3.so
libspa-codec-bluez5-ldac.so
libspa-codec-bluez5-opus-g.so
libspa-codec-bluez5-opus.so
libspa-codec-bluez5-sbc.so
A plugin file can exist and still fail to load if its encoder library is missing, so check what each one links to. This loop runs ldd on the four codecs that decide most purchases and prints an error line for any plugin that isn’t installed:
for f in /usr/lib/x86_64-linux-gnu/spa-0.2/bluez5/libspa-codec-bluez5-{ldac,aptx,aac,lc3}.so; do echo "== $f"; ldd "$f" 2>&1 | grep -iE 'ldac|aptx|aac|lc3|No such'; done
On Ubuntu, LDAC links to Sony’s encoder, aptX to libfreeaptx and LC3 to liblc3, while the AAC plugin isn’t installed yet:
== /usr/lib/x86_64-linux-gnu/spa-0.2/bluez5/libspa-codec-bluez5-ldac.so
libldacBT_enc.so.2 => /usr/lib/x86_64-linux-gnu/libldacBT_enc.so.2 (0x00007b72794dd000)
libldacBT_abr.so.2 => /usr/lib/x86_64-linux-gnu/libldacBT_abr.so.2 (0x00007b72794d8000)
== /usr/lib/x86_64-linux-gnu/spa-0.2/bluez5/libspa-codec-bluez5-aptx.so
libfreeaptx.so.0 => /usr/lib/x86_64-linux-gnu/libfreeaptx.so.0 (0x000079209dc6f000)
== /usr/lib/x86_64-linux-gnu/spa-0.2/bluez5/libspa-codec-bluez5-aac.so
ldd: /usr/lib/x86_64-linux-gnu/spa-0.2/bluez5/libspa-codec-bluez5-aac.so: No such file or directory
== /usr/lib/x86_64-linux-gnu/spa-0.2/bluez5/libspa-codec-bluez5-lc3.so
liblc3.so.1 => /usr/lib/x86_64-linux-gnu/liblc3.so.1 (0x00007d04e38ba000)
The same loop on Fedora, with the /usr/lib64 path, showed the mirror image: LDAC and LC3 linked, AAC linked to libfdk-aac.so.2, and aptX reported as no such file. The Fedora capture comes first:

And the Ubuntu run, from the same commands on the Ubuntu VM:

Neither distro has an aptX Adaptive or aptX Lossless plugin, and the PipeWire documentation for bluez5.codecs has no value for either. That’s the single most useful fact in this guide: a headset sold on aptX Adaptive will never use it on Linux, so judge it by its AAC, aptX or LDAC support instead.
Add the AAC plugin on Ubuntu
Ubuntu does build the AAC plugin. It just ships it in a separate universe package, libspa-0.2-modules-extra, because the encoder library it depends on (libfdk-aac2) lives in universe too. If you own an AAC headset like the Bose, install it (it also pulls in a few unrelated audio libraries, ONNX Runtime among them):
sudo apt install libspa-0.2-modules-extra
Once the package is in, the plugin directory gains the AAC file, linked to the Fraunhofer encoder:
ldd /usr/lib/x86_64-linux-gnu/spa-0.2/bluez5/libspa-codec-bluez5-aac.so | grep aac
On our Ubuntu VM it resolved to the library from the same package’s dependency:
libfdk-aac.so.2 => /usr/lib/x86_64-linux-gnu/libfdk-aac.so.2 (0x000073842b380000)
Restart the audio services with systemctl --user restart pipewire wireplumber so PipeWire picks the plugin up, then reconnect the headphones. Fedora’s equivalent for aptX is RPM Fusion’s pipewire-codec-aptx, which adds only the aptX plugin once the RPM Fusion repository is enabled. Its Fedora 45 build comes from a slightly older PipeWire release than Fedora ships. We didn’t install it in the lab, so confirm the plugin file appears before relying on it.
Don’t count on LE Audio on Linux yet
Both distros ship the LC3 plugin, so the codec half of LE Audio is installed. The Bluetooth daemon half isn’t switched on. BlueZ keeps the options LE Audio needs commented out in its main config file, which you can confirm with a grep:
grep -nE '^#?\s*(ControllerMode|Experimental|KernelExperimental)\s*=' /etc/bluetooth/main.conf
Fedora 45 prints the three lines below, all commented out, so LE Audio’s experimental features are off. Ubuntu 26.04 showed the same three lines, each one line number further down:
52:#ControllerMode = dual
127:#Experimental = false
144:#KernelExperimental = false
The PipeWire LE Audio wiki page still calls the feature experimental, not enabled by default and flaky. Before you try it, check that you have everything on this list:
- Your laptop’s Bluetooth chip supports LE Audio. The wiki names Intel AX210 and AX211 plus some MediaTek and Realtek parts.
- You’ve set
ExperimentalandKernelExperimentalin/etc/bluetooth/main.conf, the second one with the ISO socket UUID listed in BlueZ’s ownmain.conf. - You accept
ControllerMode = le, which the wiki’s setup uses. That mode turns off classic Bluetooth on the adapter, so A2DP headphones and every other classic device stop working until you set it back. - Your BlueZ release meets the wiki’s preferred minimum. Fedora 45 does, and Ubuntu 26.04 ships one release short of it.
- Your headset has LE Audio turned on. On the XM6 that means the Sony app on an Android phone first.
- You can see the LE Audio service UUID
00001850inbluetoothctl infoonce the headset is paired.
If any of those is a no, buy for the classic codecs and treat LE Audio as a bonus that may work in a year. That’s why LC3 support didn’t decide any pick on this list.
Keep music quality when a call app grabs the mic
Every pick here sounds worse the moment you join a meeting through its built-in microphone. That is not a fault in your headset. Classic Bluetooth cannot run the high-quality A2DP stream and the headset microphone at the same time, so PipeWire switches to the hands-free profile and a speech codec, and your music turns muffled.
How muffled depends on the speech codec both ends agree on. Both lab machines ship CVSD, mSBC and LC3-SWB plugins for calls, and the wideband ones sound clearer than CVSD, but the makers rarely say which their headsets support. The cleaner fix for a developer who takes a lot of calls is a separate USB microphone, with the headphones left on A2DP. WirePlumber’s auto-switch setting decides whether it flips the headset into call mode when an app starts recording, and it’s on by default:
wpctl settings bluetooth.autoswitch-to-headset-profile
Both lab machines reported the default as true:
Value: true
Turn it off and save it, so the change survives a reboot. Set your USB microphone as the default input in your desktop’s sound settings too, otherwise a call app may still pick the headset mic:
wpctl settings --save bluetooth.autoswitch-to-headset-profile false
WirePlumber confirms the new value and that it was saved:
Updated and saved setting 'bluetooth.autoswitch-to-headset-profile' to: false
Reading the setting again now shows Value: false (Saved: false). With it off, the headset microphone isn’t offered until you switch the headset profile by hand, and wpctl settings --save bluetooth.autoswitch-to-headset-profile true puts the default back. If the first command says the setting is not found, that’s a startup race we hit once on a freshly booted Fedora VM: run systemctl --user restart wireplumber and try again. You can stop here if you use the headset mic for calls, because the default behaviour is what makes it work. If the headset refuses to reconnect after a profile switch, our guide to pairing a Bluetooth device from the Linux terminal covers the bluetoothctl side.
Pin LDAC to its highest bitrate in WirePlumber
With the Sony or the Soundcore, PipeWire’s LDAC encoder runs in adaptive mode by default, dropping the bitrate when the radio link gets weak. If you sit a metre from your laptop all day, you can pin it to the high-quality mode instead. This is a per-device property, so it belongs in a monitor.bluez.rules block that matches Bluetooth cards. Do not add a bluez5.codecs list while you are there: every codec is enabled by default, and a hand-written list can switch off the mSBC and LC3-SWB call codecs without telling you. Create the drop-in directory first:
mkdir -p ~/.config/wireplumber/wireplumber.conf.d
Open a new file there. You do not need sudo, because it lives in your own home directory:
vim ~/.config/wireplumber/wireplumber.conf.d/51-ldac-quality.conf
Add the rule. The ~bluez_card.* match applies it to every Bluetooth audio device, and headsets without LDAC ignore it:
monitor.bluez.rules = [
{
matches = [
{
device.name = "~bluez_card.*"
}
]
actions = {
update-props = {
bluez5.a2dp.ldac.quality = "hq"
}
}
}
]
The WirePlumber Bluetooth configuration docs list the other values (sq, mq and the default auto). If the audio starts dropping out when you walk away from the desk, go back to auto. Restart WirePlumber so it reads the file:
systemctl --user restart wireplumber && systemctl --user is-active wireplumber
Both lab machines printed active, but that alone proves little. We deliberately broke a copy of the file by deleting its closing bracket, and WirePlumber still reported active. It skipped the broken file and logged one line about it, so the journal is the real check:
journalctl --user -u wireplumber -b --no-pager -o cat | tail -6
This is what the broken copy produced on Fedora. With the good file in place, everything after the restart lines was camera warnings, which are normal on a machine with no webcam:
Stopping wireplumber.service - Multimedia Service Session Manager...
Stopped wireplumber.service - Multimedia Service Session Manager.
Started wireplumber.service - Multimedia Service Session Manager.
wp-conf: <WpConf:0x56349bd9a330> failed to open '/home/lorna/.config/wireplumber/wireplumber.conf.d/52-broken.conf': section 'monitor.bluez.rules' has no value
[0:04:23.565400738] [7249] INFO Camera camera_manager.cpp:340 libcamera v0.7.2
[0:04:23.565679014] [7273] ERROR DmaBufAllocator dma_buf_allocator.cpp:119 Could not open any dma-buf provider
If you see a failed to open line naming your file, fix the brackets and restart again. To confirm which codec a paired headset actually negotiated, the Arch Wiki Bluetooth headset page documents pactl send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez list-codecs, with your headset’s address in place of the X’s. Our VMs had no Bluetooth radio, so we couldn’t run that one, but it’s the quickest way to prove you’re getting LDAC rather than SBC.
Match the headphones to the laptop on your desk
Everything above comes down to one question: which codec will your machine actually send? Run through this before you order, especially if you’re buying as a gift for someone whose distro you don’t know:
- You run Fedora: pick an LDAC headset (the Sony or the Soundcore), or accept AAC from the Bose and Sennheiser. RPM Fusion’s aptX plugin only helps the Sennheiser. Even then, it needs to offer classic aptX.
- You run Ubuntu: pick LDAC again, or the Sennheiser for aptX if it offers classic aptX to your laptop, and install
libspa-0.2-modules-extrabefore pairing an AAC headset like the Bose. - You don’t know the distro: the Sony WH-1000XM6 and Soundcore Space One Pro sound the same on both.
- You sit at one desk all day: a USB-C audio headset (the Bose or the Sennheiser) can skip the codec question, once you’ve confirmed it shows up in
wpctl status.
If you’re building out the rest of the desk too, the same thinking applies to a Thunderbolt dock that behaves on Linux, a monitor for programming with sane HiDPI scaling and the mouse and keyboard you code on. For the trip between home and office, the laptop backpack picks for developers all have room for a headphone case.


