summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio/audio.cc41
1 files changed, 23 insertions, 18 deletions
diff --git a/src/audio/audio.cc b/src/audio/audio.cc
index 779cb6c..de1c702 100644
--- a/src/audio/audio.cc
+++ b/src/audio/audio.cc
@@ -72,11 +72,6 @@ void audio_start() {
}
void audio_render_ahead(float music_time, float dt) {
- // Calculate how much audio is currently buffered
- int buffered_samples = g_ring_buffer.available_read();
- float buffered_time =
- (float)buffered_samples / (RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS);
-
// Target: maintain look-ahead buffer
const float target_lookahead =
(float)RING_BUFFER_LOOKAHEAD_MS / 1000.0f;
@@ -86,20 +81,33 @@ void audio_render_ahead(float music_time, float dt) {
const int chunk_frames = (int)(dt * RING_BUFFER_SAMPLE_RATE);
const int chunk_samples = chunk_frames * RING_BUFFER_CHANNELS;
+ if (chunk_frames <= 0) return;
+
// Keep rendering small chunks until buffer is full enough
- while (buffered_time < target_lookahead) {
- const int frames_to_render = chunk_frames;
- if (frames_to_render <= 0) break;
+ while (true) {
+ // Check current buffer state
+ const int buffered_samples = g_ring_buffer.available_read();
+ const float buffered_time =
+ (float)buffered_samples / (RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS);
+
+ // Stop if buffer is full enough
+ if (buffered_time >= target_lookahead) break;
+
+ // Check if buffer has space for this chunk BEFORE rendering
+ const int available_space = g_ring_buffer.available_write();
+ if (available_space < chunk_samples) {
+ // Buffer is too full, wait for audio callback to consume more
+ break;
+ }
// Allocate temporary buffer (stereo)
- const int samples_to_render = frames_to_render * RING_BUFFER_CHANNELS;
- float* temp_buffer = new float[samples_to_render];
+ float* temp_buffer = new float[chunk_samples];
// Render audio from synth (advances synth state incrementally)
- synth_render(temp_buffer, frames_to_render);
+ synth_render(temp_buffer, chunk_frames);
- // Write to ring buffer
- const int written = g_ring_buffer.write(temp_buffer, samples_to_render);
+ // Write to ring buffer (should succeed since we checked space)
+ const int written = g_ring_buffer.write(temp_buffer, chunk_samples);
// Notify backend of frames rendered (for testing/tracking)
if (g_audio_backend != nullptr) {
@@ -108,11 +116,8 @@ void audio_render_ahead(float music_time, float dt) {
delete[] temp_buffer;
- // Update buffered time for next iteration
- buffered_time += (float)written / (RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS);
-
- // Safety: avoid infinite loop if buffer is full
- if (written < samples_to_render) break;
+ // Safety: if write failed unexpectedly, stop to avoid infinite loop
+ if (written < chunk_samples) break;
}
}