#![allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
#![allow(unsafe_code)]
pub const HIGH_LEVEL: i16 = i16::MAX;
pub const LOW_LEVEL: i16 = i16::MIN;
pub fn manchester_encode_simd(bits: &[u8]) -> Vec<i16> {
#[cfg(target_arch = "x86_64")]
{
if is_x86_feature_detected!("avx2") {
return manchester_encode_avx2(bits);
}
}
manchester_encode_scalar(bits)
}
pub fn manchester_encode_scalar(bits: &[u8]) -> Vec<i16> {
let mut out = Vec::with_capacity(bits.len() * 2);
for &b in bits {
if b == 0 {
out.push(HIGH_LEVEL);
out.push(LOW_LEVEL);
} else {
out.push(LOW_LEVEL);
out.push(HIGH_LEVEL);
}
}
out
}
#[cfg(target_arch = "x86_64")]
fn manchester_encode_avx2(bits: &[u8]) -> Vec<i16> {
use std::arch::x86_64::*;
let mut out = Vec::with_capacity(bits.len() * 2);
let chunks = bits.chunks_exact(32);
let remainder = chunks.remainder();
for chunk in chunks {
unsafe {
let v = _mm256_loadu_si256(chunk.as_ptr().cast::<__m256i>());
let zero = _mm256_setzero_si256();
let all_ones = _mm256_set1_epi8(-1_i8);
let nonzero_mask: u32 =
_mm256_movemask_epi8(_mm256_andnot_si256(_mm256_cmpeq_epi8(v, zero), all_ones))
as u32;
for lane in 0..32usize {
let is_one = (nonzero_mask >> lane) & 1;
if is_one == 0 {
out.push(HIGH_LEVEL);
out.push(LOW_LEVEL);
} else {
out.push(LOW_LEVEL);
out.push(HIGH_LEVEL);
}
}
}
}
for &b in remainder {
if b == 0 {
out.push(HIGH_LEVEL);
out.push(LOW_LEVEL);
} else {
out.push(LOW_LEVEL);
out.push(HIGH_LEVEL);
}
}
out
}
pub fn manchester_decode_simd(samples: &[i16], threshold: i16) -> Vec<u8> {
#[cfg(target_arch = "x86_64")]
{
if is_x86_feature_detected!("avx2") {
return manchester_decode_avx2(samples, threshold);
}
}
manchester_decode_scalar(samples, threshold)
}
pub fn manchester_decode_scalar(samples: &[i16], threshold: i16) -> Vec<u8> {
let mut out = Vec::with_capacity(samples.len() / 2);
let mut i = 0;
while i + 1 < samples.len() {
let first = samples[i];
let second = samples[i + 1];
let first_positive = first >= threshold;
let first_negative = first <= -threshold;
let second_positive = second >= threshold;
let second_negative = second <= -threshold;
let bit = if first_positive && second_negative {
0u8
} else if first_negative && second_positive {
1u8
} else {
if first.unsigned_abs() >= second.unsigned_abs() {
if first >= 0 {
0u8 } else {
1u8 }
} else {
if second >= 0 {
1u8 } else {
0u8 }
}
};
out.push(bit);
i += 2;
}
out
}
#[cfg(target_arch = "x86_64")]
fn manchester_decode_avx2(samples: &[i16], threshold: i16) -> Vec<u8> {
use std::arch::x86_64::*;
let mut out = Vec::with_capacity(samples.len() / 2);
let pair_count = samples.len() / 2;
let avx_pairs_per_iter = 16usize;
let full_iters = pair_count / avx_pairs_per_iter;
let remainder_start = full_iters * avx_pairs_per_iter * 2;
unsafe {
let thresh_vec = _mm256_set1_epi16(threshold);
let neg_thresh_vec = _mm256_set1_epi16(-threshold);
let mask_lo16 = _mm256_set1_epi32(0x0000_FFFF_u32 as i32);
let thresh_m1 = _mm256_sub_epi16(thresh_vec, _mm256_set1_epi16(1));
let neg_thresh_m1 = _mm256_sub_epi16(neg_thresh_vec, _mm256_set1_epi16(1));
for iter in 0..full_iters {
let base = iter * avx_pairs_per_iter * 2;
let raw_lo = _mm256_loadu_si256(samples[base..].as_ptr().cast::<__m256i>());
let raw_hi = _mm256_loadu_si256(samples[base + 16..].as_ptr().cast::<__m256i>());
let firsts_lo = _mm256_and_si256(raw_lo, mask_lo16);
let firsts_hi = _mm256_and_si256(raw_hi, mask_lo16);
let seconds_lo = _mm256_srli_epi32(raw_lo, 16);
let seconds_hi = _mm256_srli_epi32(raw_hi, 16);
let first_high_lo = _mm256_cmpgt_epi16(firsts_lo, thresh_m1);
let first_high_hi = _mm256_cmpgt_epi16(firsts_hi, thresh_m1);
let second_low_lo = _mm256_cmpgt_epi16(neg_thresh_m1, seconds_lo);
let second_low_hi = _mm256_cmpgt_epi16(neg_thresh_m1, seconds_hi);
let bit0_lo = _mm256_and_si256(first_high_lo, second_low_lo);
let bit0_hi = _mm256_and_si256(first_high_hi, second_low_hi);
let bits_lo: u32 = _mm256_movemask_epi8(bit0_lo) as u32;
let bits_hi: u32 = _mm256_movemask_epi8(bit0_hi) as u32;
for k in 0..8usize {
let is_bit0 = (bits_lo >> (k * 4)) & 1;
out.push(if is_bit0 != 0 { 0u8 } else { 1u8 });
}
for k in 0..8usize {
let is_bit0 = (bits_hi >> (k * 4)) & 1;
out.push(if is_bit0 != 0 { 0u8 } else { 1u8 });
}
}
}
out.extend(manchester_decode_scalar(
&samples[remainder_start..],
threshold,
));
out
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_encode_zero_bit() {
let encoded = manchester_encode_scalar(&[0]);
assert_eq!(encoded.len(), 2);
assert_eq!(encoded[0], HIGH_LEVEL, "bit 0: first sample should be HIGH");
assert_eq!(encoded[1], LOW_LEVEL, "bit 0: second sample should be LOW");
}
#[test]
fn test_encode_one_bit() {
let encoded = manchester_encode_scalar(&[1]);
assert_eq!(encoded.len(), 2);
assert_eq!(encoded[0], LOW_LEVEL, "bit 1: first sample should be LOW");
assert_eq!(
encoded[1], HIGH_LEVEL,
"bit 1: second sample should be HIGH"
);
}
#[test]
fn test_encode_empty() {
let encoded = manchester_encode_scalar(&[]);
assert!(encoded.is_empty());
}
#[test]
fn test_encode_zero_stream() {
let bits: Vec<u8> = vec![0; 8];
let encoded = manchester_encode_scalar(&bits);
assert_eq!(encoded.len(), 16);
for i in 0..8 {
assert_eq!(encoded[i * 2], HIGH_LEVEL, "bit {i}: first must be HIGH");
assert_eq!(encoded[i * 2 + 1], LOW_LEVEL, "bit {i}: second must be LOW");
}
}
#[test]
fn test_encode_256_random_roundtrip_scalar() {
let bits: Vec<u8> = (0u32..256)
.map(|i| ((i.wrapping_mul(2654435761) >> 16) & 1) as u8)
.collect();
let encoded = manchester_encode_scalar(&bits);
let decoded = manchester_decode_scalar(&encoded, HIGH_LEVEL / 2);
assert_eq!(decoded.len(), bits.len());
for (i, (&orig, &dec)) in bits.iter().zip(decoded.iter()).enumerate() {
assert_eq!(orig, dec, "round-trip mismatch at bit {i}");
}
}
#[test]
fn test_encode_simd_matches_scalar() {
let bits: Vec<u8> = (0u8..255).collect(); let scalar = manchester_encode_scalar(&bits);
let simd = manchester_encode_simd(&bits);
assert_eq!(scalar, simd, "SIMD encode must match scalar encode");
}
#[test]
fn test_decode_zero_bit() {
let samples = [HIGH_LEVEL, LOW_LEVEL];
let decoded = manchester_decode_scalar(&samples, HIGH_LEVEL / 2);
assert_eq!(decoded, vec![0u8]);
}
#[test]
fn test_decode_one_bit() {
let samples = [LOW_LEVEL, HIGH_LEVEL];
let decoded = manchester_decode_scalar(&samples, HIGH_LEVEL / 2);
assert_eq!(decoded, vec![1u8]);
}
#[test]
fn test_decode_empty() {
let decoded = manchester_decode_scalar(&[], 1000);
assert!(decoded.is_empty());
}
#[test]
fn test_decode_odd_length_ignores_tail() {
let samples = [HIGH_LEVEL, LOW_LEVEL, HIGH_LEVEL]; let decoded = manchester_decode_scalar(&samples, HIGH_LEVEL / 2);
assert_eq!(decoded.len(), 1);
assert_eq!(decoded[0], 0);
}
#[test]
fn test_decode_simd_matches_scalar() {
let bits: Vec<u8> = (0u8..255).map(|b| b & 1).collect();
let samples = manchester_encode_scalar(&bits);
let scalar = manchester_decode_scalar(&samples, HIGH_LEVEL / 2);
let simd = manchester_decode_simd(&samples, HIGH_LEVEL / 2);
assert_eq!(scalar, simd, "SIMD decode must match scalar decode");
}
#[test]
fn test_encode_decode_256_random_simd_roundtrip() {
let bits: Vec<u8> = (0u64..256)
.map(|i| {
let hash = i
.wrapping_mul(6364136223846793005_u64)
.wrapping_add(1442695040888963407_u64);
((hash >> 32) & 1) as u8
})
.collect();
let encoded = manchester_encode_simd(&bits);
let decoded = manchester_decode_simd(&encoded, HIGH_LEVEL / 2);
assert_eq!(decoded.len(), bits.len());
for (i, (&orig, &dec)) in bits.iter().zip(decoded.iter()).enumerate() {
assert_eq!(orig, dec, "SIMD round-trip mismatch at bit {i}");
}
}
}