pub const MULAW_BIAS: i32 = 0x84;
pub const fn mulaw_decode(b: u8) -> i16 {
let inv = !b;
let sign = inv & 0x80;
let exp = ((inv >> 4) & 0x07) as u32;
let mant = (inv & 0x0F) as i32;
let mag = (((mant << 3) + MULAW_BIAS) << exp) - MULAW_BIAS;
if sign == 0 {
mag as i16
} else {
(-mag) as i16
}
}
pub const MULAW_DECODE: [i16; 256] = {
let mut t = [0i16; 256];
let mut i = 0;
while i < 256 {
t[i] = mulaw_decode(i as u8);
i += 1;
}
t
};
pub const ALAW_XOR: u8 = 0x55;
pub const fn alaw_decode(b: u8) -> i16 {
let inv = b ^ ALAW_XOR;
let sign = inv & 0x80;
let exp = ((inv >> 4) & 0x07) as u32;
let mant = (inv & 0x0F) as i32;
let mag = if exp == 0 {
(mant << 4) + 8
} else {
((mant << 4) + 0x108) << (exp - 1)
};
if sign != 0 {
mag as i16
} else {
(-mag) as i16
}
}
pub const ALAW_DECODE: [i16; 256] = {
let mut t = [0i16; 256];
let mut i = 0;
while i < 256 {
t[i] = alaw_decode(i as u8);
i += 1;
}
t
};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn mulaw_endpoints() {
assert_eq!(MULAW_DECODE[0xFF], 0);
assert_eq!(MULAW_DECODE[0x7F], 0);
assert_eq!(MULAW_DECODE[0x00], -(MULAW_DECODE[0x80] as i32) as i16);
}
#[test]
fn mulaw_symmetry() {
for b in 0u8..=255 {
let a = MULAW_DECODE[b as usize] as i32;
let c = MULAW_DECODE[(b ^ 0x80) as usize] as i32;
assert_eq!(a, -c, "mu-law symmetry failed for byte {:#x}", b);
}
}
#[test]
fn alaw_symmetry() {
for b in 0u8..=255 {
let a = ALAW_DECODE[b as usize] as i32;
let c = ALAW_DECODE[(b ^ 0x80) as usize] as i32;
assert_eq!(a, -c, "A-law symmetry failed for byte {:#x}", b);
}
}
#[test]
fn alaw_zero_code() {
assert_eq!(ALAW_DECODE[0xD5], 8);
assert_eq!(ALAW_DECODE[0x55], -8);
}
}