Score:0

Bluetooth headset codecs in Ubuntu 18.04 vs 20.04

cn flag

I know that Ubuntu (PulseAudio) has well-known issues with Bluetooth Headsets and for some time I was struggling to fix this. After different attempts this one helped me and everything seems to be working. I even managed to make auto-switch profiles work when I use a microphone.

But I use two Ubuntu systems (18.04 and 20.04) and available codecs differ for the same headphones on both systems. Even though I checked all the configs, installed packages, logs, etc., everything looks exactly the same.

On 20.04 I have AAC codec by default and mSBC when using a microphone which is nice. But on 18.04 I have SBC codec by default and CVSD when using a microphone which is worse.

All available profiles on 18.04:

  • Headset Head Unit (HSP/HPF, codec CVSD)
  • High Fidelity Playback (A2DP Sink)
  • High Fidelity Playback (A2DP Sink, codec SBC)

All available profiles on 20.04:

  • Headset Head Unit (HSP/HPF, codec mSBC)
  • High Fidelity Playback (A2DP Sink)
  • High Fidelity Playback (A2DP Sink, codec SBC-XQ)
  • High Fidelity Playback (A2DP Sink, codec SBC)
  • High Fidelity Playback (A2DP Sink, codec AAC)

How to bring the same codecs to 18.04 to make the quality better?

/etc/pipewire/media-session.d/bluez-monitor.conf (the same for both systems, pretty much default but bluez5.autoswitch-profile set to true):

# Bluez monitor config file for PipeWire version 0.4.1 #
#
# Copy and edit this file in /etc/pipewire/media-session.d/
# for system-wide changes or in
# ~/.config/pipewire/media-session.d/ for local changes.

properties = {
    # These features do not work on all headsets, so they are enabled
    # by default based on the hardware database. They can also be
    # forced on/off for all devices by the following options:

    #bluez5.enable-sbc-xq    = true
    #bluez5.enable-msbc      = true
    #bluez5.enable-hw-volume = true
    #bluez5.enable-faststream = true

    # See bluez-hardware.conf for the hardware database.

    # Enabled headset roles (default: [ hsp_hs hfp_ag ]), this
    # property only applies to native backend. Currently some headsets
    # (Sony WH-1000XM3) are not working with both hsp_ag and hfp_ag
    # enabled, disable either hsp_ag or hfp_ag to work around it.
    #
    # Supported headset roles: hsp_hs (HSP Headset),
    #                          hsp_ag (HSP Audio Gateway),
    #                          hfp_hf (HFP Hands-Free),
    #                          hfp_ag (HFP Audio Gateway)
    #bluez5.headset-roles = [ hsp_hs hsp_ag hfp_hf hfp_ag ]

    # Enabled A2DP codecs (default: all).
    #bluez5.codecs = [ sbc sbc_xq aac ldac aptx aptx_hd aptx_ll aptx_ll_duplex faststream faststream_duplex ]

    # HFP/HSP backend (default: native).
    # Available values: any, none, hsphfpd, ofono, native
    #bluez5.hfphsp-backend = native

    # Properties for the A2DP codec configuration
    #bluez5.default.rate     = 48000
    #bluez5.default.channels = 2

    # Register dummy AVRCP player, required for AVRCP volume function.
    # Disable if you are running mpris-proxy or equivalent.
    #bluez5.dummy-avrcp-player = true
}

rules = [
    # An array of matches/actions to evaluate.
    {
        # Rules for matching a device or node. It is an array of
        # properties that all need to match the regexp. If any of the
        # matches work, the actions are executed for the object.
        matches = [
            {
                # This matches all cards.
                device.name = "~bluez_card.*"
            }
        ]
        actions = {
            # Actions can update properties on the matched object.
            update-props = {

                # Auto-connect device profiles on start up or when only partial
                # profiles have connected. Disabled by default if the property
                # is not specified.
                #bluez5.auto-connect = [
                #    hfp_hf
                #    hsp_hs
                #    a2dp_sink
                #    hfp_ag
                #    hsp_ag
                #    a2dp_source
                #]
                bluez5.auto-connect = [ hfp_hf hsp_hs a2dp_sink ]

                # Hardware volume control (default: all)
                #bluez5.hw-volume = [
                #    hfp_hf
                #    hsp_hs
                #    a2dp_sink
                #    hfp_ag
                #    hsp_ag
                #    a2dp_source
                #]

                # LDAC encoding quality
                # Available values: auto (Adaptive Bitrate, default)
                #                   hq   (High Quality, 990/909kbps)
                #                   sq   (Standard Quality, 660/606kbps)
                #                   mq   (Mobile use Quality, 330/303kbps)
                #bluez5.a2dp.ldac.quality = auto

                # AAC variable bitrate mode
                # Available values: 0 (cbr, default), 1-5 (quality level)
                #bluez5.a2dp.aac.bitratemode = 0

                # Profile connected first
                # Available values: a2dp-sink (default), headset-head-unit
                #bluez5.profile = a2dp-sink

                # A2DP <-> HFP profile auto-switching (when device is default output)
                # Available values: false, role (default), true
                # 'role' will switch the profile if the recording application
                # specifies Communication (or "phone" in PA) as the stream role.
                bluez5.autoswitch-profile = true
            }
        }
    }
    {
        matches = [
            {
                # Matches all sources.
                node.name = "~bluez_input.*"
            }
            {
                # Matches all sinks.
                node.name = "~bluez_output.*"
            }
        ]
        actions = {
            update-props = {
                #node.nick                       = "My Node"
                #node.nick                       = null
                #priority.driver                 = 100
                #priority.session                = 100
                node.pause-on-idle               = false
                #resample.quality                = 4
                #channelmix.normalize            = false
                #channelmix.mix-lfe              = false
                #session.suspend-timeout-seconds = 5            # 0 disables suspend
                #monitor.channel-volumes         = false

                # A2DP source role, "input" or "playback"
                # Defaults to "playback", playing stream to speakers
                # Set to "input" to use as an input for apps
                #bluez5.a2dp-source-role = input
            }
        }
    }
]

upd. Looks like the reason is bluez version. Ubuntu 20.04 has bluez5.53 while Ubuntu 18.04 latest version is bluez5.48. I tried looking for PPAs, found only one (ppa:bluetooth/bluez) which offers 5.50 version. But unfortunately, it changes nothing. Any good way to upgrade bluez version in Ubuntu 18.04 to the latest one? Only manual compiling?

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.