const SYNC_LENGHT: usize = 40; const SYNCA_SEQ: [bool; 40] = [ false, false, false, false, true, true, false, false, // Pulse 1 true, true, false, false, // Pulse 2 true, true, false, false, // Pulse 3 true, true, false, false, // Pulse 4 true, true, false, false, // Pulse 5 true, true, false, false, // Pulse 6 true, true, false, false, // Pulse 7 false, false, false, false, false, false, false, false, ]; const SYNCB_SEQ: [bool; 40] = [ false, false, false, false, true, true, true, false, false, true, true, true, false, false, true, true, true, false, false, true, true, true, false, false, true, true, true, false, false, true, true, true, false, false, true, true, true, false, false, false, ]; pub enum SyncedSample { Sample(f32), SyncA(f32), SyncB(f32), } pub struct APTSyncer<'a> { state: [f32; SYNC_LENGHT], pos: usize, nones_read: usize, avg_level: f32, iterator: Box + 'a>, } impl<'a> APTSyncer<'a> { pub fn from(mut iterator: I) -> APTSyncer<'a> where I: Iterator + 'a, { let mut state = [0.0; SYNC_LENGHT]; let mut avg_level = 0.5; for i in 0..SYNC_LENGHT { match iterator.next() { Some(x) => { state[i] = x; avg_level = 0.25 * x + avg_level * 0.75; } None => panic!("Could not retrieve enough samples to prime syncer"), } } APTSyncer { state, pos: 0, nones_read: 0, avg_level, iterator: Box::new(iterator), } } fn is_marker(&mut self) -> (bool, bool) { let mut count_a = 0; let mut count_b = 0; for i in 0..SYNC_LENGHT { let sync_pos = (self.pos + i) % SYNC_LENGHT; let sample = self.state[sync_pos] / (self.avg_level * 2.0); if (sample > 0.5 && SYNCA_SEQ[i]) || (sample <= 0.5 && !SYNCA_SEQ[i]) { count_a += 1; } if (sample > 0.5 && SYNCB_SEQ[i]) || (sample <= 0.5 && !SYNCB_SEQ[i]) { count_b += 1; } /* if !count_a && !count_b { break; } */ } return (count_a > 35, count_b > 35); } } impl<'a> Iterator for APTSyncer<'a> { type Item = SyncedSample; fn next(&mut self) -> Option { let (is_a, is_b) = self.is_marker(); let sample = self.state[self.pos]; match self.iterator.next() { Some(x) => { self.state[self.pos] = x; self.avg_level = 0.25 * x + self.avg_level * 0.75; } None => self.nones_read += 1, }; if self.nones_read >= SYNC_LENGHT { return None; } self.pos = (self.pos + 1) % SYNC_LENGHT; if is_a { return Some(SyncedSample::SyncA(sample)); } else if is_b { return Some(SyncedSample::SyncB(sample)); } else { return Some(SyncedSample::Sample(sample)); } } }