Experiencing Stuttering and Audio Interruptions in Bluetooth Calls with Pulseaudio

Hi everyone,

I have Pulseaudio set up and working correctly. However, when I make/receive calls over Bluetooth, there is stuttering and audio interruptions. I tried modifying the following settings from the “Stuttering and audio interruptions” section on this Debian Wiki page:

  • high-priority = no
  • nice-level = -1
  • realtime-scheduling = yes
  • realtime-priority = 5
  • flat-volumes = no
  • resample-method = speex-float-1
  • default-sample-rate = 48000

but the issue persists. What can I adjust in the configuration to prevent this from happening?

Regards,
Ferran

Hello @ferranmc,

In terms of software, what are you using for the bluetooth audio communication?
From your previous post, you mentioned that you had to disable bluealsa to get pulseaudio to work properly when executed by a non-root user.
Bluealsa should still be a viable alternative here, but you would need to use the module-alsa-sink and pass the device=bluetooth argument when loading this plugin.

Did you take this approach?
If not, what is your setup?

Best Regards,
Bruno

Hi Bruno,

I use these modules in pulseaudio for Bluetooth:

module-bluetooth.policy
module-bluetooth-discover
module-bluez5-discover
module-bluez5-devices

Additionally, I modified the /etc/dbus-1/system.d/bluetooth.conf file by adding the following lines:

<policy user="pulse">
    <allow send_destination="org.bluez"/>
</policy>

I also modified the /etc/asound.conf file, replacing the original content with:

#pcm.!default{
#type plug
#route_policy "average"
#slave.pcm "asymed"
#}

#ctl.!default{
#type hw
#card "imx8mmwm8904"
#}

pcm.!default {
    type pulse
    hint.description "Default Audio Device"
}
ctl.!default {
    type pulse
}

To make Bluetooth calls using pulseaudio, I run the following command to set the card profile:

pactl set-card-profile bluez_card.XX_XX_XX_XX_XX_XX headset_head_unit

Despite these changes, I am still experiencing stuttering and audio interruptions when making or receiving calls over Bluetooth.

Regards,
Ferran

Hello @ferranmc,

Thanks for the additional information.
I will try to reproduce the problem here.

Best Regards,
Bruno

Hi Bruno,

When I enable bluealsa and ofono, I connect to a Bluetooth device, and then request a list of cards with the command pactl list short cards, the Bluetooth device’s card does not appear. However, if I disconnect it, the Bluetooth device’s card does appear.

I tried the approach you suggested. I configured the following line in /etc/pulse/default.pa:

load-module module-alsa-sink device=bluetooth

Then, I checked the loaded modules at system startup using pactl list short modules, and it doesn’t appear in the list. Here is the output:

0       module-device-restore
1       module-stream-restore
2       module-card-restore
3       module-augment-properties
4       module-switch-on-port-available
6       module-udev-detect      tsched=0
7       module-alsa-card        device_id="0" name="platform-sound-card" card_name="alsa_card.platform-sound-card" namereg_fail=false tsched=no fixed_latency_range=no ignore_dB=no deferred_volume=yes use_ucm=yes avoid_resampling=no card_properties="module-udev-detect.discovered=1"
8       module-bluetooth-policy
9       module-bluetooth-discover       headset=auto
10      module-bluez5-discover  headset=auto
11      module-native-protocol-unix
12      module-default-device-restore
14      module-always-sink
15      module-intended-roles
16      module-suspend-on-idle
17      module-position-event-sounds
18      module-role-cork
19      module-filter-heuristics
20      module-filter-apply
21      module-dbus-protocol

After that, I tried to load it manually with pactl load-module module-alsa-sink and got the following error:

pactl load-module module-alsa-sink
Failure: Timeout

Did it work for you? Is there anything else that needs to be configured?

Regards,
Ferran

Hi Bruno,

I am adding more information regarding the previous post.

For PulseAudio, I stop and start it in verbose mode with the following commands:

pulseaudio --kill
pulseaudio -v

Then, I try to load the module-alsa-sink module with the following command:

pactl load-module module-alsa-sink
Failure: Timeout

pactl load-module module-alsa-sink device=bluetooth
Failure: Module initialization failed

In verbose mode, I see the following:

I: [pulseaudio] client.c: Freed 4 "Native client (UNIX socket client)"
I: [pulseaudio] protocol-native.c: Connection died.

I: [pulseaudio] client.c: Created 5 "Native client (UNIX socket client)"
I: [pulseaudio] protocol-native.c: Got credentials: uid=1000 gid=1000 success=1
I: [pulseaudio] pcm.c: Unknown PCM bluetooth
I: [pulseaudio] alsa-util.c: Error opening PCM device bluetooth: No such file or directory
E: [pulseaudio] module.c: Failed to load module "module-alsa-sink" (argument: "device=bluetooth"): initialization failed.
I: [pulseaudio] client.c: Freed 5 "pactl"
I: [pulseaudio] protocol-native.c: Connection died.

Do you have any idea why this error occurs? Is there any additional configuration I should check?

Thanks,
Ferran

Hello @ferranmc,

I did not test this specific use case, but from what I read it could be a valid configuration for using bluealsa along with Pulseaudio.
More options may be needed.

My current plan is to first try to reproduce the stuttering problem you initially reported, and then move on to the module-alsa-sink load issue.

Once I have further information or updates I will send them on this thread.

Best Regards,
Bruno

Hello @ferranmc,

I was able to reproduce the stuttering and audio interruptions in a bluetooth call using pulse audio.
The main difference was that the profile which was available for the bluetooth audio was handsfree_audio_gateway, instead of headset_head_unit.
This may just be a difference in the device which is connected via bluetooth and how it names the different profiles.

I will test this again just using bluealsa to see if the problem is specific to this setup or more generalized when using bluetooth calling.
It is worth pointing out that with the a2dp_source profile, audio played well on the Verdin iMX8MM, but this mode is not available for calls.

Best Regards,
Bruno

Hi Bruno,

With only bluealsa (without PulseAudio installed), I don’t experience the audio interruptions.

Another thing that happened is that, using PulseAudio, when pairing the same phone, sometimes it only supported A2DP and the handsfree_audio_gateway profile was not available, while other times it was available. What causes this? Is there a way to force the profile to be available?

Thanks, Ferran

Hello @ferranmc,

Thanks for the confirmation.
I was also able to confirm this by following the configuration from the following post: Bluetooth Hands Free Phone no audio - #5 by rafael.tx


From my testing, when using pulseaudio it seems the phone requests which mode the device should be in.
For example, when using music playback the device gets switched automatically to a2dp, while when making calls the device gets switched to handsfree_audio_gateway.


What I think may be the solution is to get a working setup with BlueAlsa and try to use Pulseaudio over bluealsa.

Have you tested this while running alsaloop?

It may also be possible that using some combination of module-alsa-sink, module-alsa-source and module-alsa-card would be needed, considering there is both a sound input and output involved in a call.
The following page contains relevant information about the arguments available for these modules: Modules – PulseAudio

Best Regards,
Bruno

Hi Bruno,

The configuration proposed in the link works, but I detected an issue. During long calls (after 10-15 minutes), the connection becomes unstable, and there are audio dropouts. I have to restart the call audio script to fix it.

You suggested that a possible solution is to use BlueAlsa over PulseAudio. How would that be done exactly?

Additionally, could you let me know what Class is configured in /etc/bluetooth/main.conf when you perform your tests?

I tested it with alsaloop stopped.

Thanks,
Ferran

Hello @ferranmc,

I apologize the for the delay on this topic, it has been hard to get the calling feature to work on my setup.
However, one of our domain experts got a setup to work, which includes the use of the webrtc echo cancellation configuration, which I included in the following response: Pulseaudio and module-echo-cancel YOCTO recipe - #15 by bruno.tx

Therefore, the use of alsaloop does not seem to be the way to go here.


There was no specific configuration on the /etc/bluetooth/main.conf file to get this to work.

Best Regards,
Bruno

Hello,

I loaded a build from scratch to test this. Here are the steps I followed:

 uname -a
Linux NIIRA-06894995 5.15.77-6.3.0-devel+git.ddc6ca4d76ea #1 SMP PREEMPT Thu Jun 29 10:14:22 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux

To run Pulseaudio, I first stopped the following services:

systemctl stop bluealsa   
systemctl stop ofono
systemctl disable bluealsa
systemctl disable ofono

Then, I created a non-root user named test with the following commands:

adduser test
usermod -aG audio test

Additionally, I modified the /etc/dbus-1/system.d/bluetooth.conf file by adding the following lines:

<policy user="pulse">
    <allow send_destination="org.bluez"/>
</policy>

I also modified the /etc/asound.conf file, replacing the original content with:

pcm.!default {
    type pulse
    hint.description "Default Audio Device"
}
ctl.!default {
    type pulse
}

I want to indicate that I executed the script in the WebRTC thread like this:

Run as root:

echo "Killing and unblocking bluetooth"
rfkill unblock bluetooth

sleep 1
echo "Powering bluetooth" 
bluetoothctl power on

echo "Turn on agent"
bluetoothctl agent on 

sleep 1
echo "setting default agent"
bluetoothctl default-agent 

# Check for PulseAudio processes
process_id=$(ps aux | grep -i pulseaudio | grep -v grep | awk '{print $2}')

# If a PulseAudio process is found
if [ ! -z "$process_id" ]; then
    echo "PulseAudio process found with PID: $process_id"
    
    # Kill the PulseAudio process
    kill -9 $process_id
    
    # Verify if the process is killed
    if [ $? -eq 0 ]; then
        echo "PulseAudio process killed successfully."
    else
        echo "Failed to kill the PulseAudio process."
    fi
else
    echo "No PulseAudio process found."
fi

Run as test user:

# to check if PulseAudio is running
check_pulseaudio() {
    ps aux | grep -i pulseaudio | grep -v grep > /dev/null
    return $?
}

echo "starting Pulseaudio"
pulseaudio -v

# Wait for PulseAudio process to start
while ! check_pulseaudio; do
    echo "Waiting for PulseAudio to start..."
    sleep 1
done

echo "PulseAudio is now running."

echo "Loading sink/output device"
pactl load-module module-alsa-sink device=hw:0,0

sleep 1

echo "Setting default sink/output"
pactl set-default-sink alsa_output.hw_0_0

echo "Loading source/input"
pactl load-module module-alsa-source device=hw:0,0

Run as root:

echo "Enabling SCO"
hcitool -i hci0 cmd 0x3F 0x001D 0x00

I also executed the entire script as root and with the test user. However, none of these tests worked; the audio was choppy, and the receiver could not hear me.

Thanks,
Ferran

Hello @ferranmc,

Our testing was done with the root user.
We also did not disable ofono.

However, the results with the Verdin iMX8MM were not ideal, so please hold while we investigate this further.

Once we have more information we will send it on this thread.

Best Regards,
Bruno

Hi Bruno,

Thank you for the update and for the work you’re doing.

I’ve been testing with PulseAudio on my setup, and I’ve encountered some behavior that I’d like to ask you about to see if you can confirm how you’re running it.

When I try to run pulseaudio directly from the console as root, I get the following warning:

pulseaudio
W: [pulseaudio] main.c: This program is not intended to be run as root (unless --system is specified).
W: [pulseaudio] authkey.c: Failed to open cookie file '/home/root/.config/pulse/cookie': No such file or directory
W: [pulseaudio] authkey.c: Failed to load authentication key '/home/root/.config/pulse/cookie': No such file or directory
W: [pulseaudio] authkey.c: Failed to open cookie file '/home/root/.pulse-cookie': No such file or directory
W: [pulseaudio] authkey.c: Failed to load authentication key '/home/root/.pulse-cookie': No such file or directory
E: [pulseaudio] module-rescue-streams.c: module-rescue-stream is obsolete and should no longer be loaded. Please remove it from your configuration.
W: [pulseaudio] server-lookup.c: Unable to contact D-Bus: org.freedesktop.DBus.Error.NotSupported: Using X11 for dbus-daemon autolaunch was disabled at compile time, set your DBUS_SESSION_BUS_ADDRESS instead
W: [pulseaudio] main.c: Unable to contact D-Bus: org.freedesktop.DBus.Error.NotSupported: Using X11 for dbus-daemon autolaunch was disabled at compile time, set your DBUS_SESSION_BUS_ADDRESS instead

Then, when I try running it with the --system option:

pulseaudio --system
W: [pulseaudio] main.c: Running in system mode, but --disallow-exit not set.
W: [pulseaudio] main.c: Running in system mode, but --disallow-module-loading not set.
N: [pulseaudio] main.c: Running in system mode, forcibly disabling SHM mode.
W: [pulseaudio] main.c: OK, so you are running PA in system mode. Please make sure that you actually do want to do that.
W: [pulseaudio] main.c: Please read http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/WhatIsWrongWithSystemWide/ for an explanation why system mode is usually a bad idea.
W: [pulseaudio] authkey.c: Failed to open cookie file '/var/run/pulse/.config/pulse/cookie': No such file or directory
W: [pulseaudio] authkey.c: Failed to load authentication key '/var/run/pulse/.config/pulse/cookie': No such file or directory
W: [pulseaudio] authkey.c: Failed to open cookie file '/var/run/pulse/.pulse-cookie': No such file or directory
W: [pulseaudio] authkey.c: Failed to load authentication key '/var/run/pulse/.pulse-cookie': No such file or directory
W: [pulseaudio] cli-command.c: stat('/etc/pulse/system.pa.d'): No such file or directory

It runs in system mode, but there are several warnings about potential risks and drawbacks of using this mode.

Could you confirm whether you are running PulseAudio with --system in your test setup? Or if there’s any specific configuration you’re using that you could share?

I’ll also be awaiting your further updates on the Verdin iMX8MM tests as mentioned. Thanks in advance for your help.

Best regards,
Ferran

Hello @ferranmc,

In our tests, we are running PulseAudio without the --system flag and with the root user.
This is not ideal for production, but we are trying to get to a working baseline.
From this working baseline the permissions can be limited and a user created to run PulseAudio.

This is the current, non-working configuration, in case it is useful to you:

See More
  • Additions to local.conf:
ACCEPT_FSL_EULA = "1"

IMAGE_INSTALL:append = " pulseaudio-server pulseaudio-module-loopback pulseaudio-module-bluez5-discover pulseaudio-module-bluetooth-discover pulseaudio-module-bluetooth-policy pulseaudio-module-bluez5-device pulseaudio-module-cli pulseaudio-module-echo-cancel ofono pulseaudio pulseaudio-misc webrtc-audio-processing"

DISTRO_FEATURES:append = " pulseaudio"
PACKAGECONFIG:append:pn-pulseaudio = " webrtc"
  • /etc/dbus-1/system.d/pulse.conf:
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
​<busconfig>
  ​<policy user="root">
    <allow own="org.pulseaudio.Server"/>
    <allow send_destination="org.bluez"/>
    <allow send_interface="org.bluez.Manager"/>
  </policy>
  ​<policy user="pulse">
    <allow own="org.pulseaudio.Server"/>
    <allow send_destination="org.bluez"/>
    <allow send_interface="org.bluez.Manager"/>
  </policy>
  ​<policy context="default">
    <deny own="org.pulseaudio.Server"/>
    <deny send_destination="org.bluez"/>
    <deny send_interface="org.bluez.Manager"/>
  </policy>
</busconfig>
  • Addition to /etc/dbus-1/system.d/ofono.conf, at the end of ​, before ​
​<!-- add permissions for the pulse user, necessary for HFP -->
  ​<policy user="pulse">
    <allow send_destination="org.ofono"/>
  </policy>
  • Disable bluealsa:
systemctl stop bluealsa
systemctl disable bluealsa

After this setup, the board is rebooted and the linked script is used.

Best Regards,
Bruno

Hello @ferranmc,

Upon further investigation we have narrowed down the problem to the SDIO driver for the WiFi/Bluetooth module on the Verdin iMX8MM.
The setup from my last message works for the Verdin iMX8MP (which does not use the SDIO driver) and for the Verdin iMX8MM using an external bluetooth adapter.

We will continue to investigate this problem to understand where the bug is on the SDIO driver.

Best Regards,
Bruno