diff options
Diffstat (limited to 'src/audio/audio.cc')
| -rw-r--r-- | src/audio/audio.cc | 41 |
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; } } |
