initial commit
Signed-off-by: Kamal Tufekcic <kamal@lo.sh>
This commit is contained in:
commit
7862cb1d9d
2884 changed files with 16797 additions and 0 deletions
103
tests/determinism.rs
Normal file
103
tests/determinism.rs
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
//! Determinism fence: the encoder is contractually bit-exact on the
|
||||
//! same input, and the decoder is contractually bit-exact on the same
|
||||
//! bitstream. This file exists to catch a future change that would
|
||||
//! quietly break either property — a parallel order search with a
|
||||
//! race, a `HashMap` iteration order leaking into state, a
|
||||
//! non-deterministic tie-break. All three would pass the round-trip
|
||||
//! tests but fail here.
|
||||
//!
|
||||
//! Tests drive small deterministic inputs (LFSR noise, sine) so they
|
||||
//! don't depend on corpus presence and run in milliseconds.
|
||||
|
||||
use lac::{decode_frame, encode_frame};
|
||||
|
||||
// ── Deterministic inputs ────────────────────────────────────────────────────
|
||||
|
||||
/// 32-bit Galois LFSR, mirrored from `tests/synthetic.rs`. Seeded
|
||||
/// deterministically so repeated calls with the same `seed` produce
|
||||
/// bit-identical outputs, which is the property we rely on below.
|
||||
fn lfsr_noise(n: usize, bit_depth: u8, seed: u32) -> Vec<i32> {
|
||||
assert!((1..=24).contains(&bit_depth));
|
||||
let mut state = if seed == 0 { 0xACE1_ACE1 } else { seed };
|
||||
let shift = 32 - bit_depth as u32;
|
||||
let max: i32 = (1i32 << (bit_depth - 1)) - 1;
|
||||
(0..n)
|
||||
.map(|_| {
|
||||
let lsb = state & 1;
|
||||
state >>= 1;
|
||||
if lsb != 0 {
|
||||
state ^= 0x8020_0003;
|
||||
}
|
||||
((state as i32) >> shift).max(-max)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
// ── Tests ───────────────────────────────────────────────────────────────────
|
||||
|
||||
#[test]
|
||||
fn encode_byte_equal_on_same_input_silence() {
|
||||
let samples = vec![0i32; 4096];
|
||||
let a = encode_frame(&samples);
|
||||
let b = encode_frame(&samples);
|
||||
assert_eq!(a, b, "encoder produced different bytes for identical input");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encode_byte_equal_on_same_input_noise() {
|
||||
// 16-bit noise — exercises the non-trivial LPC/Rice search path
|
||||
// where any latent non-determinism (tie-break, parallelism, hash
|
||||
// ordering) would be most likely to surface.
|
||||
let samples = lfsr_noise(4096, 16, 0xDEAD);
|
||||
let a = encode_frame(&samples);
|
||||
let b = encode_frame(&samples);
|
||||
assert_eq!(
|
||||
a,
|
||||
b,
|
||||
"encoder produced different bytes on a noisy input (first {} bytes)",
|
||||
a.len().min(16)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encode_byte_equal_on_same_input_24bit_full_scale() {
|
||||
// Full-scale content stresses the autocorrelation accumulator
|
||||
// width; any non-determinism in coefficient quantization would
|
||||
// show up differently from the silence and noise cases.
|
||||
let samples = vec![(1 << 23) - 1; 2048];
|
||||
let a = encode_frame(&samples);
|
||||
let b = encode_frame(&samples);
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encode_byte_equal_across_many_repeats() {
|
||||
// Ten encodes of the same input — catches an intermittent race
|
||||
// that a two-shot comparison might miss by luck. LFSR seed chosen
|
||||
// independently from the other tests to reduce correlation
|
||||
// between failure modes.
|
||||
let samples = lfsr_noise(2048, 20, 0xBEEF);
|
||||
let reference = encode_frame(&samples);
|
||||
for i in 1..10 {
|
||||
let current = encode_frame(&samples);
|
||||
assert_eq!(
|
||||
current, reference,
|
||||
"encode #{} differs from the reference encode",
|
||||
i
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_byte_equal_on_same_input() {
|
||||
// Decoder determinism: same bitstream, same samples, every time.
|
||||
let samples = lfsr_noise(2048, 16, 0xF00D);
|
||||
let bytes = encode_frame(&samples);
|
||||
let a = decode_frame(&bytes).expect("decode a");
|
||||
let b = decode_frame(&bytes).expect("decode b");
|
||||
assert_eq!(
|
||||
a, b,
|
||||
"decoder produced different samples for identical bytes"
|
||||
);
|
||||
assert_eq!(a, samples, "decoder output doesn't match original samples");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue