1#[derive(Debug, Clone)]
5pub struct EegSample {
6 pub timestamp_ms: u64,
8 pub values: Vec<f32>,
10}
11
12impl EegSample {
13 pub fn new(timestamp_ms: u64, values: Vec<f32>) -> Self {
14 Self {
15 timestamp_ms,
16 values,
17 }
18 }
19
20 pub fn channel_count(&self) -> usize {
21 self.values.len()
22 }
23
24 pub fn get(&self, channel: usize) -> Option<f32> {
25 self.values.get(channel).copied()
26 }
27}
28
29#[derive(Debug, Clone)]
31pub struct SampleBuffer {
32 pub sample_rate: u16,
34 pub channel_count: usize,
36 data: Vec<f32>,
38 timestamps: Vec<u64>,
40}
41
42impl SampleBuffer {
43 pub fn new(sample_rate: u16, channel_count: usize) -> Self {
44 Self {
45 sample_rate,
46 channel_count,
47 data: Vec::new(),
48 timestamps: Vec::new(),
49 }
50 }
51
52 pub fn with_capacity(sample_rate: u16, channel_count: usize, sample_capacity: usize) -> Self {
54 Self {
55 sample_rate,
56 channel_count,
57 data: Vec::with_capacity(channel_count * sample_capacity),
58 timestamps: Vec::with_capacity(sample_capacity),
59 }
60 }
61
62 pub fn sample_count(&self) -> usize {
64 self.timestamps.len()
65 }
66
67 pub fn duration_secs(&self) -> f32 {
69 self.sample_count() as f32 / self.sample_rate as f32
70 }
71
72 pub fn clear(&mut self) {
74 self.data.clear();
75 self.timestamps.clear();
76 }
77
78 pub fn push(&mut self, sample: &EegSample) {
80 assert_eq!(sample.channel_count(), self.channel_count);
81 self.timestamps.push(sample.timestamp_ms);
82 for (ch, &value) in sample.values.iter().enumerate() {
84 let idx = ch * self.sample_count() + (self.timestamps.len() - 1);
85 if idx >= self.data.len() {
86 self.data
87 .resize(self.channel_count * self.timestamps.len(), 0.0);
88 }
89 self.data[ch * self.timestamps.len() + self.timestamps.len() - 1] = value;
90 }
91 }
92
93 pub fn push_interleaved(&mut self, data: &[f32], timestamp_start: u64, sample_rate: u16) {
96 let samples_per_channel = data.len() / self.channel_count;
97 let sample_interval_ms = 1000.0 / sample_rate as f64;
98
99 let start_idx = self.timestamps.len();
100
101 for i in 0..samples_per_channel {
103 let ts = timestamp_start + (i as f64 * sample_interval_ms) as u64;
104 self.timestamps.push(ts);
105 }
106
107 let new_sample_count = self.timestamps.len();
109 self.data.resize(self.channel_count * new_sample_count, 0.0);
110
111 for sample_idx in 0..samples_per_channel {
113 for ch in 0..self.channel_count {
114 let src_idx = sample_idx * self.channel_count + ch;
115 let dst_idx = ch * new_sample_count + start_idx + sample_idx;
116 self.data[dst_idx] = data[src_idx];
117 }
118 }
119 }
120
121 pub fn channel_data(&self, channel: usize) -> &[f32] {
123 let start = channel * self.sample_count();
124 let end = start + self.sample_count();
125 &self.data[start..end]
126 }
127
128 pub fn channel_data_mut(&mut self, channel: usize) -> &mut [f32] {
130 let count = self.sample_count();
131 let start = channel * count;
132 let end = start + count;
133 &mut self.data[start..end]
134 }
135
136 pub fn timestamp(&self, sample_idx: usize) -> Option<u64> {
138 self.timestamps.get(sample_idx).copied()
139 }
140
141 pub fn recent_channel_data(&self, channel: usize, n: usize) -> &[f32] {
143 let data = self.channel_data(channel);
144 if data.len() <= n {
145 data
146 } else {
147 &data[data.len() - n..]
148 }
149 }
150
151 pub fn retain_recent(&mut self, n: usize) {
153 if self.sample_count() <= n {
154 return;
155 }
156
157 let remove_count = self.sample_count() - n;
158
159 self.timestamps.drain(0..remove_count);
161
162 let new_count = self.timestamps.len();
164 for ch in 0..self.channel_count {
165 let old_start = ch * (new_count + remove_count) + remove_count;
166 let new_start = ch * new_count;
167 for i in 0..new_count {
168 self.data[new_start + i] = self.data[old_start + i];
169 }
170 }
171 self.data.truncate(self.channel_count * new_count);
172 }
173}
174
175#[cfg(test)]
176mod tests {
177 use super::*;
178
179 #[test]
180 fn test_sample_buffer_interleaved() {
181 let mut buf = SampleBuffer::new(256, 2);
182
183 let data = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
185 buf.push_interleaved(&data, 1000, 256);
186
187 assert_eq!(buf.sample_count(), 3);
188 assert_eq!(buf.channel_data(0), &[1.0, 3.0, 5.0]);
189 assert_eq!(buf.channel_data(1), &[2.0, 4.0, 6.0]);
190 }
191
192 #[test]
193 fn test_recent_data() {
194 let mut buf = SampleBuffer::new(256, 1);
195 let data: Vec<f32> = (0..10).map(|i| i as f32).collect();
196 buf.push_interleaved(&data, 0, 256);
197
198 assert_eq!(buf.recent_channel_data(0, 3), &[7.0, 8.0, 9.0]);
199 }
200}