#[inline]
pub fn bit_reverse_8(i: u8) -> u8 {
let i64 = i as u64;
(((i64 * 0x8020_0802u64) & 0x0884_4221_10u64).wrapping_mul(0x0101_0101_01u64) >> 32) as u8
}
pub fn interleave_bitrev<T: Copy + Default, const FRAME: usize>(buf: &mut [T; FRAME]) {
let mut tmp = [T::default(); FRAME];
let mut p = 0usize;
let mut i: u32 = 0;
while p < FRAME {
let j = bit_reverse_8((i & 0xff) as u8) as usize;
if j < FRAME {
tmp[j] = buf[p];
p += 1;
}
i = i.wrapping_add(1);
}
*buf = tmp;
}
pub fn deinterleave_bitrev<T: Copy + Default, const FRAME: usize>(buf: &mut [T; FRAME]) {
let mut tmp = [T::default(); FRAME];
let mut p = 0usize;
let mut i: u32 = 0;
while p < FRAME {
let j = bit_reverse_8((i & 0xff) as u8) as usize;
if j < FRAME {
tmp[p] = buf[j];
p += 1;
}
i = i.wrapping_add(1);
}
*buf = tmp;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn round_trip_162() {
let mut bits = [0u8; 162];
for (i, b) in bits.iter_mut().enumerate() {
*b = ((i * 7 + 3) & 1) as u8;
}
let original = bits;
interleave_bitrev(&mut bits);
assert_ne!(bits, original, "permutation must change content");
deinterleave_bitrev(&mut bits);
assert_eq!(bits, original, "deinterleave must invert interleave");
}
#[test]
fn round_trip_206() {
let mut bits = [0u8; 206];
for (i, b) in bits.iter_mut().enumerate() {
*b = ((i * 11 + 5) & 1) as u8;
}
let original = bits;
interleave_bitrev(&mut bits);
assert_ne!(bits, original, "permutation must change content");
deinterleave_bitrev(&mut bits);
assert_eq!(bits, original, "deinterleave must invert interleave");
}
#[test]
fn llr_variant_round_trips() {
let mut llrs = [0f32; 162];
for (i, v) in llrs.iter_mut().enumerate() {
*v = if i % 3 == 0 { 4.0 } else { -4.0 };
}
let original = llrs;
interleave_bitrev(&mut llrs);
deinterleave_bitrev(&mut llrs);
assert_eq!(llrs, original);
}
}