use std::sync::OnceLock;
use crate::frame::{BlockType, GranuleSideInfo, GRANULE_LINES};
use crate::header::FrameHeader;
use super::psychoacoustic::PsyResult;
pub const MAX_LEVEL: i32 = 8206;
pub const QUANT_BIAS: f64 = 0.0946;
pub fn requant_magnitude(level: i32) -> f64 {
static T: OnceLock<Vec<f64>> = OnceLock::new();
let t = T.get_or_init(|| {
(0..=MAX_LEVEL as usize)
.map(|i| (i as f64).powf(4.0 / 3.0))
.collect()
});
let a = level.unsigned_abs() as usize;
t.get(a)
.copied()
.unwrap_or_else(|| (a as f64).powf(4.0 / 3.0))
}
#[must_use]
pub fn quantize_level(xr: f64) -> i32 {
level_from(xr.abs().powf(0.75))
}
#[inline]
pub(crate) fn level_from(powered: f64) -> i32 {
let m = powered - QUANT_BIAS;
(m.clamp(0.0, f64::from(MAX_LEVEL)) + 0.5) as i32
}
#[must_use]
pub fn xrpow(freq: &[f32; GRANULE_LINES]) -> [f64; GRANULE_LINES] {
let mut p = [0f64; GRANULE_LINES];
if xrpow_use_powf() {
for (pi, &f) in p.iter_mut().zip(freq.iter()) {
*pi = f64::from(f.abs()).powf(0.75); }
} else {
for (pi, &f) in p.iter_mut().zip(freq.iter()) {
let a = f64::from(f.abs());
*pi = (a * a.sqrt()).sqrt();
}
}
p
}
fn xrpow_use_powf() -> bool {
static USE_POWF: OnceLock<bool> = OnceLock::new();
*USE_POWF.get_or_init(|| std::env::var("RFF_MP3_XRPOW").is_ok_and(|v| v == "powf"))
}
#[derive(Debug, Clone)]
pub struct QuantizedGranule {
pub coeffs: [i32; GRANULE_LINES],
pub side: GranuleSideInfo,
pub scalefactors: [u8; 39],
}
impl Default for QuantizedGranule {
fn default() -> Self {
Self {
coeffs: [0; GRANULE_LINES],
side: GranuleSideInfo::default(),
scalefactors: [0; 39],
}
}
}
fn sf_step_lut() -> &'static [f64; 256] {
static T: OnceLock<[f64; 256]> = OnceLock::new();
T.get_or_init(|| {
let mut t = [0f64; 256];
for (s, v) in t.iter_mut().enumerate() {
*v = 2f64.powf(0.75 * SF_MULT * s as f64);
}
t
})
}
fn sf_inv_lut() -> &'static [f64; 256] {
static T: OnceLock<[f64; 256]> = OnceLock::new();
T.get_or_init(|| {
let mut t = [0f64; 256];
for (s, v) in t.iter_mut().enumerate() {
*v = 2f64.powf(-SF_MULT * s as f64);
}
t
})
}
const MAX_UNCLIPPED: i32 = 8191;
const SF_MULT: f64 = 0.5;
const MAX_SF: u8 = 15;
#[inline]
fn max_sf(b: usize) -> u8 {
if b < 11 {
MAX_SF
} else {
7
}
}
const MAX_OUTER: usize = 24;
fn quantize_with_sf(
header: &FrameHeader,
freq: &[f32; GRANULE_LINES],
xrp: &[f64; GRANULE_LINES],
gain: i32,
sf: &[u8; 22],
) -> [i32; GRANULE_LINES] {
let mut out = [0i32; GRANULE_LINES];
quantize_into(header, freq, xrp, gain, sf, &mut out);
out
}
fn quantize_into(
header: &FrameHeader,
freq: &[f32; GRANULE_LINES],
xrp: &[f64; GRANULE_LINES],
gain: i32,
sf: &[u8; 22],
out: &mut [i32; GRANULE_LINES],
) {
let off = crate::tables::sfb_long_offsets(header.sample_rate);
let base = -0.25 * f64::from(gain - 210);
let step_base = 2f64.powf(0.75 * base);
let sf_step = sf_step_lut();
let mut sfx = *sf;
sfx[21] = 0;
let mut steps = [0f64; 22];
for b in 0..22 {
let s = sfx[b];
steps[b] = step_base * sf_step[s as usize];
}
let simd = crate::decode::isa::use_simd();
if simd {
unsafe { quantize_lines_simd(off, &steps, freq, xrp, out) };
} else {
quantize_lines_scalar(off, &steps, freq, xrp, out);
}
super::prof::QUANT_CALLS[usize::from(simd)].fetch_add(1, std::sync::atomic::Ordering::Relaxed);
}
#[inline]
fn quantize_lines_scalar(
off: &[u16; 23],
steps: &[f64; 22],
freq: &[f32; GRANULE_LINES],
xrp: &[f64; GRANULE_LINES],
out: &mut [i32; GRANULE_LINES],
) {
for b in 0..22 {
let step = steps[b];
let (lo, hi) = (off[b] as usize, (off[b + 1] as usize).min(GRANULE_LINES));
for i in lo..hi {
let mag = level_from(xrp[i] * step);
out[i] = if freq[i] < 0.0 { -mag } else { mag };
}
}
}
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "avx")]
unsafe fn quantize_lines_avx(
off: &[u16; 23],
steps: &[f64; 22],
freq: &[f32; GRANULE_LINES],
xrp: &[f64; GRANULE_LINES],
out: &mut [i32; GRANULE_LINES],
) {
use std::arch::x86_64::*;
let (bias, zero, max, half) = (
_mm256_set1_pd(QUANT_BIAS),
_mm256_setzero_pd(),
_mm256_set1_pd(f64::from(MAX_LEVEL)),
_mm256_set1_pd(0.5),
);
let fzero = _mm_setzero_ps();
for b in 0..22 {
let (lo, hi) = (off[b] as usize, (off[b + 1] as usize).min(GRANULE_LINES));
let vstep = _mm256_set1_pd(steps[b]);
let mut i = lo;
while i + 4 <= hi {
unsafe {
let p = _mm256_mul_pd(_mm256_loadu_pd(xrp.as_ptr().add(i)), vstep);
let m = _mm256_sub_pd(p, bias);
let c = _mm256_min_pd(_mm256_max_pd(m, zero), max);
let mag = _mm256_cvttpd_epi32(_mm256_add_pd(c, half));
let neg = _mm_castps_si128(_mm_cmplt_ps(_mm_loadu_ps(freq.as_ptr().add(i)), fzero));
let q = _mm_sub_epi32(_mm_xor_si128(mag, neg), neg);
#[allow(clippy::cast_ptr_alignment)]
_mm_storeu_si128(out.as_mut_ptr().add(i).cast::<__m128i>(), q);
}
i += 4;
}
let step = steps[b];
while i < hi {
let mag = level_from(xrp[i] * step);
out[i] = if freq[i] < 0.0 { -mag } else { mag };
i += 1;
}
}
}
#[cfg(target_arch = "aarch64")]
unsafe fn quantize_lines_neon(
off: &[u16; 23],
steps: &[f64; 22],
freq: &[f32; GRANULE_LINES],
xrp: &[f64; GRANULE_LINES],
out: &mut [i32; GRANULE_LINES],
) {
use std::arch::aarch64::*;
unsafe {
let (bias, zero, max, half) = (
vdupq_n_f64(QUANT_BIAS),
vdupq_n_f64(0.0),
vdupq_n_f64(MAX_LEVEL as f64),
vdupq_n_f64(0.5),
);
for b in 0..22 {
let (lo, hi) = (off[b] as usize, (off[b + 1] as usize).min(GRANULE_LINES));
let vstep = vdupq_n_f64(steps[b]);
let mut i = lo;
while i + 2 <= hi {
let p = vmulq_f64(vld1q_f64(xrp.as_ptr().add(i)), vstep);
let c = vminq_f64(vmaxq_f64(vsubq_f64(p, bias), zero), max);
let mag = vmovn_s64(vcvtq_s64_f64(vaddq_f64(c, half)));
let neg =
vreinterpret_s32_u32(vclt_f32(vld1_f32(freq.as_ptr().add(i)), vdup_n_f32(0.0)));
let q = vsub_s32(veor_s32(mag, neg), neg);
vst1_s32(out.as_mut_ptr().add(i), q);
i += 2;
}
let step = steps[b];
while i < hi {
let mag = level_from(xrp[i] * step);
out[i] = if freq[i] < 0.0 { -mag } else { mag };
i += 1;
}
}
}
}
#[inline]
unsafe fn quantize_lines_simd(
off: &[u16; 23],
steps: &[f64; 22],
freq: &[f32; GRANULE_LINES],
xrp: &[f64; GRANULE_LINES],
out: &mut [i32; GRANULE_LINES],
) {
#[cfg(target_arch = "x86_64")]
unsafe {
quantize_lines_avx(off, steps, freq, xrp, out);
}
#[cfg(target_arch = "aarch64")]
unsafe {
quantize_lines_neon(off, steps, freq, xrp, out)
}
#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
quantize_lines_scalar(off, steps, freq, xrp, out)
}
fn quantize_band_in_place(
header: &FrameHeader,
freq: &[f32; GRANULE_LINES],
xrp: &[f64; GRANULE_LINES],
gain: i32,
sf_b: u8,
b: usize,
coeffs: &mut [i32; GRANULE_LINES],
) {
let off = crate::tables::sfb_long_offsets(header.sample_rate);
let base = -0.25 * f64::from(gain - 210);
let s = f64::from(if b < 21 { sf_b } else { 0 });
let step = 2f64.powf(0.75 * (base + SF_MULT * s));
let (lo, hi) = (off[b] as usize, (off[b + 1] as usize).min(GRANULE_LINES));
for i in lo..hi {
let mag = level_from(xrp[i] * step);
coeffs[i] = if freq[i] < 0.0 { -mag } else { mag };
}
}
fn band_noise_one(
header: &FrameHeader,
freq: &[f32; GRANULE_LINES],
coeffs: &[i32; GRANULE_LINES],
gain: i32,
sf_b: u8,
b: usize,
) -> f32 {
let off = crate::tables::sfb_long_offsets(header.sample_rate);
let scale = 2f64.powf(0.25 * f64::from(gain - 210)) * sf_inv_lut()[sf_b as usize];
let (lo, hi) = (off[b] as usize, (off[b + 1] as usize).min(GRANULE_LINES));
let mut e = 0f64;
for i in lo..hi {
let xr = f64::from(coeffs[i].signum()) * requant_magnitude(coeffs[i]) * scale;
let d = f64::from(freq[i]) - xr;
e += d * d;
}
e as f32
}
fn band_noise(
header: &FrameHeader,
freq: &[f32; GRANULE_LINES],
coeffs: &[i32; GRANULE_LINES],
gain: i32,
sf: &[u8; 22],
) -> [f32; 21] {
let off = crate::tables::sfb_long_offsets(header.sample_rate);
let mut noise = [0f32; 21];
let scale_base = 2f64.powf(0.25 * f64::from(gain - 210));
let sf_inv = sf_inv_lut();
for (b, n) in noise.iter_mut().enumerate() {
let scale = scale_base * sf_inv[sf[b] as usize];
let (lo, hi) = (off[b] as usize, (off[b + 1] as usize).min(GRANULE_LINES));
let mut e = 0f64;
for i in lo..hi {
let xr = f64::from(coeffs[i].signum()) * requant_magnitude(coeffs[i]) * scale;
let d = f64::from(freq[i]) - xr;
e += d * d;
}
*n = e as f32;
}
noise
}
fn bits_for(v: u8) -> u8 {
if v == 0 {
0
} else {
(8 - v.leading_zeros()) as u8
}
}
fn choose_compress(sf: &[u8; 22]) -> (u16, usize) {
let max1 = sf[0..11].iter().copied().max().unwrap_or(0);
let max2 = sf[11..21].iter().copied().max().unwrap_or(0);
let (need1, need2) = (bits_for(max1), bits_for(max2));
for (idx, &(slen1, slen2)) in crate::tables::SCALEFAC_COMPRESS_V1.iter().enumerate() {
if slen1 >= need1 && slen2 >= need2 {
return (idx as u16, 11 * slen1 as usize + 10 * slen2 as usize);
}
}
debug_assert!(
false,
"scalefactors exceed the scalefac_compress table (need slen1>={need1}, slen2>={need2}); \
the caller must clamp each band with max_sf()"
);
(15, 11 * 4 + 10 * 3)
}
fn huff_cost(
header: &FrameHeader,
coeffs: &[i32; GRANULE_LINES],
block_type: BlockType,
) -> (GranuleSideInfo, usize) {
super::huffman::select(header, coeffs, block_type)
}
fn inner_gain(
header: &FrameHeader,
freq: &[f32; GRANULE_LINES],
xrp: &[f64; GRANULE_LINES],
sf: &[u8; 22],
huff_budget: usize,
block_type: BlockType,
out: &mut [i32; GRANULE_LINES],
) -> (i32, Option<GranuleSideInfo>) {
let mut buf_a = [0i32; GRANULE_LINES];
let mut buf_b = [0i32; GRANULE_LINES];
let mut probe: &mut [i32; GRANULE_LINES] = &mut buf_a;
let mut best: &mut [i32; GRANULE_LINES] = &mut buf_b;
let mut best_side: Option<GranuleSideInfo> = None;
let mut best_gain = i32::MIN;
let (mut lo, mut hi) = (0i32, 255i32);
while lo < hi {
let mid = (lo + hi) / 2;
quantize_into(header, freq, xrp, mid, sf, probe);
let fits = probe.iter().all(|&c| c.abs() <= MAX_UNCLIPPED) && {
let (side, bits) = huff_cost(header, probe, block_type);
let fits = bits <= huff_budget;
if fits {
std::mem::swap(&mut probe, &mut best);
best_side = Some(side);
best_gain = mid;
}
fits
};
if fits {
hi = mid;
} else {
lo = mid + 1;
}
}
if best_gain == lo {
out.copy_from_slice(best);
(lo, best_side)
} else {
(lo, None)
}
}
pub fn loops(
header: &FrameHeader,
freq: &[f32; GRANULE_LINES],
psy: &PsyResult,
bit_budget: usize,
block_type: BlockType,
) -> QuantizedGranule {
let mut sf = [0u8; 22];
let mut best: Option<(f32, QuantizedGranule)> = None;
let mut best_iter = 0usize;
let xrp = xrpow(freq);
let mdct_energy: f32 = freq.iter().map(|x| x * x).sum();
let domain_scale = if domain_correction() && psy.signal_energy > 1e-20 && mdct_energy > 1e-20 {
mdct_energy / psy.signal_energy
} else {
1.0
};
if shape_slack() {
return loops_slack(
header,
freq,
psy,
bit_budget,
block_type,
domain_scale,
&xrp,
);
}
for outer in 0..MAX_OUTER {
super::prof::OUTER_ITERS.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
let (compress, sf_bits) = choose_compress(&sf);
let huff_budget = bit_budget.saturating_sub(sf_bits);
let mut coeffs = [0i32; GRANULE_LINES];
let (gain, inner) = inner_gain(
header,
freq,
&xrp,
&sf,
huff_budget,
block_type,
&mut coeffs,
);
let mut side = if let Some(side) = inner {
side
} else {
quantize_into(header, freq, &xrp, gain, &sf, &mut coeffs);
huff_cost(header, &coeffs, block_type).0
};
side.global_gain = gain as u8;
side.scalefac_compress = compress;
let mut scalefactors = [0u8; 39];
scalefactors[..22].copy_from_slice(&sf);
let granule = QuantizedGranule {
coeffs,
side,
scalefactors,
};
if outer == 0 {
super::prof::note_domain(psy.signal_energy, mdct_energy);
}
let noise = band_noise(header, freq, &granule.coeffs, gain, &sf);
let mut peak_nmr = f32::NEG_INFINITY;
let mut worst: Option<usize> = None;
let mut worst_nmr = f32::NEG_INFINITY;
for (b, &n) in noise.iter().enumerate() {
let thr = (psy.thresholds[b] * domain_scale).max(1e-20);
let nmr = n / thr;
if outer == 0 {
super::prof::note_nmr(nmr);
}
peak_nmr = peak_nmr.max(nmr);
if n > thr && sf[b] < max_sf(b) && nmr > worst_nmr && shaping_allowed(header) {
worst_nmr = nmr;
worst = Some(b);
}
}
if best.as_ref().is_none_or(|(bn, _)| peak_nmr < *bn) {
best = Some((peak_nmr, granule));
best_iter = outer;
}
match worst {
Some(b) => sf[b] += 1, None => break, }
}
super::prof::OUTER_TOTAL.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
if best_iter == 0 {
super::prof::OUTER_KEPT0.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
}
best.expect("at least one iteration runs").1
}
#[inline]
fn shaping_allowed(header: &FrameHeader) -> bool {
header.version == crate::header::MpegVersion::V1
}
const MAX_REFINE: usize = 24;
#[allow(clippy::too_many_arguments)]
fn loops_slack(
header: &FrameHeader,
freq: &[f32; GRANULE_LINES],
psy: &PsyResult,
bit_budget: usize,
block_type: BlockType,
domain_scale: f32,
xrp: &[f64; GRANULE_LINES],
) -> QuantizedGranule {
let mut sf = [0u8; 22];
let (mut compress, sf_bits) = choose_compress(&sf);
let mut coeffs = [0i32; GRANULE_LINES];
let (gain, inner) = inner_gain(
header,
freq,
xrp,
&sf,
bit_budget.saturating_sub(sf_bits),
block_type,
&mut coeffs,
);
let mut side = if let Some(side) = inner {
side
} else {
quantize_into(header, freq, xrp, gain, &sf, &mut coeffs);
huff_cost(header, &coeffs, block_type).0
};
let mut noise = band_noise(header, freq, &coeffs, gain, &sf);
let off = crate::tables::sfb_long_offsets(header.sample_rate);
for _ in 0..MAX_REFINE {
if !shaping_allowed(header) {
break; }
let audible_only = shape_audible_only();
let pick = pick_rule();
let mut worst = None;
let mut worst_score = f32::NEG_INFINITY;
for (b, &n) in noise.iter().enumerate() {
let thr = (psy.thresholds[b] * domain_scale).max(1e-20);
let score = match pick {
Pick::Nmr => n / thr,
Pick::Noise => n,
Pick::Widest => n / (band_width(header, b) as f32),
Pick::LowFirst => -(b as f32),
};
if sf[b] < max_sf(b) && score > worst_score && (!audible_only || n > thr) {
worst_score = score;
worst = Some(b);
}
}
{
let mut any_best = None;
let mut any_score = f32::NEG_INFINITY;
for (bb, &n) in noise.iter().enumerate() {
let thr = (psy.thresholds[bb] * domain_scale).max(1e-20);
let sc = n / thr;
if sc > any_score && (!audible_only || n > thr) {
any_score = sc;
any_best = Some(bb);
}
}
if let Some(bb) = any_best {
if sf[bb] >= max_sf(bb) {
use std::sync::atomic::Ordering::Relaxed;
if bb < 11 {
super::prof::CAP_BLOCK_LO.fetch_add(1, Relaxed);
} else {
super::prof::CAP_BLOCK_HI.fetch_add(1, Relaxed);
}
}
}
}
let Some(b) = worst else { break };
let mut trial = sf;
trial[b] += 1;
let (t_compress, t_sf_bits) = choose_compress(&trial);
quantize_band_in_place(header, freq, xrp, gain, trial[b], b, &mut coeffs);
let (lo, hi) = (off[b] as usize, (off[b + 1] as usize).min(GRANULE_LINES));
let clipped = coeffs[lo..hi].iter().any(|&c| c.abs() > MAX_UNCLIPPED);
let (t_side, t_bits) = if clipped {
(side.clone(), usize::MAX)
} else {
huff_cost(header, &coeffs, block_type)
};
if clipped || t_bits + t_sf_bits > bit_budget {
quantize_band_in_place(header, freq, xrp, gain, sf[b], b, &mut coeffs);
break;
}
noise[b] = band_noise_one(header, freq, &coeffs, gain, trial[b], b);
sf = trial;
side = t_side;
compress = t_compress;
super::prof::REFINE_STEPS.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
}
side.global_gain = gain as u8;
side.scalefac_compress = compress;
let mut scalefactors = [0u8; 39];
scalefactors[..22].copy_from_slice(&sf);
let relaxed = std::sync::atomic::Ordering::Relaxed;
super::prof::OUTER_TOTAL.fetch_add(1, relaxed);
if sf.iter().all(|&v| v == 0) {
super::prof::OUTER_KEPT0.fetch_add(1, relaxed);
} else if (11..21).all(|b| sf[b] >= crate::tables::PRETAB[b]) {
super::prof::PREFLAG_OK.fetch_add(1, relaxed);
}
QuantizedGranule {
coeffs,
side,
scalefactors,
}
}
fn band_width(header: &FrameHeader, b: usize) -> usize {
let off = crate::tables::sfb_long_offsets(header.sample_rate);
(off[b + 1] as usize).min(GRANULE_LINES) - off[b] as usize
}
#[derive(Clone, Copy, PartialEq)]
enum Pick {
Nmr,
Noise,
Widest,
LowFirst,
}
fn pick_rule() -> Pick {
static V: std::sync::OnceLock<Pick> = std::sync::OnceLock::new();
*V.get_or_init(|| match std::env::var("MP3_PICK").as_deref() {
Ok("noise") => Pick::Noise,
Ok("perline") => Pick::Widest,
Ok("lowfirst") => Pick::LowFirst,
_ => Pick::Nmr,
})
}
fn shape_audible_only() -> bool {
static V: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
*V.get_or_init(|| std::env::var("MP3_SHAPE").as_deref() == Ok("audible"))
}
fn shape_slack() -> bool {
static V: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
*V.get_or_init(|| std::env::var("MP3_SHAPE").as_deref() != Ok("outer"))
}
fn domain_correction() -> bool {
static V: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
*V.get_or_init(|| std::env::var("MP3_PSY_DOMAIN").as_deref() != Ok("0"))
}
fn nonclip_floor(
header: &FrameHeader,
freq: &[f32; GRANULE_LINES],
xrp: &[f64; GRANULE_LINES],
) -> i32 {
let flat = [0u8; 22];
let ok = |g: i32| {
quantize_with_sf(header, freq, xrp, g, &flat)
.iter()
.all(|&c| c.abs() <= MAX_UNCLIPPED)
};
let (mut lo, mut hi) = (0i32, 255i32);
while lo < hi {
let mid = (lo + hi) / 2;
if ok(mid) {
hi = mid;
} else {
lo = mid + 1;
}
}
lo
}
pub fn loops_vbr(
header: &FrameHeader,
freq: &[f32; GRANULE_LINES],
psy: &PsyResult,
target_nmr: f32,
block_type: BlockType,
) -> QuantizedGranule {
let flat = [0u8; 22];
let xrp = xrpow(freq);
let mdct_energy: f32 = freq.iter().map(|x| x * x).sum();
let domain_scale = if psy.signal_energy > 1e-20 && mdct_energy > 1e-20 {
mdct_energy / psy.signal_energy
} else {
1.0
};
let peak = |g: i32| {
let coeffs = quantize_with_sf(header, freq, &xrp, g, &flat);
let noise = band_noise(header, freq, &coeffs, g, &flat);
noise
.iter()
.enumerate()
.map(|(b, &n)| n / (psy.thresholds[b] * domain_scale).max(1e-20))
.fold(0f32, f32::max)
};
let (mut lo, mut hi) = (0i32, 255i32);
while lo < hi {
let mid = (lo + hi + 1) / 2;
if peak(mid) <= target_nmr {
lo = mid;
} else {
hi = mid - 1;
}
}
let floor = nonclip_floor(header, freq, &xrp);
let gain = lo.max(floor);
{
use std::sync::atomic::{AtomicU64, Ordering::Relaxed};
pub static N: AtomicU64 = AtomicU64::new(0);
pub static SUM_LO: AtomicU64 = AtomicU64::new(0);
pub static SUM_FLOOR: AtomicU64 = AtomicU64::new(0);
pub static CLAMPED: AtomicU64 = AtomicU64::new(0);
pub static SATURATED: AtomicU64 = AtomicU64::new(0);
N.fetch_add(1, Relaxed);
SUM_LO.fetch_add(lo.max(0) as u64, Relaxed);
SUM_FLOOR.fetch_add(floor.max(0) as u64, Relaxed);
if floor > lo {
CLAMPED.fetch_add(1, Relaxed);
}
if lo >= 255 {
SATURATED.fetch_add(1, Relaxed);
}
let n = N.load(Relaxed);
if n % 2000 == 0 {
let p_floor = peak(floor);
let p_max = peak(255);
let thr_min = psy.thresholds.iter().copied().fold(f32::MAX, f32::min);
let thr_max = psy.thresholds.iter().copied().fold(0f32, f32::max);
let sig: f32 = freq.iter().map(|x| x * x).sum();
eprintln!(
"[nmr] peak(floor={floor})={p_floor:.6e} peak(255)={p_max:.6e} thr[min={thr_min:.3e} max={thr_max:.3e}] sig_energy={sig:.3e}"
);
eprintln!(
"[vbr] n={n} target_nmr={target_nmr:.4} mean_lo={:.1} mean_floor={:.1} clamped={:.1}% saturated={:.1}%",
SUM_LO.load(Relaxed) as f64 / n as f64,
SUM_FLOOR.load(Relaxed) as f64 / n as f64,
100.0 * CLAMPED.load(Relaxed) as f64 / n as f64,
100.0 * SATURATED.load(Relaxed) as f64 / n as f64,
);
}
}
let mut sf = [0u8; 22];
for _ in 0..MAX_OUTER {
let coeffs = quantize_with_sf(header, freq, &xrp, gain, &sf);
let noise = band_noise(header, freq, &coeffs, gain, &sf);
let mut worst = None;
let mut worst_nmr = f32::NEG_INFINITY;
for (b, &n) in noise.iter().enumerate() {
let thr = (psy.thresholds[b] * domain_scale).max(1e-20);
let nmr = n / thr;
if n > thr && nmr > worst_nmr && sf[b] >= max_sf(b) && sf[b] < MAX_SF {
super::prof::SF_OVERFLOW.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
}
if n > thr && sf[b] < max_sf(b) && nmr > worst_nmr {
worst_nmr = nmr;
worst = Some(b);
}
}
match worst {
Some(b) => sf[b] += 1,
None => break,
}
}
let coeffs = quantize_with_sf(header, freq, &xrp, gain, &sf);
let (compress, _) = choose_compress(&sf);
let (mut side, _) = super::huffman::select(header, &coeffs, block_type);
side.global_gain = gain as u8;
side.scalefac_compress = compress;
let mut scalefactors = [0u8; 39];
scalefactors[..22].copy_from_slice(&sf);
QuantizedGranule {
coeffs,
side,
scalefactors,
}
}
#[cfg(test)]
mod c2_tests {
use super::*;
use crate::decode::scalefactors::ScaleFactors;
use crate::frame::ChannelMode;
use crate::header::MpegVersion;
fn hdr() -> FrameHeader {
FrameHeader {
version: MpegVersion::V1,
crc_protected: false,
bitrate_kbps: 128,
sample_rate: 44100,
padding: false,
channel_mode: ChannelMode::Mono,
copyright: false,
original: true,
emphasis: 0,
}
}
#[test]
fn xrpow_path_matches_powf_reference() {
let header = hdr();
let mut s = 0xABCD_1234u32;
let mut total = 0usize;
let mut diffs = 0usize;
for trial in 0..40 {
let mut freq = [0f32; GRANULE_LINES];
for f in &mut freq {
s = s.wrapping_mul(1_664_525).wrapping_add(1_013_904_223);
*f = ((s >> 8) as f32 / (1u32 << 24) as f32 - 0.5) * 2.0 * 1000.0;
}
let xrp = xrpow(&freq);
let off = crate::tables::sfb_long_offsets(header.sample_rate);
for &gain in &[120i32, 180, 210, 230] {
let mut sf = [0u8; 22];
for (b, sfb) in sf.iter_mut().enumerate() {
*sfb = ((trial + b) % 4) as u8;
}
let got = quantize_with_sf(&header, &freq, &xrp, gain, &sf);
let base = -0.25 * f64::from(gain - 210);
for b in 0..22 {
let sv = f64::from(if b < 21 { sf[b] } else { 0 });
let scale_inv = 2f64.powf(base + SF_MULT * sv);
let (lo, hi) = (off[b] as usize, (off[b + 1] as usize).min(GRANULE_LINES));
for i in lo..hi {
let mag = quantize_level(f64::from(freq[i].abs()) * scale_inv);
let want = if freq[i] < 0.0 { -mag } else { mag };
total += 1;
if got[i] != want {
assert!(
(got[i] - want).abs() <= 1,
"line {i}: table {} vs powf {want} (gain {gain})",
got[i]
);
diffs += 1;
}
}
}
}
}
assert!(
diffs * 1000 < total,
"too many xrpow/powf mismatches: {diffs}/{total}"
);
eprintln!("[A1] xrpow vs powf: {diffs}/{total} off-by-one (ULP) lines");
}
#[test]
fn spectrum_roundtrip_through_quantizer() {
let header = hdr();
let mut freq = [0f32; GRANULE_LINES];
freq[40] = 5.0;
freq[41] = -3.0;
freq[100] = 1.2;
freq[200] = 0.6;
let psy = PsyResult::default();
let q = loops(&header, &freq, &psy, 100_000, BlockType::Long); eprintln!(
"[C2dbg] gain={} part2_3={} nz_coeffs={}",
q.side.global_gain,
q.side.part2_3_length,
q.coeffs.iter().filter(|&&c| c != 0).count()
);
let mut sf = ScaleFactors::default();
sf.long.copy_from_slice(&q.scalefactors[..22]);
let mut out = [0f32; GRANULE_LINES];
let nz = q.coeffs.iter().rposition(|&c| c != 0).map_or(0, |i| i + 1);
crate::decode::requantize::apply(&header, &q.side, &sf, &q.coeffs, nz, &mut out);
let mut maxerr = 0f32;
for i in 0..GRANULE_LINES {
maxerr = maxerr.max((out[i] - freq[i]).abs());
}
eprintln!(
"[C2dbg] requant maxerr={maxerr} out[40]={} out[41]={}",
out[40], out[41]
);
assert!(maxerr < 0.2, "spectrum round-trip error {maxerr}");
}
}
#[cfg(test)]
mod q6_tests {
use super::*;
use crate::frame::{BlockType, ChannelMode, GranuleSideInfo};
use crate::header::MpegVersion;
fn hdr() -> FrameHeader {
FrameHeader {
version: MpegVersion::V1,
crc_protected: false,
bitrate_kbps: 128,
sample_rate: 44100,
padding: false,
channel_mode: ChannelMode::Mono,
copyright: false,
original: true,
emphasis: 0,
}
}
fn peak_nmr_db(
header: &FrameHeader,
freq: &[f32; GRANULE_LINES],
g: &QuantizedGranule,
thresholds: &[f32; 22],
) -> f32 {
let mut sf = [0u8; 22];
sf.copy_from_slice(&g.scalefactors[..22]);
let noise = band_noise(header, freq, &g.coeffs, i32::from(g.side.global_gain), &sf);
let mut peak = f32::NEG_INFINITY;
for (b, &n) in noise.iter().enumerate() {
peak = peak.max(10.0 * (n / thresholds[b].max(1e-20)).log10());
}
peak
}
#[test]
fn distortion_loop_beats_flat_on_a_complex_signal() {
let header = hdr();
let sr = 44100.0;
let pcm: Vec<f32> = (0..1152)
.map(|i| {
let t = i as f32 / sr;
0.35 * (2.0 * std::f32::consts::PI * 600.0 * t).sin()
+ 0.2 * (2.0 * std::f32::consts::PI * 5200.0 * t).sin()
})
.collect();
let psy = super::super::psychoacoustic::analyze(&pcm, 44100);
let mut fifo = [0f32; 512];
let sub = super::super::filterbank::analyze(&pcm, &mut fifo);
let mut overlap = [0f32; GRANULE_LINES];
let mut freq = super::super::mdct::forward(&sub, BlockType::Long, &mut overlap);
super::super::antialias::expand(&GranuleSideInfo::default(), &mut freq);
let budget = 1600;
let flat = PsyResult {
thresholds: [f32::MAX; 22], ..psy.clone()
};
let shaped = loops(&header, &freq, &psy, budget, BlockType::Long);
let plain = loops(&header, &freq, &flat, budget, BlockType::Long);
let nmr_shaped = peak_nmr_db(&header, &freq, &shaped, &psy.thresholds);
let nmr_plain = peak_nmr_db(&header, &freq, &plain, &psy.thresholds);
eprintln!("[Q6] peak NMR: shaped {nmr_shaped:.1} dB vs flat {nmr_plain:.1} dB");
assert!(
nmr_shaped <= nmr_plain + 0.01,
"psymodel shaping must not worsen peak NMR: {nmr_shaped} vs {nmr_plain}"
);
}
}
#[cfg(test)]
mod n4_tests {
use super::*;
#[test]
fn requant_magnitude_matches_power_law() {
for level in [0, 1, 2, 3, 17, 255, 1024, MAX_LEVEL] {
let expect = f64::from(level).powf(4.0 / 3.0);
assert!((requant_magnitude(level) - expect).abs() < 1e-9);
}
assert_eq!(requant_magnitude(-3), requant_magnitude(3));
}
#[test]
fn forward_inverse_round_trip_on_the_lattice() {
for level in 0..=MAX_LEVEL {
let xr = requant_magnitude(level);
assert_eq!(
quantize_level(xr),
level,
"round-trip failed at level {level} (xr={xr})"
);
}
}
#[test]
fn quantizer_clamps_and_zeroes() {
assert_eq!(quantize_level(0.0), 0);
assert_eq!(quantize_level(0.3), 0);
assert_eq!(quantize_level(1.0e9), MAX_LEVEL);
}
#[test]
fn quantize_lines_simd_matches_scalar() {
if !crate::decode::isa::simd_available() {
eprintln!("no SIMD twin on this host - scalar path only, gate skipped");
return;
}
let mut st = 0x6C07_8965u32;
let mut r = move || {
st = st.wrapping_mul(1_664_525).wrapping_add(1_013_904_223);
st
};
for &rate in &[44100u32, 32000, 22050, 8000] {
let off = crate::tables::sfb_long_offsets(rate);
for trial in 0..64 {
let mut freq = [0f32; GRANULE_LINES];
let mut xrp = [0f64; GRANULE_LINES];
for i in 0..GRANULE_LINES {
let k = r();
freq[i] = match k % 7 {
0 => -0.0,
1 => 0.0,
_ => ((k >> 3) as f32 / 2.0e8) - 10.0,
};
xrp[i] = match (k >> 8) % 5 {
0 => f64::from(k % 9000) + 0.5 + QUANT_BIAS, 1 => 1.0e9, 2 => 0.0,
_ => f64::from(k >> 4) / 1.0e5,
};
}
let mut steps = [0f64; 22];
for s in &mut steps {
*s = [1.0, 0.5, 2.0, 0.123_456_7][(r() % 4) as usize];
}
let (mut a, mut b) = ([0i32; GRANULE_LINES], [0i32; GRANULE_LINES]);
quantize_lines_scalar(off, &steps, &freq, &xrp, &mut a);
unsafe { quantize_lines_simd(off, &steps, &freq, &xrp, &mut b) };
assert_eq!(
a, b,
"quantizer SIMD/scalar mismatch at rate {rate} trial {trial}"
);
}
}
}
#[test]
fn level_from_matches_guarded() {
let guarded = |powered: f64| -> i32 {
let m = powered - QUANT_BIAS;
if m <= 0.0 {
0
} else {
(m.round() as i32).clamp(0, MAX_LEVEL)
}
};
let mut p = -1.0f64;
#[allow(clippy::while_float)]
while p < 9000.0 {
assert_eq!(level_from(p), guarded(p), "level_from mismatch at {p}");
p += 0.013; }
for n in 0..50 {
let mid = f64::from(n) + 0.5 + QUANT_BIAS;
assert_eq!(level_from(mid), guarded(mid), "midpoint {mid}");
}
for &p in &[f64::from(0), 1e9, f64::from(MAX_LEVEL) + 5.0] {
assert_eq!(level_from(p), guarded(p));
}
}
}
#[cfg(test)]
mod sf_range_tests {
use super::*;
#[test]
fn max_sf_is_representable_for_every_band() {
for b in 0..21 {
let mut sf = [0u8; 22];
sf[b] = max_sf(b);
let (idx, _bits) = choose_compress(&sf);
let (slen1, slen2) = crate::tables::SCALEFAC_COMPRESS_V1[idx as usize];
let slen = if b < 11 { slen1 } else { slen2 };
let representable = if slen == 0 { 0 } else { (1u16 << slen) - 1 };
assert!(
u16::from(sf[b]) <= representable,
"band {b}: sf {} needs more than slen {slen} ({representable} max)",
sf[b]
);
}
}
#[test]
fn high_band_ceiling_is_seven() {
assert_eq!(max_sf(0), 15);
assert_eq!(max_sf(10), 15);
assert_eq!(max_sf(11), 7);
assert_eq!(max_sf(20), 7);
let max_slen2 = crate::tables::SCALEFAC_COMPRESS_V1
.iter()
.map(|&(_, s2)| s2)
.max()
.unwrap();
assert_eq!(max_slen2, 3, "slen2 ceiling moved; revisit max_sf()");
}
}