diff options
Diffstat (limited to 'src/audio/ring_buffer.h')
| -rw-r--r-- | src/audio/ring_buffer.h | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/audio/ring_buffer.h b/src/audio/ring_buffer.h new file mode 100644 index 0000000..d6c41ce --- /dev/null +++ b/src/audio/ring_buffer.h @@ -0,0 +1,50 @@ +// This file is part of the 64k demo project. +// It implements a lock-free ring buffer for audio streaming. +// Bridges main thread (variable tempo) and audio thread (fixed rate). + +#pragma once + +#include <atomic> +#include <cstdint> + +// Ring buffer capacity: 200ms @ 32kHz stereo +// = 200ms * 32000 samples/sec * 2 channels / 1000ms = 12800 samples +// This is exactly 25 DCT frames (25 * 512 = 12800) +#define RING_BUFFER_LOOKAHEAD_MS 200 +#define RING_BUFFER_SAMPLE_RATE 32000 +#define RING_BUFFER_CHANNELS 2 +#define RING_BUFFER_CAPACITY_SAMPLES \ + ((RING_BUFFER_LOOKAHEAD_MS * RING_BUFFER_SAMPLE_RATE * RING_BUFFER_CHANNELS) / 1000) + +class AudioRingBuffer { + public: + AudioRingBuffer(); + ~AudioRingBuffer(); + + // Thread-safe write (main thread) + // Returns number of samples actually written + int write(const float* samples, int count); + + // Thread-safe read (audio thread) + // Returns number of samples actually read + // If not enough samples available, fills remainder with silence + int read(float* samples, int count); + + // Query buffer state + int available_write() const; // Samples that can be written + int available_read() const; // Samples that can be read + + // Get total samples consumed (for timing) + int64_t get_total_read() const { return total_read_.load(std::memory_order_acquire); } + + // Clear buffer (for seeking) + void clear(); + + private: + float buffer_[RING_BUFFER_CAPACITY_SAMPLES]; + int capacity_; // Total capacity in samples + + std::atomic<int> write_pos_; // Write position (0 to capacity-1) + std::atomic<int> read_pos_; // Read position (0 to capacity-1) + std::atomic<int64_t> total_read_; // Total samples read (for playback time) +}; |
