summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-15 11:52:14 +0100
committerskal <pascal.massimino@gmail.com>2026-02-15 11:52:14 +0100
commit6899cc35addc43acb04bb04bcb60e88cb66ab1de (patch)
treedf2d8240e2484327c7aba754405bc3be119a308d
parentaa58489ffb597fc981fd779e9ce8b54f32e48197 (diff)
fix(audio): eliminate startup delay with automatic buffer pre-fill
Added audio_get_required_prefill_time() to query ring buffer lookahead (400ms) and audio_is_prefilled() to check buffer state. audio_start() now warns if buffer under-filled. Replaced hardcoded 100ms pre-fill with automatic target-based pre-fill in main.cc and test_demo.cc. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
-rw-r--r--src/app/main.cc4
-rw-r--r--src/app/test_demo.cc4
-rw-r--r--src/audio/audio.cc24
-rw-r--r--src/audio/audio.h6
4 files changed, 34 insertions, 4 deletions
diff --git a/src/app/main.cc b/src/app/main.cc
index 90e3015..03434a0 100644
--- a/src/app/main.cc
+++ b/src/app/main.cc
@@ -198,8 +198,8 @@ int main(int argc, char** argv) {
}
#endif /* !defined(STRIP_ALL) */
- // Pre-fill using same pattern as main loop (100ms)
- fill_audio_buffer(0.1f, 0.0);
+ // Pre-fill ring buffer to target lookahead (prevents startup delay)
+ fill_audio_buffer(audio_get_required_prefill_time(), 0.0);
audio_start();
g_last_audio_time = audio_get_playback_time(); // Initialize after start
diff --git a/src/app/test_demo.cc b/src/app/test_demo.cc
index 39dbcba..f45916a 100644
--- a/src/app/test_demo.cc
+++ b/src/app/test_demo.cc
@@ -286,8 +286,8 @@ int main(int argc, char** argv) {
audio_render_ahead(g_music_time, audio_dt * g_tempo_scale);
};
- // Pre-fill using same pattern as main loop (100ms)
- fill_audio_buffer(0.1f, 0.0);
+ // Pre-fill ring buffer to target lookahead (prevents startup delay)
+ fill_audio_buffer(audio_get_required_prefill_time(), 0.0);
audio_start();
g_last_audio_time = audio_get_playback_time();
diff --git a/src/audio/audio.cc b/src/audio/audio.cc
index d044b00..aaadd5a 100644
--- a/src/audio/audio.cc
+++ b/src/audio/audio.cc
@@ -57,11 +57,35 @@ void audio_init() {
g_audio_backend->init();
}
+float audio_get_required_prefill_time() {
+ return (float)RING_BUFFER_LOOKAHEAD_MS / 1000.0f;
+}
+
+bool audio_is_prefilled() {
+ const int buffered = g_ring_buffer.available_read();
+ const float buffered_time =
+ (float)buffered / (RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS);
+ const float required = audio_get_required_prefill_time();
+ return buffered_time >= (required - 0.001f); // 1ms tolerance
+}
+
void audio_start() {
if (g_audio_backend == nullptr) {
printf("Cannot start: audio not initialized.\n");
return;
}
+
+#if !defined(STRIP_ALL)
+ if (!audio_is_prefilled()) {
+ const int buffered = g_ring_buffer.available_read();
+ const float buffered_ms =
+ (float)buffered / (RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS) *
+ 1000.0f;
+ printf("WARNING: Audio buffer not pre-filled (%.1fms < %.1fms)\n",
+ buffered_ms, audio_get_required_prefill_time() * 1000.0f);
+ }
+#endif
+
g_audio_backend->start();
}
diff --git a/src/audio/audio.h b/src/audio/audio.h
index 9d521e6..beb994f 100644
--- a/src/audio/audio.h
+++ b/src/audio/audio.h
@@ -23,6 +23,12 @@ struct SpecHeader {
void audio_init();
void audio_start(); // Starts the audio device callback
+// Get required pre-fill time (matches ring buffer lookahead)
+float audio_get_required_prefill_time();
+
+// Check if buffer is sufficiently pre-filled
+bool audio_is_prefilled();
+
// Ring buffer audio rendering (main thread fills buffer)
// target_fill: Target buffer fill time in seconds (default:
// RING_BUFFER_LOOKAHEAD_MS/1000)