How to prevent Automatic Switching to HSP/HFP on KDE Neon After Update?

Hello,

Since the last update of KDE Neon, I have an issue with my Bluetooth headset in A2DP mode. Previously, when I connected my headset, it stayed in A2DP, and if I wanted to enable HSP/HFP mode to use the headset microphone, I would manually switch it in the audio settings.

However, since the update, as soon as I join a voice channel (e.g., on Discord) or use an application that requires a microphone, PulseAudio or PipeWire automatically switches the headset to HSP/HFP, which significantly reduces audio quality. I then have to go back into the settings to manually switch it back to A2DP.

This behavior did not occur before, and I would like to restore the previous functionality:

  • Keep my headset in A2DP mode unless I manually change the profile
  • Allow me to switch to HSP/HFP when needed, but only through manual action
  • Prevent PulseAudio (or PipeWire) from automatically forcing HSP/HFP mode

Does anyone have a solution to prevent this automatic switching while still allowing manual profile changes if necessary?

Thanks in advance for your help!

You can try a few things.
Pipewire/wireplumber caches device states, profiles and other info in ~/.local/state/wireplumber.
It is possible that an option or setting for the device is corrupt or not saving the current device profile (a2dp).

You can poke around the files, but one can delete that directory and reboot, or probably more correctly, stop the service, remove the directory, then restart the service:

$ systemctl --user stop wireplumber.service
$ rm -r ~/.local/state/wireplumber # deletes settings
$ systemctl --user start wireplumber.service

This should reset any preferences to normal defaults, so hopefully it stops reverting to HSP/HFP.

If that doesn’t work you can try editing your pulseaudio config, which still is present and probably still used for configuration settings. This is the old pulseaudio setting to turn off the autoswitching, and may still work.

1 Like

Thank you for your response!

Before deleting the cache, I checked its contents and found these files:

martin@martin-pulse17b13vfk î‚° ~ î‚° ls ~/.local/state/wireplumber
default-nodes  default-profile  default-routes  policy-bluetooth  restore-stream

I checked their contents, specifically default-profile and policy-bluetooth:

martin@martin-pulse17b13vfk î‚° ~ î‚° cat ~/.local/state/wireplumber/default-profile
[default-profile]
bluez_card.40_58_99_B7_18_F7=a2dp-sink-sbc_xq
martin@martin-pulse17b13vfk î‚° ~ î‚° cat ~/.local/state/wireplumber/policy-bluetooth
[policy-bluetooth]
saved-headset-profile:bluez_card.40_58_99_B7_18_F7=a2dp-sink-sbc_xq

As far as I can tell, the default profile saved is A2DP with SBC XQ, so I don’t understand why it automatically switches to HSP/HFP as soon as an application requests a microphone.

Next, I checked whether PulseAudio is still involved using the following command:

martin@martin-pulse17b13vfk î‚° ~ î‚° pactl list cards | grep bluez
        Name: bluez_card.40_58_99_B7_18_F7
        Driver: module-bluez5-device.c
                api.bluez5.address = "40:58:99:B7:18:F7"
                api.bluez5.class = "0x240404"
                api.bluez5.connection = "disconnected"
                api.bluez5.device = ""
                api.bluez5.icon = "audio-headset"
                api.bluez5.id = "1"
                api.bluez5.path = "/org/bluez/hci0/dev_40_58_99_B7_18_F7"
                bluez5.profile = "off"
                device.api = "bluez5"
                device.name = "bluez_card.40_58_99_B7_18_F7"

From this output, PulseAudio appears to be active and still using module-bluez5-device.c.
However, I find it strange that api.bluez5.connection = "disconnected" and bluez5.profile = "off", even though my headset is connected and working for audio. Is this normal?

I also checked WirePlumber’s status:

martin@martin-pulse17b13vfk î‚° ~ î‚° systemctl --user status wireplumber
â—Ź wireplumber.service - Multimedia Service Session Manager
     Loaded: loaded (/usr/lib/systemd/user/wireplumber.service; enabled; preset: enabled)
     Active: active (running) since Thu 2025-02-06 06:09:10 CET; 4 days ago
   Main PID: 2362 (wireplumber)
      Tasks: 6 (limit: 38062)
     Memory: 12.5M (peak: 15.2M swap: 2.7M swap peak: 2.8M)
        CPU: 22min 42.664s
     CGroup: /user.slice/user-1000.slice/user@1000.service/session.slice/wireplumber.service
             └─2362 /usr/bin/wireplumber

Feb 10 11:50:52 martin-pulse17b13vfk wireplumber[2362]: <WpSiAudioAdapter:0x5eaf432b8970> Object activation aborted: proxy destroyed
Feb 10 11:50:52 martin-pulse17b13vfk wireplumber[2362]: <WpSiAudioAdapter:0x5eaf432b8970> failed to activate item: Object activation aborted: proxy destroyed
Feb 10 11:50:52 martin-pulse17b13vfk wireplumber[2362]: <WpSiStandardLink:0x5eaf4361aa60> si-standard-link: in/out items are not valid anymore
Feb 10 11:50:52 martin-pulse17b13vfk wireplumber[2362]: <WpSiStandardLink:0x5eaf43452d80> 2 of 2 PipeWire links failed to activate
Feb 10 11:50:52 martin-pulse17b13vfk wireplumber[2362]: <WpSiStandardLink:0x5eaf431b52e0> item deactivated before format set
Feb 10 13:00:07 martin-pulse17b13vfk wireplumber[2362]: 0x5eaf4370bf58: error 24
Feb 10 13:00:07 martin-pulse17b13vfk wireplumber[2362]: (bluez_output.40_58_99_B7_18_F7.1-299) running -> error (Received error event)
Feb 10 13:00:07 martin-pulse17b13vfk wireplumber[2362]: Failure in Bluetooth audio transport /org/bluez/hci0/dev_40_58_99_B7_18_F7/sep1/fd31
Feb 10 13:12:55 martin-pulse17b13vfk wireplumber[2362]: <WpSiNode:0x5eaf43192e70> Object activation aborted: proxy destroyed
Feb 10 13:12:55 martin-pulse17b13vfk wireplumber[2362]: <WpSiNode:0x5eaf43192e70> failed to activate item: Object activation aborted: proxy destroyed

The service is running, but there are multiple recurring errors related to PipeWire links failing to activate, as well as an Object activation aborted: proxy destroyed error. I’m not sure if this is related to my issue where the Bluetooth profile switches to HSP/HFP.

Before trying anything, do these outputs seem normal to you? Is there anything else I should check before clearing WirePlumber’s cache or modifying PulseAudio?

Thanks again for your help!

I have no idea. I just know when I was mucking around with enabling and fiddling with Bluetooth codecs when full-pipewire was newer, and had similar issues. Even though these cache files seemed to reflect the correct settings, deleting them fixed things, and is fairly well documented.
Deleting these won’t hurt anything.

I tried it, I’ll see if it fixes the problem and I will give an update here.

~/.config/wireplumber/wireplumber.conf.d/90-no-bt-autoswitch.conf

wireplumber.settings = {
    ## Whether to use headset profile in the presence of an input stream.
    bluetooth.autoswitch-to-headset-profile = false
}
2 Likes

It seems the issue is fixed for now, if it happens again, i’ll try