use {Code, CodeType, b3, b1};
pub trait Encoder {
fn encode(&self, signal: &Vec<b1>) -> Vec<b1>;
}
impl Encoder for Code {
fn encode(&self, signal: &Vec<b1>) -> Vec<b1> {
match self.code_type {
CodeType::FIRCode => encode_fir(self, signal),
CodeType::IIRCode => encode_iir(self, signal)
}
}
}
fn encode_fir(code: &Code, signal: &Vec<b1>) -> Vec<b1> {
signal.iter().scan(code.start_state.clone(), |state, sig_bit| {
state.push(*sig_bit);
let adder_outputs: Vec<_> =
code.polys.iter().map(|code_poly| {
poly_add(*code_poly, &state)
}).collect();
state.remove(0);
Some(adder_outputs)
}).flat_map(|x| x).collect()
}
fn encode_iir(code: &Code, signal: &Vec<b1>) -> Vec<b1> {
signal.iter().scan(code.start_state.clone(), |state, sig_bit| {
state.push(*sig_bit);
let adder_outputs: Vec<_> =
code.polys.iter().map(|code_poly| {
poly_add(*code_poly, &state)
}).collect();
state.pop();
for out_ind in 0..(adder_outputs.len()) {
state.remove(0);
state.push(adder_outputs[out_ind]);
}
Some(adder_outputs)
}).flat_map(|x| x).collect()
}
fn poly_add(code_vec: b3, sig_arr: &[b1]) -> b1 {
sig_arr.iter().rev().zip(code_vec.bits().iter())
.map(|(&sig, &code)| sig & code)
.fold(b1(false), |accum, val| accum ^ val)
}