const WINDOW: usize = 5;
pub struct MedianFilter {
buf: [u16; WINDOW],
pos: usize,
count: usize,
}
impl MedianFilter {
pub const fn new() -> Self {
Self {
buf: [0u16; WINDOW],
pos: 0,
count: 0,
}
}
pub fn update(&mut self, input: u16) -> u16 {
self.buf[self.pos] = input;
self.pos = (self.pos + 1) % WINDOW;
if self.count < WINDOW {
self.count += 1;
}
self.median()
}
fn median(&self) -> u16 {
let n = self.count;
let mut tmp = [0u16; WINDOW];
tmp[..n].copy_from_slice(&self.buf[..n]);
insertion_sort(&mut tmp[..n]);
tmp[n / 2]
}
pub fn reset(&mut self) {
self.buf = [0u16; WINDOW];
self.pos = 0;
self.count = 0;
}
}
impl Default for MedianFilter {
fn default() -> Self {
Self::new()
}
}
fn insertion_sort(arr: &mut [u16]) {
let n = arr.len();
for i in 1..n {
let key = arr[i];
let mut j = i;
while j > 0 && arr[j - 1] > key {
arr[j] = arr[j - 1];
j -= 1;
}
arr[j] = key;
}
}