SDL: aaudio: Set low-latency audio mode.

From 1e016fd5eaa3b78248fc9e14a5958c0a884b76b8 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Mon, 22 Jan 2024 18:23:14 -0500
Subject: [PATCH] aaudio: Set low-latency audio mode.

Note that apparently this has caused some weird-sounding audio
on some Android devices, so we might wrap this in a hint later,
or try to check for specific devices.

Fixes #8888.
 src/audio/aaudio/SDL_aaudio.c      | 1 +
 src/audio/aaudio/SDL_aaudiofuncs.h | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/audio/aaudio/SDL_aaudio.c b/src/audio/aaudio/SDL_aaudio.c
index c5959095fdde..057d7930b03d 100644
--- a/src/audio/aaudio/SDL_aaudio.c
+++ b/src/audio/aaudio/SDL_aaudio.c
@@ -121,6 +121,7 @@ static int aaudio_OpenDevice(_THIS, const char *devname)
     ctx.AAudioStreamBuilder_setErrorCallback(ctx.builder, aaudio_errorCallback, private);
+    ctx.AAudioStreamBuilder_setPerformanceMode(ctx.builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
     LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
          this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
diff --git a/src/audio/aaudio/SDL_aaudiofuncs.h b/src/audio/aaudio/SDL_aaudiofuncs.h
index 0aa813925d50..2bc674c038ff 100644
--- a/src/audio/aaudio/SDL_aaudiofuncs.h
+++ b/src/audio/aaudio/SDL_aaudiofuncs.h
@@ -32,7 +32,7 @@ SDL_PROC(void, AAudioStreamBuilder_setFormat, (AAudioStreamBuilder * builder, aa
 SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder * builder, aaudio_sharing_mode_t sharingMode))
 SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction))
 SDL_PROC_UNUSED(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames))
-SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode))
+SDL_PROC(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode))
 SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage))                                         /* API 28 */
 SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType))                      /* API 28 */
 SDL_PROC_UNUSED(void, AAudioStreamBuilder_setInputPreset, (AAudioStreamBuilder * builder, aaudio_input_preset_t inputPreset))                      /* API 28 */


disclaimer: this is my first post in this forum, and I am not particularly experienced with SDL

Looking at this post I notice that the code that opens an audio device in Android ignores the samples parameter of the audio spec structure. The result is that it does not look like it’s possible to adjust the audio buffer size in Android. I have done some sound experiments with a piece of code that runs in both Linux and Android, and the audio in the Android version has significant jittering, due to the delay due to buffering.

I have found that the following patch reduces the audio delay and the jittering significantly:

diff -Naur a/src/audio/aaudio/SDL_aaudio.c b/src/audio/aaudio/SDL_aaudio.c
--- a/src/audio/aaudio/SDL_aaudio.c	2024-01-28 01:51:37.000000000 -0500
+++ b/src/audio/aaudio/SDL_aaudio.c	2024-01-31 23:36:22.164434054 -0500
@@ -128,6 +128,7 @@
         return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
+    ctx.AAudioStream_setBufferSizeInFrames(private->stream, this->spec.samples);
     this->spec.freq = ctx.AAudioStream_getSampleRate(private->stream);
     this->spec.channels = ctx.AAudioStream_getChannelCount(private->stream);
@@ -250,6 +251,7 @@
         LOGI("SDL Failed AAudioStreamBuilder_openStream %d", res);
         return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
+    ctx.AAudioStream_setBufferSizeInFrames(hidden->stream, device->spec.samples);

Without those lines the default buffer size in my Android device (Pixel 4a) is 40ms worth of samples. With those lines I can reduce that to 20ms. That is not great either, but it is significantly better. Note that in my laptop running windows I can set the number of samples to 64, which is less than 2ms at 44.1kHz.