1#[derive(Debug, Clone)]
20pub struct ReferenceRing {
21 buf: Vec<f32>,
22 cap: usize,
23 write_pos: usize,
24 len: usize,
25}
26
27impl ReferenceRing {
28 pub fn new(max_delay_samples: usize) -> Self {
29 let cap = max_delay_samples.max(160) + 4096;
30 Self {
31 buf: vec![0.0; cap],
32 cap,
33 write_pos: 0,
34 len: 0,
35 }
36 }
37
38 pub fn push(&mut self, samples: &[f32]) {
39 for &s in samples {
40 self.buf[self.write_pos] = s;
41 self.write_pos = (self.write_pos + 1) % self.cap;
42 self.len = self.len.saturating_add(1).min(self.cap);
43 }
44 }
45
46 pub fn clear(&mut self) {
47 self.len = 0;
48 self.write_pos = 0;
49 }
50
51 pub fn read_delayed(&self, delay_samples: usize, out_len: usize, out: &mut [f32]) {
53 let n = out.len().min(out_len);
54 for i in 0..n {
55 let age = delay_samples + (out_len - n) + i;
56 out[i] = self.sample_at_age(age);
57 }
58 }
59
60 fn sample_at_age(&self, age: usize) -> f32 {
61 if self.len == 0 || age >= self.len {
62 return 0.0;
63 }
64 let idx = (self.write_pos + self.cap - 1 - age) % self.cap;
65 self.buf[idx]
66 }
67}
68
69pub fn estimate_delay_samples(far: &[f32], mic: &[f32], _n_fft: usize, max_delay: usize) -> usize {
71 let n = far.len().min(mic.len());
72 if n < 64 {
73 return 0;
74 }
75 let search = max_delay.min(n - 1);
76 let mut best_lag = 0usize;
77 let mut best = -1e30f32;
78 for lag in 0..=search {
79 let mut sum = 0.0f32;
80 for i in lag..n {
81 sum += far[i - lag] * mic[i];
82 }
83 if sum > best {
84 best = sum;
85 best_lag = lag;
86 }
87 }
88 best_lag
89}