diff options
Diffstat (limited to 'src/audio/audio.cc')
| -rw-r--r-- | src/audio/audio.cc | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/audio/audio.cc b/src/audio/audio.cc index 6ee9782..7c0f490 100644 --- a/src/audio/audio.cc +++ b/src/audio/audio.cc @@ -5,6 +5,7 @@ #include "audio.h" #include "audio_backend.h" #include "miniaudio_backend.h" +#include "ring_buffer.h" #include "synth.h" #include "util/asset_manager.h" @@ -13,6 +14,9 @@ #include <stdio.h> +// Global ring buffer for audio streaming +static AudioRingBuffer g_ring_buffer; + // Global backend pointer for audio abstraction static AudioBackend* g_audio_backend = nullptr; static MiniaudioBackend g_default_backend; @@ -67,6 +71,55 @@ void audio_start() { g_audio_backend->start(); } +void audio_render_ahead(float music_time, float dt) { + // Calculate how much audio is currently buffered + const int buffered_samples = g_ring_buffer.available_read(); + const 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; + + // Only render if we're below target + if (buffered_time < target_lookahead * 0.5f) { // Refill when half empty + // Calculate how many frames to render + const float time_to_render = target_lookahead - buffered_time; + const int frames_to_render = + (int)(time_to_render * RING_BUFFER_SAMPLE_RATE); + + if (frames_to_render > 0) { + // Allocate temporary buffer (stereo) + const int samples_to_render = frames_to_render * RING_BUFFER_CHANNELS; + float* temp_buffer = new float[samples_to_render]; + + // Render audio from synth + synth_render(temp_buffer, frames_to_render); + + // Write to ring buffer + const int written = g_ring_buffer.write(temp_buffer, samples_to_render); + + // Notify backend of frames rendered (for testing/tracking) + if (g_audio_backend != nullptr) { + g_audio_backend->on_frames_rendered(written / RING_BUFFER_CHANNELS); + } + + delete[] temp_buffer; + } + } +} + +float audio_get_playback_time() { + const int64_t total_samples = g_ring_buffer.get_total_read(); + return (float)total_samples / + (RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS); +} + +// Expose ring buffer for backends +AudioRingBuffer* audio_get_ring_buffer() { + return &g_ring_buffer; +} + #if !defined(STRIP_ALL) void audio_render_silent(float duration_sec) { const int sample_rate = 32000; |
