blob: d6c41ce3f0aa9bb19eefbc134b2b3c3df2ed1b11 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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)
};
|