2016-11-26 00:12:10 +01:00
|
|
|
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> {
|
2016-11-28 09:33:00 +01:00
|
|
|
state: [f32; SYNC_LENGHT],
|
2016-11-26 00:12:10 +01:00
|
|
|
pos : usize,
|
|
|
|
nones_read: usize,
|
2017-12-31 01:13:44 +01:00
|
|
|
avg_level : f32,
|
2016-11-26 00:12:10 +01:00
|
|
|
iterator: Box<Iterator<Item=f32> + 'a>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> APTSyncer<'a> {
|
|
|
|
pub fn from<I>(mut iterator: I) -> APTSyncer<'a> where I: Iterator<Item=f32> + 'a {
|
2016-11-28 09:33:00 +01:00
|
|
|
let mut state = [0.0; SYNC_LENGHT];
|
2017-12-31 01:13:44 +01:00
|
|
|
let mut avg_level = 0.5;
|
2016-11-28 09:33:00 +01:00
|
|
|
for i in 0..SYNC_LENGHT {
|
2016-11-26 00:12:10 +01:00
|
|
|
match iterator.next() {
|
|
|
|
Some(x) => {
|
2016-11-28 09:33:00 +01:00
|
|
|
state[i] = x;
|
2017-12-31 01:13:44 +01:00
|
|
|
avg_level = 0.25 * x + avg_level * 0.75;
|
2016-11-26 00:12:10 +01:00
|
|
|
},
|
|
|
|
None => panic!("Could not retrieve enough samples to prime syncer")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
APTSyncer {
|
|
|
|
state: state,
|
|
|
|
pos: 0,
|
|
|
|
nones_read: 0,
|
2017-12-31 01:13:44 +01:00
|
|
|
avg_level: avg_level,
|
2016-11-26 00:12:10 +01:00
|
|
|
iterator: Box::new(iterator)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-28 09:33:00 +01:00
|
|
|
fn is_marker(&mut self) -> (bool, bool) {
|
2017-12-30 21:49:36 +01:00
|
|
|
let mut count_a = 0;
|
|
|
|
let mut count_b = 0;
|
|
|
|
|
2016-11-26 00:12:10 +01:00
|
|
|
for i in 0..SYNC_LENGHT {
|
|
|
|
let sync_pos = (self.pos + i) % SYNC_LENGHT;
|
2017-12-31 01:13:44 +01:00
|
|
|
let sample = self.state[sync_pos] / (self.avg_level * 2.0);
|
2017-12-30 21:49:36 +01:00
|
|
|
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;
|
|
|
|
}
|
2016-11-28 09:33:00 +01:00
|
|
|
|
2017-12-30 21:49:36 +01:00
|
|
|
/*
|
|
|
|
if !count_a && !count_b {
|
2016-11-28 09:33:00 +01:00
|
|
|
break;
|
2016-11-26 00:12:10 +01:00
|
|
|
}
|
2017-12-30 21:49:36 +01:00
|
|
|
*/
|
2016-11-26 00:12:10 +01:00
|
|
|
}
|
|
|
|
|
2017-12-30 21:49:36 +01:00
|
|
|
return (count_a > 35, count_b > 35);
|
2016-11-26 00:12:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Iterator for APTSyncer<'a> {
|
|
|
|
type Item = SyncedSample;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
|
2016-11-28 09:33:00 +01:00
|
|
|
let (is_a, is_b) = self.is_marker();
|
2016-11-26 00:12:10 +01:00
|
|
|
|
|
|
|
let sample = self.state[self.pos];
|
|
|
|
match self.iterator.next() {
|
|
|
|
Some(x) => {
|
|
|
|
self.state[self.pos] = x;
|
2017-12-31 01:13:44 +01:00
|
|
|
self.avg_level = 0.25 * x + self.avg_level * 0.75;
|
2016-11-26 00:12:10 +01:00
|
|
|
},
|
|
|
|
None => self.nones_read += 1
|
|
|
|
};
|
2016-11-28 09:33:00 +01:00
|
|
|
|
2016-11-26 00:12:10 +01:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|