actually works now! maybe

This commit is contained in:
Ellie 2019-06-15 15:37:43 +00:00
parent 4a21613f42
commit b1d50fb611
1 changed files with 77 additions and 54 deletions

View File

@ -4,25 +4,56 @@ use std::io::prelude::*;
use std::fs::File;
use std::io;
static FILTER_STRENGTH:u8 = 10; // how severely to low-pass the incoming data
static RESET_THRESH:usize = 20; // this many samples with no bits = reset byte position
static FILTER_STRENGTH:u8 = 200; // how severely to low-pass the incoming data
static OVERSAMPLE_FACTOR:usize = 10; // how many samples long are each bit in the decoder input?
static INVERT:bool = false; // whether or not the source inverts the samples
struct StreamCoder {
encoder:[u16;256],
decoder:[u8;4096],
decoder:[Option<u8>;65536],
}
fn streamcoder_gen() -> StreamCoder {
let mut output_a:[u16;256] = [0x0000;256];
let mut output_b:[u8;4096] = [0x20;4096];
let mut output_b:[Option<u8>;65536] = [None;65536];
let mut a:u8 = 0;
let mut b:u16 = 0;
loop {
if b.count_ones() == b.count_zeros()-4 {
let mut score:i8 = 0;
let mut max_consec:u8 = 0;
let mut consec:u8 = 0;
let mut state:bool = false;
for i in 0..16 {
let thisbit = b & (0x01 << i) != 0x00;
if thisbit != state {
state = thisbit;
consec = 1;
} else {
consec += 1;
}
if consec > max_consec {
max_consec = consec;
}
if thisbit {
score += 1;
} else {
score -= 1;
}
}
let mut errors:[u16;16] = [0x0000;16];
let mut errorcollide:bool = false;
for i in 0..16 {
errors[i] = b ^ (0x01 << i);
if output_b[errors[i] as usize] != None {
errorcollide = true;
}
}
if score == 0 && max_consec <= 8 && !errorcollide {
output_a[a as usize] = b;
output_b[b as usize] = a;
output_b[b as usize] = Some(a);
for error in errors.iter() {
output_b[*error as usize] = Some(a);
}
if a == 0xFF {
break;
} else {
@ -37,9 +68,9 @@ fn streamcoder_gen() -> StreamCoder {
};
}
fn code_bits(n:u16) -> [bool;12] {
let mut output:[bool;12] = [false;12];
for i in 0..12 {
fn code_bits(n:u16) -> [bool;16] {
let mut output:[bool;16] = [false;16];
for i in 0..16 {
output[i] = (n >> i) & 0x01 == 0x01;
}
return output;
@ -47,10 +78,10 @@ fn code_bits(n:u16) -> [bool;12] {
fn bits_code(b:&[bool]) -> u16 {
let mut output:u16 = 0;
if b.len() < 12 {
if b.len() < 16 {
return 0;
}
for i in 0..12 {
for i in 0..16 {
if b[i] {
output += (0x01 << i) as u16;
}
@ -60,12 +91,15 @@ fn bits_code(b:&[bool]) -> u16 {
impl StreamCoder {
fn encode(&self,byte:u8) -> [bool;12] {
fn encode(&self,byte:u8) -> [bool;16] {
return code_bits(self.encoder[byte as usize]);
}
fn decode(&self,states:&[bool]) -> u8 {
return self.decoder[bits_code(states) as usize];
return match self.decoder[bits_code(states) as usize] {
None => 0x20,
Some(b) => b,
};
}
}
@ -118,14 +152,15 @@ fn main() {
},
Ok(_) => (),
};
let mut payload:Vec<u8> = Vec::with_capacity(16*OVERSAMPLE_FACTOR);
let mut payload:Vec<u8> = Vec::with_capacity(18*OVERSAMPLE_FACTOR);
let bits = coder.encode(ibuffer[0]);
for i in 0..12 {
for i in 0..16 {
payload.append(&mut match bits[i] {
true => vec![0xFF;OVERSAMPLE_FACTOR],
false => vec![0x00;OVERSAMPLE_FACTOR],
});
}
payload.append(&mut vec![0x80;OVERSAMPLE_FACTOR*2]);
match iooutput.write_all(&payload) {
Err(why) => {
eprintln!("write failed: {}",why);
@ -136,11 +171,11 @@ fn main() {
}
} else if mode == "d" {
let mut ibuffer:[u8;1] = [0x00];
let mut filterstate:u16 = 0x0000;
let mut filterstate:u16 = 0x0080;
let mut logicstate:i8 = 0;
let mut statecount:Option<(i8,usize)> = None;
let mut count:usize = 1;
let mut outbits:Vec<bool> = Vec::with_capacity(12);
let mut sampleclock:usize = 1;
let mut outbits:Vec<bool> = Vec::with_capacity(16);
let mut outbyte:Option<u8> = None;
loop {
match ioinput.read_exact(&mut ibuffer) {
Err(why) => match why.kind() {
@ -153,52 +188,40 @@ fn main() {
Ok(_) => (),
};
filterstate = filterstate*(FILTER_STRENGTH as u16)/0x00FF + ((0x00FF-FILTER_STRENGTH as u16)*ibuffer[0] as u16)/0x00FF;
if filterstate > 170 {
if logicstate == 1 {
count += 1;
} else {
statecount = Some((logicstate,count));
count = 1;
logicstate = 1;
}
} else if filterstate < 85 {
if logicstate == -1 {
count += 1;
} else {
statecount = Some((logicstate,count));
count = 1;
logicstate = -1;
}
} else {
if logicstate != 0 {
count = 1;
logicstate = 0;
}
statecount = Some((logicstate,count));
let newlogicstate = match (filterstate > 170,filterstate < 85) {
(true,false) => 1,
(false,true) => -1,
_ => 0,
};
if logicstate != newlogicstate {
sampleclock = OVERSAMPLE_FACTOR/5;
}
if let Some((state,n)) = statecount {
if state == 0 {
if n >= RESET_THRESH {
logicstate = newlogicstate;
if (sampleclock + OVERSAMPLE_FACTOR/2) % OVERSAMPLE_FACTOR == 0 {
match logicstate {
1 => outbits.push(true ^ INVERT),
-1 => outbits.push(false ^ INVERT),
_ => if outbits.len() > 0 {
outbyte = Some(0x20);
outbits.clear();
}
} else {
for _ in 0..(n+OVERSAMPLE_FACTOR/2)/OVERSAMPLE_FACTOR {
outbits.push((state > 0) ^ INVERT);
}
}
statecount = None;
},
};
}
if outbits.len() >= 12 {
let outbyte:u8 = coder.decode(&outbits);
if outbits.len() >= 16 {
outbyte = Some(coder.decode(&outbits));
outbits.clear();
match iooutput.write_all(&[outbyte]) {
}
if let Some(byte) = outbyte {
match iooutput.write_all(&[byte]) {
Err(why) => {
eprintln!("write failed: {}",why);
exit(1);
},
Ok(_) => (),
};
outbyte = None;
}
sampleclock += 1;
}
} else {
eprintln!("unknown mode operation `{}`",mode);