1use crate::{ProcessTimings, VadCapabilities, VadError, VoiceActivityDetector};
8
9pub struct FrameAdapter {
14 inner: Box<dyn VoiceActivityDetector>,
16 capabilities: VadCapabilities,
18 buffer: Vec<i16>,
20}
21
22impl FrameAdapter {
23 pub fn new(inner: Box<dyn VoiceActivityDetector>) -> Self {
25 let capabilities = inner.capabilities();
26 Self {
27 inner,
28 capabilities,
29 buffer: Vec::new(),
30 }
31 }
32
33 pub fn capabilities(&self) -> &VadCapabilities {
35 &self.capabilities
36 }
37
38 pub fn sample_rate(&self) -> u32 {
40 self.capabilities.sample_rate
41 }
42
43 pub fn frame_size(&self) -> usize {
45 self.capabilities.frame_size
46 }
47
48 pub fn process(&mut self, samples: &[i16], sample_rate: u32) -> Result<Option<f32>, VadError> {
60 if sample_rate != self.capabilities.sample_rate {
61 return Err(VadError::InvalidSampleRate(sample_rate));
62 }
63
64 self.buffer.extend_from_slice(samples);
65
66 if self.buffer.len() >= self.capabilities.frame_size {
67 let frame: Vec<i16> = self.buffer.drain(..self.capabilities.frame_size).collect();
68 let probability = self.inner.process(&frame, sample_rate)?;
69 Ok(Some(probability))
70 } else {
71 Ok(None)
72 }
73 }
74
75 pub fn process_all(&mut self, samples: &[i16], sample_rate: u32) -> Result<Vec<f32>, VadError> {
80 if sample_rate != self.capabilities.sample_rate {
81 return Err(VadError::InvalidSampleRate(sample_rate));
82 }
83
84 self.buffer.extend_from_slice(samples);
85
86 let mut results = Vec::new();
87 while self.buffer.len() >= self.capabilities.frame_size {
88 let frame: Vec<i16> = self.buffer.drain(..self.capabilities.frame_size).collect();
89 let probability = self.inner.process(&frame, sample_rate)?;
90 results.push(probability);
91 }
92
93 Ok(results)
94 }
95
96 pub fn process_latest(&mut self, samples: &[i16], sample_rate: u32) -> Result<f32, VadError> {
101 let results = self.process_all(samples, sample_rate)?;
102 Ok(results.into_iter().last().unwrap_or(0.0))
103 }
104
105 pub fn reset(&mut self) {
107 self.buffer.clear();
108 self.inner.reset();
109 }
110
111 pub fn buffered_samples(&self) -> usize {
113 self.buffer.len()
114 }
115
116 pub fn timings(&self) -> ProcessTimings {
118 self.inner.timings()
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 struct MockVad {
128 sample_rate: u32,
129 frame_size: usize,
130 call_count: usize,
131 }
132
133 impl MockVad {
134 fn new(sample_rate: u32, frame_size: usize) -> Self {
135 Self {
136 sample_rate,
137 frame_size,
138 call_count: 0,
139 }
140 }
141 }
142
143 impl VoiceActivityDetector for MockVad {
144 fn capabilities(&self) -> VadCapabilities {
145 VadCapabilities {
146 sample_rate: self.sample_rate,
147 frame_size: self.frame_size,
148 frame_duration_ms: (self.frame_size as u32 * 1000) / self.sample_rate,
149 }
150 }
151
152 fn process(&mut self, samples: &[i16], _sample_rate: u32) -> Result<f32, VadError> {
153 assert_eq!(samples.len(), self.frame_size);
154 self.call_count += 1;
155 Ok(0.5)
156 }
157
158 fn reset(&mut self) {
159 self.call_count = 0;
160 }
161 }
162
163 #[test]
164 fn test_adapter_buffers_samples() {
165 let mock = MockVad::new(16000, 512);
166 let mut adapter = FrameAdapter::new(Box::new(mock));
167
168 let result = adapter.process(&[0i16; 256], 16000).unwrap();
170 assert!(result.is_none());
171 assert_eq!(adapter.buffered_samples(), 256);
172
173 let result = adapter.process(&[0i16; 256], 16000).unwrap();
175 assert!(result.is_some());
176 assert_eq!(adapter.buffered_samples(), 0);
177 }
178
179 #[test]
180 fn test_adapter_handles_multiple_frames() {
181 let mock = MockVad::new(16000, 512);
182 let mut adapter = FrameAdapter::new(Box::new(mock));
183
184 let results = adapter.process_all(&[0i16; 1024], 16000).unwrap();
186 assert_eq!(results.len(), 2);
187 }
188
189 #[test]
190 fn test_adapter_wrong_sample_rate() {
191 let mock = MockVad::new(16000, 512);
192 let mut adapter = FrameAdapter::new(Box::new(mock));
193
194 let result = adapter.process(&[0i16; 512], 48000);
195 assert!(matches!(result, Err(VadError::InvalidSampleRate(48000))));
196 }
197
198 #[test]
199 fn test_adapter_reset() {
200 let mock = MockVad::new(16000, 512);
201 let mut adapter = FrameAdapter::new(Box::new(mock));
202
203 let _ = adapter.process(&[0i16; 256], 16000);
205 assert_eq!(adapter.buffered_samples(), 256);
206
207 adapter.reset();
209 assert_eq!(adapter.buffered_samples(), 0);
210 }
211
212 #[test]
213 fn test_process_latest() {
214 let mock = MockVad::new(16000, 512);
215 let mut adapter = FrameAdapter::new(Box::new(mock));
216
217 let result = adapter.process_latest(&[0i16; 1600], 16000).unwrap();
219 assert_eq!(result, 0.5); assert_eq!(adapter.buffered_samples(), 64); }
222}