brainwires_audio/
buffer.rs1use crate::types::AudioConfig;
2
3pub struct AudioRingBuffer {
8 data: Vec<u8>,
9 capacity: usize,
10 write_pos: usize,
11 len: usize,
12 config: AudioConfig,
13}
14
15impl AudioRingBuffer {
16 pub fn new(config: AudioConfig, duration_secs: f64) -> Self {
18 let capacity =
19 (config.sample_rate as f64 * duration_secs) as usize * config.bytes_per_frame();
20 Self {
21 data: vec![0u8; capacity],
22 capacity,
23 write_pos: 0,
24 len: 0,
25 config,
26 }
27 }
28
29 pub fn push(&mut self, bytes: &[u8]) {
31 for &byte in bytes {
32 self.data[self.write_pos] = byte;
33 self.write_pos = (self.write_pos + 1) % self.capacity;
34 if self.len < self.capacity {
35 self.len += 1;
36 }
37 }
38 }
39
40 pub fn read_all(&self) -> Vec<u8> {
44 if self.len < self.capacity {
45 self.data[..self.len].to_vec()
47 } else {
48 let mut result = Vec::with_capacity(self.capacity);
50 result.extend_from_slice(&self.data[self.write_pos..]);
51 result.extend_from_slice(&self.data[..self.write_pos]);
52 result
53 }
54 }
55
56 pub fn duration_secs(&self) -> f64 {
58 let frame_size = self.config.bytes_per_frame();
59 if frame_size == 0 {
60 return 0.0;
61 }
62 let num_frames = self.len / frame_size;
63 num_frames as f64 / self.config.sample_rate as f64
64 }
65
66 pub fn len(&self) -> usize {
68 self.len
69 }
70
71 pub fn is_empty(&self) -> bool {
73 self.len == 0
74 }
75
76 pub fn capacity(&self) -> usize {
78 self.capacity
79 }
80
81 pub fn is_full(&self) -> bool {
83 self.len >= self.capacity
84 }
85
86 pub fn clear(&mut self) {
88 self.write_pos = 0;
89 self.len = 0;
90 }
91
92 pub fn config(&self) -> &AudioConfig {
94 &self.config
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn test_ring_buffer_basic() {
104 let config = AudioConfig::speech(); let mut buf = AudioRingBuffer::new(config, 0.001); assert!(buf.is_empty());
108 assert_eq!(buf.duration_secs(), 0.0);
109
110 buf.push(&[1, 2, 3, 4]);
111 assert_eq!(buf.len(), 4);
112 assert_eq!(buf.read_all(), vec![1, 2, 3, 4]);
113 }
114
115 #[test]
116 fn test_ring_buffer_wrap() {
117 let config = AudioConfig {
118 sample_rate: 4,
119 channels: 1,
120 sample_format: crate::types::SampleFormat::I16,
121 };
122 let mut buf = AudioRingBuffer::new(config, 1.0);
124 assert_eq!(buf.capacity(), 8);
125
126 buf.push(&[1, 2, 3, 4, 5, 6, 7, 8]);
127 assert!(buf.is_full());
128
129 buf.push(&[9, 10]);
131 let data = buf.read_all();
132 assert_eq!(data, vec![3, 4, 5, 6, 7, 8, 9, 10]);
133 }
134
135 #[test]
136 fn test_ring_buffer_clear() {
137 let config = AudioConfig::speech();
138 let mut buf = AudioRingBuffer::new(config, 0.01);
139 buf.push(&[1, 2, 3, 4]);
140 buf.clear();
141 assert!(buf.is_empty());
142 assert_eq!(buf.len(), 0);
143 }
144}