A2DP on PulseAudio - terrible choppy/skipping audio

As none of the other answers worked on my system (Ubuntu 18.04 LTS on a 2012 MacBook Air), I found my solution on the german ubuntuusers wiki. English summary of the german instructions:

The choppy output might be caused by the A2DP implementation, and how it buffers sound before encoding it. For me, changing this buffer's size solved the choppy sound problem. You need to perform three steps:

  1. Find necessary info about the bluetooth device (while it is connected!)

    pactl list | grep -Pzo '.*bluez_card(.*\n)*'
    

The output should be something like

    Name: bluez_card.28_11_A5_84_B6_F9
    Driver: module-bluez5-device.c
    ...
    Ports:
    speaker-output: Speaker (priority: 0, latency offset: 0 usec, available)
        Part of profile(s): a2dp_sink, headset_head_unit
    speaker-input: Bluetooth Input (priority: 0, latency offset: 0 usec, not available)
        Part of profile(s): headset_head_unit

We see that the buffers have currently 0 latency. In the next step, you will need the NAME and PORT of your output. In this example, these are bluez_card.28_11_A5_84_B6_F9 and speaker-output, respectively.

  1. Set the buffer size (latency) of your card to a suitable value with this command pattern:

    pactl set-port-latency-offset <NAME> <PORT> <BUFFER_SIZE_MICROSECONDS> 
    

The latency unit of the following command is microseconds, so I'm using a 50 millisecond buffer for my command here:

    pactl set-port-latency-offset bluez_card.28_11_A5_84_B6_F9 speaker-output 50000 
  1. Restart your bluetooth service to apply your change

    sudo service bluetooth restart
    

As there is usually no documentation about this, you may have to experiment with higher or lower buffer values. Many people people posted their working latencies in the comments to this answer. Check them out for guidance on the latency value.


Edit the ALSA configuration file

sudo gedit /etc/modprobe.d/alsa-base.conf

Add the line

options snd-hda-intel model=generic

to the end of the file, and restart the bluetooth service:

sudo service bluetooth restart

Chris_128 answer worked for me but for newbies I'll add a bit detail.

For the NAME and PORT for the command below:

pactl set-port-latency-offset NAME PORT 50000 

You will get it after you have result from typing:

pactl list | grep -Pzo '.*bluez_card(.*\n)*'


Name: bluez_card.5C_FB_7C_0D_0F_EE
Driver: module-bluez5-device.c
Owner Module: 28
Properties:
    ...
Profiles:
    headset_head_unit: Headset Head Unit (HSP/HFP) (sinks: 1, sources: 1, priority: 30, available: yes)
    a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 40, available: yes)
    off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: a2dp_sink
Ports:
    headset-output: Headset (priority: 0, latency offset: 0 usec, available)
        Part of profile(s): headset_head_unit, a2dp_sink
    headset-input: Headset (priority: 0, latency offset: 0 usec)
        Part of profile(s): headset_head_unit

The NAME will be "bluez_card.5C_FB_7C_0D_0F_EE" and the PORT will be "headset-output"

So for my case my command is

"pactl set-port-latency-offset bluez_card.5C_FB_7C_0D_0F_EE headset-output 50000"

Restart your bluetooth service

sudo service bluetooth restart