Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf5d6c8d authored by Andy Hung's avatar Andy Hung Committed by Andre Eisenbach
Browse files

Match socket buffer sizes between audio HAL and BT server

Adjust our mixer buffer size to be one quarter that of
the socket buffer size for quadruple buffering.

Increase socket buffer size from 20*512 to 28*512 to
smooth out variability in data draw from AudioFlinger.

Bug: 28286313
Change-Id: I8a9ca9e1f4639a0724cfe126acc670c2058cb0fb
parent fb11bcfc
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -638,10 +638,16 @@ static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
static size_t out_get_buffer_size(const struct audio_stream *stream)
{
    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    // period_size is the AudioFlinger mixer buffer size.
    const size_t period_size = out->common.buffer_sz / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS;
    const size_t mixer_unit_size = 16 /* frames */ * 4 /* framesize */;

    DEBUG("buffer_size : %zu", out->common.buffer_sz);
    DEBUG("socket buffer size: %zu  period size: %zu", out->common.buffer_sz, period_size);
    if (period_size % mixer_unit_size != 0) {
        ERROR("period size %zu not a multiple of %zu", period_size, mixer_unit_size);
    }

    return out->common.buffer_sz;
    return period_size;
}

static uint32_t out_get_channels(const struct audio_stream *stream)
+37 −1
Original line number Diff line number Diff line
@@ -38,7 +38,43 @@
#define AUDIO_STREAM_DEFAULT_RATE          44100
#define AUDIO_STREAM_DEFAULT_FORMAT        AUDIO_FORMAT_PCM_16_BIT
#define AUDIO_STREAM_DEFAULT_CHANNEL_FLAG  AUDIO_CHANNEL_OUT_STEREO
#define AUDIO_STREAM_OUTPUT_BUFFER_SZ      (20*512)

// AUDIO_STREAM_OUTPUT_BUFFER_SZ controls the size of the audio socket buffer.
// If one assumes the write buffer is always full during normal BT playback,
// then increasing this value increases our playback latency.
//
// FIXME: AUDIO_STREAM_OUTPUT_BUFFER_SZ should be controlled by the actual audio
// sample rate rather than being constant.
//
// FIXME: The BT HAL should consume data at a constant rate.
// AudioFlinger assumes that the HAL draws data at a constant rate, which is true
// for most audio devices; however, the BT engine reads data at a variable rate
// (over the short term), which confuses both AudioFlinger as well as applications
// which deliver data at a (generally) fixed rate.
//
// 20 * 512 is not sufficient size to smooth the variability for some BT devices,
// resulting in mixer sleep and throttling. We increase this to 28 * 512 to help
// reduce the effect of variable data consumption.
#define AUDIO_STREAM_OUTPUT_BUFFER_SZ      (28*512)

// AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is divided
// for AudioFlinger data delivery. The AudioFlinger mixer delivers data in chunks
// of AUDIO_STREAM_OUTPUT_BUFFER_SZ / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS. If
// the number of periods is 2, the socket buffer represents "double buffering"
// of the AudioFlinger mixer buffer.
//
// In general, AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 * 4 should be a divisor of
// AUDIO_STREAM_OUTPUT_BUFFER_SZ.
//
// These values should be chosen such that
//
// AUDIO_STREAM_BUFFER_SIZE * 1000 / (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS
//         * AUDIO_STREAM_DEFAULT_RATE * 4) > 20 (ms)
//
// to avoid introducing the FastMixer in AudioFlinger. Using the FastMixer results in
// unnecessary latency and CPU overhead for Bluetooth.
#define AUDIO_STREAM_OUTPUT_BUFFER_PERIODS 4

#define AUDIO_SKT_DISCONNECTED             (-1)

typedef enum {
+7 −0
Original line number Diff line number Diff line
@@ -193,6 +193,13 @@ static int accept_server_socket(int sfd)
         return -1;
    }

    // match socket buffer size option with client
    const int size = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
    int ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char*)&size, (int)sizeof(size));
    if (ret < 0) {
        BTIF_TRACE_ERROR("setsockopt failed (%s)", strerror(errno));
    }

    //BTIF_TRACE_EVENT("new fd %d", fd);

    return fd;