1use crate::{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
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 struct MockVad {
123 sample_rate: u32,
124 frame_size: usize,
125 call_count: usize,
126 }
127
128 impl MockVad {
129 fn new(sample_rate: u32, frame_size: usize) -> Self {
130 Self {
131 sample_rate,
132 frame_size,
133 call_count: 0,
134 }
135 }
136 }
137
138 impl VoiceActivityDetector for MockVad {
139 fn capabilities(&self) -> VadCapabilities {
140 VadCapabilities {
141 sample_rate: self.sample_rate,
142 frame_size: self.frame_size,
143 frame_duration_ms: (self.frame_size as u32 * 1000) / self.sample_rate,
144 }
145 }
146
147 fn process(&mut self, samples: &[i16], _sample_rate: u32) -> Result<f32, VadError> {
148 assert_eq!(samples.len(), self.frame_size);
149 self.call_count += 1;
150 Ok(0.5)
151 }
152
153 fn reset(&mut self) {
154 self.call_count = 0;
155 }
156 }
157
158 #[test]
159 fn test_adapter_buffers_samples() {
160 let mock = MockVad::new(16000, 512);
161 let mut adapter = FrameAdapter::new(Box::new(mock));
162
163 let result = adapter.process(&[0i16; 256], 16000).unwrap();
165 assert!(result.is_none());
166 assert_eq!(adapter.buffered_samples(), 256);
167
168 let result = adapter.process(&[0i16; 256], 16000).unwrap();
170 assert!(result.is_some());
171 assert_eq!(adapter.buffered_samples(), 0);
172 }
173
174 #[test]
175 fn test_adapter_handles_multiple_frames() {
176 let mock = MockVad::new(16000, 512);
177 let mut adapter = FrameAdapter::new(Box::new(mock));
178
179 let results = adapter.process_all(&[0i16; 1024], 16000).unwrap();
181 assert_eq!(results.len(), 2);
182 }
183
184 #[test]
185 fn test_adapter_wrong_sample_rate() {
186 let mock = MockVad::new(16000, 512);
187 let mut adapter = FrameAdapter::new(Box::new(mock));
188
189 let result = adapter.process(&[0i16; 512], 48000);
190 assert!(matches!(result, Err(VadError::InvalidSampleRate(48000))));
191 }
192
193 #[test]
194 fn test_adapter_reset() {
195 let mock = MockVad::new(16000, 512);
196 let mut adapter = FrameAdapter::new(Box::new(mock));
197
198 let _ = adapter.process(&[0i16; 256], 16000);
200 assert_eq!(adapter.buffered_samples(), 256);
201
202 adapter.reset();
204 assert_eq!(adapter.buffered_samples(), 0);
205 }
206
207 #[test]
208 fn test_process_latest() {
209 let mock = MockVad::new(16000, 512);
210 let mut adapter = FrameAdapter::new(Box::new(mock));
211
212 let result = adapter.process_latest(&[0i16; 1600], 16000).unwrap();
214 assert_eq!(result, 0.5); assert_eq!(adapter.buffered_samples(), 64); }
217}