mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-28 20:16:52 -06:00
Refactor opusenc for strict Clippy checks
This commit is contained in:
+18
-24
@@ -8,7 +8,8 @@
|
||||
|
||||
use crate::range::{BITRES, RangeEncoder, ilog};
|
||||
use crate::rate::{Mode, QTHETA_OFFSET, get_pulses};
|
||||
use crate::tables::*;
|
||||
use crate::tables::EBANDS;
|
||||
use crate::{CeltFrame, rate::Allocation};
|
||||
|
||||
pub const SPREAD_NORMAL: usize = 2;
|
||||
|
||||
@@ -55,7 +56,7 @@ fn exp_rotation1_inv(x: &mut [f32], len: usize, stride: usize, c: f32, s: f32) {
|
||||
if len <= stride {
|
||||
return;
|
||||
}
|
||||
if len >= 2 * stride + 1 {
|
||||
if len > 2 * stride {
|
||||
for i in 0..=len - 2 * stride - 1 {
|
||||
let x1 = x[i];
|
||||
let x2 = x[i + stride];
|
||||
@@ -217,7 +218,7 @@ impl BandEnc<'_, '_> {
|
||||
let q = qn as u32;
|
||||
let half = q >> 1;
|
||||
let ft = (half + 1) * (half + 1);
|
||||
let (fl, fs) = if it <= half { (it * (it + 1) >> 1, it + 1) } else { (ft - ((q + 1 - it) * (q + 2 - it) >> 1), q + 1 - it) };
|
||||
let (fl, fs) = if it <= half { ((it * (it + 1)) >> 1, it + 1) } else { (ft - (((q + 1 - it) * (q + 2 - it)) >> 1), q + 1 - it) };
|
||||
self.enc.encode(fl, fl + fs, ft);
|
||||
itheta = ((it * 16384) / q) as i32;
|
||||
}
|
||||
@@ -294,26 +295,19 @@ impl BandEnc<'_, '_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Codes all band shapes (`quant_all_bands`, encoder side, long blocks). `x` holds `c` channels
|
||||
/// of `n` normalised MDCT coefficients each.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn quant_all_bands(
|
||||
m: &Mode,
|
||||
start: usize,
|
||||
end: usize,
|
||||
x: &[f32],
|
||||
n_total: usize,
|
||||
c: usize,
|
||||
pulses: &[i32; NB_EBANDS],
|
||||
spread: usize,
|
||||
dual_stereo: bool,
|
||||
intensity: usize,
|
||||
total_bits: i32,
|
||||
mut balance: i32,
|
||||
enc: &mut RangeEncoder,
|
||||
lm: usize,
|
||||
coded_bands: usize,
|
||||
) {
|
||||
/// Shape-coding controls, independent of the selected band allocation.
|
||||
pub struct BandCoding {
|
||||
pub spread: usize,
|
||||
pub total_bits: i32,
|
||||
}
|
||||
|
||||
/// Codes all band shapes (`quant_all_bands`, encoder side, long blocks). `x` holds
|
||||
/// `frame.channels` channels of `n_total` normalised MDCT coefficients each.
|
||||
pub fn quant_all_bands(m: &Mode, frame: CeltFrame, x: &[f32], n_total: usize, allocation: &Allocation, coding: BandCoding, enc: &mut RangeEncoder) {
|
||||
let CeltFrame { start, end, channels: c, lm } = frame;
|
||||
let Allocation { pulses, dual_stereo, intensity, coded_bands, balance, .. } = allocation;
|
||||
let (dual_stereo, intensity, coded_bands, mut balance) = (*dual_stereo, *intensity, *coded_bands, *balance);
|
||||
let BandCoding { spread, total_bits } = coding;
|
||||
let mm = 1usize << lm;
|
||||
debug_assert!(c == 1 || dual_stereo || intensity <= start, "stereo frames are coded as dual stereo");
|
||||
let mut ctx = BandEnc { m, enc, i: 0, spread, remaining_bits: 0, pvq_v: Vec::new(), iy: Vec::new(), tmp: Vec::new() };
|
||||
@@ -362,7 +356,7 @@ mod tests {
|
||||
x[i + stride] = c * x2 + s * x1;
|
||||
x[i] = c * x1 + ms * x2;
|
||||
}
|
||||
if len >= 2 * stride + 1 {
|
||||
if len > 2 * stride {
|
||||
for i in (0..=len - 2 * stride - 1).rev() {
|
||||
let x1 = x[i];
|
||||
let x2 = x[i + stride];
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
//! The quantised energies are updated with exactly the decoder's arithmetic so the prediction
|
||||
//! state never drifts between encoder and decoder.
|
||||
|
||||
use crate::CeltFrame;
|
||||
use crate::range::RangeEncoder;
|
||||
use crate::rate::MAX_FINE_BITS;
|
||||
use crate::tables::*;
|
||||
use crate::rate::{Allocation, MAX_FINE_BITS};
|
||||
use crate::tables::{BETA_COEF, BETA_INTRA, E_PROB_MODEL, NB_EBANDS, PRED_COEF, SMALL_ENERGY_ICDF};
|
||||
|
||||
const LAPLACE_MINP: u32 = 1;
|
||||
const LAPLACE_NMIN: u32 = 16;
|
||||
@@ -56,18 +57,8 @@ pub fn laplace_encode(enc: &mut RangeEncoder, value: i32, mut fs: u32, decay: u3
|
||||
/// `quant_coarse_energy` for one prediction mode. `e` holds the target log2 energies (relative
|
||||
/// to `E_MEANS`), `old_e` the quantised energies, updated in place. `budget` is the frame size in
|
||||
/// bits.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn quant_coarse_energy(
|
||||
start: usize,
|
||||
end: usize,
|
||||
e: &[f32; 2 * NB_EBANDS],
|
||||
old_e: &mut [f32; 2 * NB_EBANDS],
|
||||
intra: bool,
|
||||
enc: &mut RangeEncoder,
|
||||
c: usize,
|
||||
lm: usize,
|
||||
budget: i32,
|
||||
) {
|
||||
pub fn quant_coarse_energy(frame: CeltFrame, e: &[f32; 2 * NB_EBANDS], old_e: &mut [f32; 2 * NB_EBANDS], intra: bool, enc: &mut RangeEncoder, budget: i32) {
|
||||
let CeltFrame { start, end, channels: c, lm } = frame;
|
||||
let prob = &E_PROB_MODEL[lm][intra as usize];
|
||||
let (coef, beta) = if intra { (0.0, BETA_INTRA) } else { (PRED_COEF[lm], BETA_COEF[lm]) };
|
||||
let mut prev = [0f32; 2];
|
||||
@@ -111,15 +102,8 @@ pub fn quant_coarse_energy(
|
||||
}
|
||||
|
||||
/// `quant_fine_energy`: raw bits refining each band's quantised energy.
|
||||
pub fn quant_fine_energy(
|
||||
start: usize,
|
||||
end: usize,
|
||||
e: &[f32; 2 * NB_EBANDS],
|
||||
old_e: &mut [f32; 2 * NB_EBANDS],
|
||||
fine_quant: &[i32; NB_EBANDS],
|
||||
enc: &mut RangeEncoder,
|
||||
c: usize,
|
||||
) {
|
||||
pub fn quant_fine_energy(frame: CeltFrame, e: &[f32; 2 * NB_EBANDS], old_e: &mut [f32; 2 * NB_EBANDS], fine_quant: &[i32; NB_EBANDS], enc: &mut RangeEncoder) {
|
||||
let CeltFrame { start, end, channels: c, .. } = frame;
|
||||
for i in start..end {
|
||||
let fq = fine_quant[i];
|
||||
if fq <= 0 {
|
||||
@@ -139,18 +123,16 @@ pub fn quant_fine_energy(
|
||||
|
||||
/// `quant_energy_finalise`: spends the bits left at the end of the frame on one more bit of
|
||||
/// energy resolution per band, in priority order.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn quant_energy_finalise(
|
||||
start: usize,
|
||||
end: usize,
|
||||
frame: CeltFrame,
|
||||
e: &[f32; 2 * NB_EBANDS],
|
||||
old_e: &mut [f32; 2 * NB_EBANDS],
|
||||
fine_quant: &[i32; NB_EBANDS],
|
||||
fine_priority: &[i32; NB_EBANDS],
|
||||
allocation: &Allocation,
|
||||
mut bits_left: i32,
|
||||
enc: &mut RangeEncoder,
|
||||
c: usize,
|
||||
) {
|
||||
let CeltFrame { start, end, channels: c, .. } = frame;
|
||||
let Allocation { fine_quant, fine_priority, .. } = allocation;
|
||||
for prio in 0..2 {
|
||||
let mut i = start;
|
||||
while i < end && bits_left >= c as i32 {
|
||||
|
||||
+25
-33
@@ -24,8 +24,6 @@
|
||||
//! ```
|
||||
|
||||
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
|
||||
// The bit-allocation code mirrors the normative integer arithmetic; keep C-like shift expressions.
|
||||
#![allow(clippy::precedence, clippy::int_plus_one)]
|
||||
|
||||
mod bands;
|
||||
mod energy;
|
||||
@@ -38,14 +36,23 @@ mod tables;
|
||||
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use bands::{SPREAD_NORMAL, quant_all_bands};
|
||||
use bands::{BandCoding, SPREAD_NORMAL, quant_all_bands};
|
||||
use energy::{quant_coarse_energy, quant_energy_finalise, quant_fine_energy};
|
||||
use mdct::Mdct;
|
||||
use range::{BITRES, RangeEncoder};
|
||||
use rate::{Mode as CeltMode, compute_allocation};
|
||||
use rate::{AllocationInput, Mode as CeltMode, compute_allocation};
|
||||
use resample::Downsampler;
|
||||
use silk::SilkEncoder;
|
||||
use tables::*;
|
||||
use tables::{E_MEANS, EBANDS, NB_EBANDS, OVERLAP, PREEMPH, SPREAD_ICDF, TF_SELECT_TABLE, TRIM_ICDF};
|
||||
|
||||
/// Band range, channel count and transform size shared by CELT coding stages.
|
||||
#[derive(Clone, Copy)]
|
||||
struct CeltFrame {
|
||||
start: usize,
|
||||
end: usize,
|
||||
channels: usize,
|
||||
lm: usize,
|
||||
}
|
||||
|
||||
/// Samples per channel in one 20 ms frame at 48 kHz.
|
||||
const N: usize = 960;
|
||||
@@ -314,7 +321,7 @@ impl OpusEncoder {
|
||||
Mode::Celt => {
|
||||
let (log_e, silence) = self.celt_analysis(pcm);
|
||||
let len = self.frame_bytes;
|
||||
packet.extend_from_slice(&self.encode_celt(RangeEncoder::new(), len, 0, NB_EBANDS, &log_e, silence));
|
||||
packet.extend_from_slice(&self.encode_celt(RangeEncoder::new(), len, 0..NB_EBANDS, &log_e, silence));
|
||||
}
|
||||
Mode::Silk => {
|
||||
let x = self.silk_input(pcm);
|
||||
@@ -344,7 +351,7 @@ impl OpusEncoder {
|
||||
}
|
||||
let (log_e, _) = self.celt_analysis(pcm);
|
||||
let end = if self.bandwidth == Bandwidth::SuperWideband { 19 } else { NB_EBANDS };
|
||||
packet.extend_from_slice(&self.encode_celt(enc, len, HYBRID_START_BAND, end, &log_e, false));
|
||||
packet.extend_from_slice(&self.encode_celt(enc, len, HYBRID_START_BAND..end, &log_e, false));
|
||||
}
|
||||
}
|
||||
packet
|
||||
@@ -406,10 +413,11 @@ impl OpusEncoder {
|
||||
/// Codes one CELT frame (RFC 6716 §4.3, in bitstream order) of `len` bytes into `enc`
|
||||
/// (which already holds the SILK frame in hybrid mode), coding bands `start..end`, and
|
||||
/// finalises the frame.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn encode_celt(&mut self, mut enc: RangeEncoder, len: usize, start: usize, end: usize, log_e: &[f32; 2 * NB_EBANDS], silence: bool) -> Vec<u8> {
|
||||
fn encode_celt(&mut self, mut enc: RangeEncoder, len: usize, bands: std::ops::Range<usize>, log_e: &[f32; 2 * NB_EBANDS], silence: bool) -> Vec<u8> {
|
||||
let m = celt_mode();
|
||||
let c = self.channels;
|
||||
let frame = CeltFrame { start: bands.start, end: bands.end, channels: c, lm: LM };
|
||||
let CeltFrame { start, end, .. } = frame;
|
||||
if c == 1 {
|
||||
for i in 0..NB_EBANDS {
|
||||
self.old_band_e[i] = self.old_band_e[i].max(self.old_band_e[NB_EBANDS + i]);
|
||||
@@ -438,10 +446,10 @@ impl OpusEncoder {
|
||||
let mut enc_intra = enc.clone();
|
||||
let mut old_intra = self.old_band_e;
|
||||
enc_intra.bit_logp(true, 3);
|
||||
quant_coarse_energy(start, end, log_e, &mut old_intra, true, &mut enc_intra, c, LM, total_bits_raw);
|
||||
quant_coarse_energy(frame, log_e, &mut old_intra, true, &mut enc_intra, total_bits_raw);
|
||||
enc.bit_logp(false, 3);
|
||||
let mut old_inter = self.old_band_e;
|
||||
quant_coarse_energy(start, end, log_e, &mut old_inter, false, &mut enc, c, LM, total_bits_raw);
|
||||
quant_coarse_energy(frame, log_e, &mut old_inter, false, &mut enc, total_bits_raw);
|
||||
if enc_intra.tell_frac() < enc.tell_frac() {
|
||||
enc = enc_intra;
|
||||
self.old_band_e = old_intra;
|
||||
@@ -449,14 +457,14 @@ impl OpusEncoder {
|
||||
self.old_band_e = old_inter;
|
||||
}
|
||||
} else {
|
||||
quant_coarse_energy(start, end, log_e, &mut self.old_band_e, false, &mut enc, c, LM, total_bits_raw);
|
||||
quant_coarse_energy(frame, log_e, &mut self.old_band_e, false, &mut enc, total_bits_raw);
|
||||
}
|
||||
// TF resolution: no changes.
|
||||
{
|
||||
let mut budget = total_bits_raw;
|
||||
let mut tell = enc.tell();
|
||||
let mut logp = 4;
|
||||
let tf_select_rsv = LM > 0 && tell + logp + 1 <= budget;
|
||||
let tf_select_rsv = LM > 0 && tell + logp < budget;
|
||||
budget -= tf_select_rsv as i32;
|
||||
for _ in start..end {
|
||||
if tell + logp <= budget {
|
||||
@@ -488,27 +496,11 @@ impl OpusEncoder {
|
||||
enc.icdf(alloc_trim as usize, &TRIM_ICDF, 7);
|
||||
}
|
||||
let bits = (total_bits_raw << BITRES) - enc.tell_frac() - 1;
|
||||
let alloc = compute_allocation(m, start, end, &offsets, &cap, alloc_trim, bits, c, LM, &mut enc);
|
||||
quant_fine_energy(start, end, log_e, &mut self.old_band_e, &alloc.fine_quant, &mut enc, c);
|
||||
quant_all_bands(
|
||||
m,
|
||||
start,
|
||||
end,
|
||||
&self.freq,
|
||||
N,
|
||||
c,
|
||||
&alloc.pulses,
|
||||
SPREAD_NORMAL,
|
||||
alloc.dual_stereo,
|
||||
alloc.intensity,
|
||||
total_bits_raw << BITRES,
|
||||
alloc.balance,
|
||||
&mut enc,
|
||||
LM,
|
||||
alloc.coded_bands,
|
||||
);
|
||||
let alloc = compute_allocation(m, frame, AllocationInput { offsets: &offsets, cap: &cap, trim: alloc_trim, bits }, &mut enc);
|
||||
quant_fine_energy(frame, log_e, &mut self.old_band_e, &alloc.fine_quant, &mut enc);
|
||||
quant_all_bands(m, frame, &self.freq, N, &alloc, BandCoding { spread: SPREAD_NORMAL, total_bits: total_bits_raw << BITRES }, &mut enc);
|
||||
let bits_left = total_bits_raw - enc.tell();
|
||||
quant_energy_finalise(start, end, log_e, &mut self.old_band_e, &alloc.fine_quant, &alloc.fine_priority, bits_left, &mut enc, c);
|
||||
quant_energy_finalise(frame, log_e, &mut self.old_band_e, &alloc, bits_left, &mut enc);
|
||||
debug_assert!(enc.tell() <= total_bits_raw, "frame overflow: {} > {}", enc.tell(), total_bits_raw);
|
||||
if c == 1 {
|
||||
let (a, b) = self.old_band_e.split_at_mut(NB_EBANDS);
|
||||
|
||||
+44
-45
@@ -4,8 +4,9 @@
|
||||
//! spec-derived `filmcraft-opus` decoder (first-party, MIT OR Apache-2.0) step by step; the only
|
||||
//! difference is that the encoder *writes* the band-skip, intensity and dual-stereo symbols.
|
||||
|
||||
use crate::CeltFrame;
|
||||
use crate::range::{BITRES, RangeEncoder, ilog};
|
||||
use crate::tables::*;
|
||||
use crate::tables::{ALLOC, EBANDS, LOG2_FRAC_TABLE, MAX_LM, NB_EBANDS};
|
||||
|
||||
const MAX_PSEUDO: i32 = 40;
|
||||
const LOG_MAX_PSEUDO: i32 = 6;
|
||||
@@ -127,7 +128,7 @@ impl Mode {
|
||||
let mut cap = [0i32; NB_EBANDS];
|
||||
for (i, cp) in cap.iter_mut().enumerate() {
|
||||
let n = (EBANDS[i + 1] - EBANDS[i]) << lm;
|
||||
*cp = (self.caps[NB_EBANDS * (2 * lm + c - 1) + i] as i32 + 64) * c as i32 * n >> 2;
|
||||
*cp = ((self.caps[NB_EBANDS * (2 * lm + c - 1) + i] as i32 + 64) * c as i32 * n) >> 2;
|
||||
}
|
||||
cap
|
||||
}
|
||||
@@ -200,7 +201,7 @@ fn compute_caps(m: &Mode) -> Vec<u8> {
|
||||
let mut n0 = EBANDS[j + 1] - EBANDS[j];
|
||||
|
||||
let max_bits = if n0 << i == 1 {
|
||||
c * (1 + MAX_FINE_BITS) << BITRES
|
||||
(c * (1 + MAX_FINE_BITS)) << BITRES
|
||||
} else {
|
||||
let mut lm0 = 0;
|
||||
if n0 > 2 {
|
||||
@@ -240,7 +241,7 @@ fn compute_caps(m: &Mode) -> Vec<u8> {
|
||||
let num = mb + ndof * offset;
|
||||
let den = (ndof - 1) << BITRES;
|
||||
let qb = ((num + (den >> 1)) / den).min(MAX_FINE_BITS);
|
||||
mb += c * qb << BITRES;
|
||||
mb += (c * qb) << BITRES;
|
||||
mb
|
||||
};
|
||||
let w = c * ((EBANDS[j + 1] - EBANDS[j]) << i);
|
||||
@@ -263,21 +264,19 @@ pub struct Allocation {
|
||||
pub fine_priority: [i32; NB_EBANDS],
|
||||
}
|
||||
|
||||
/// Per-band limits, boosts and available budget for the allocation search.
|
||||
pub struct AllocationInput<'a> {
|
||||
pub offsets: &'a [i32; NB_EBANDS],
|
||||
pub cap: &'a [i32; NB_EBANDS],
|
||||
pub trim: i32,
|
||||
pub bits: i32,
|
||||
}
|
||||
|
||||
/// `clt_compute_allocation`, encoder side. Stereo frames are always coded as dual (L/R) stereo
|
||||
/// with no intensity bands, and no band is skipped voluntarily.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn compute_allocation(
|
||||
m: &Mode,
|
||||
start: usize,
|
||||
end: usize,
|
||||
offsets: &[i32; NB_EBANDS],
|
||||
cap: &[i32; NB_EBANDS],
|
||||
alloc_trim: i32,
|
||||
total: i32,
|
||||
c: usize,
|
||||
lm: usize,
|
||||
enc: &mut RangeEncoder,
|
||||
) -> Allocation {
|
||||
pub fn compute_allocation(m: &Mode, frame: CeltFrame, input: AllocationInput<'_>, enc: &mut RangeEncoder) -> Allocation {
|
||||
let CeltFrame { start, end, channels: c, lm } = frame;
|
||||
let AllocationInput { offsets, cap, trim: alloc_trim, bits: total } = input;
|
||||
let ci = c as i32;
|
||||
let lmi = lm as i32;
|
||||
let mut total = total.max(0);
|
||||
@@ -302,8 +301,8 @@ pub fn compute_allocation(
|
||||
let mut trim_offset = [0i32; NB_EBANDS];
|
||||
for j in start..end {
|
||||
let w = EBANDS[j + 1] - EBANDS[j];
|
||||
thresh[j] = (ci << BITRES).max((3 * w << lmi << BITRES) >> 4);
|
||||
trim_offset[j] = ci * w * (alloc_trim - 5 - lmi) * (end as i32 - j as i32 - 1) * (1 << (lmi + BITRES as i32)) >> 6;
|
||||
thresh[j] = (ci << BITRES).max(((3 * w) << lmi << BITRES) >> 4);
|
||||
trim_offset[j] = (ci * w * (alloc_trim - 5 - lmi) * (end as i32 - j as i32 - 1) * (1 << (lmi + BITRES as i32))) >> 6;
|
||||
if w << lmi == 1 {
|
||||
trim_offset[j] -= ci << BITRES;
|
||||
}
|
||||
@@ -317,7 +316,7 @@ pub fn compute_allocation(
|
||||
let mid = (lo + hi) >> 1;
|
||||
for j in (start..end).rev() {
|
||||
let n = EBANDS[j + 1] - EBANDS[j];
|
||||
let mut bitsj = ci * n * (ALLOC[mid as usize][j] as i32) << lmi >> 2;
|
||||
let mut bitsj = (ci * n * (ALLOC[mid as usize][j] as i32)) << lmi >> 2;
|
||||
if bitsj > 0 {
|
||||
bitsj = (bitsj + trim_offset[j]).max(0);
|
||||
}
|
||||
@@ -342,8 +341,8 @@ pub fn compute_allocation(
|
||||
lo -= 1;
|
||||
for j in start..end {
|
||||
let n = EBANDS[j + 1] - EBANDS[j];
|
||||
let mut bits1j = ci * n * (ALLOC[lo as usize][j] as i32) << lmi >> 2;
|
||||
let mut bits2j = if hi >= nb_alloc { cap[j] } else { ci * n * (ALLOC[hi as usize][j] as i32) << lmi >> 2 };
|
||||
let mut bits1j = (ci * n * (ALLOC[lo as usize][j] as i32)) << lmi >> 2;
|
||||
let mut bits2j = if hi >= nb_alloc { cap[j] } else { (ci * n * (ALLOC[hi as usize][j] as i32)) << lmi >> 2 };
|
||||
if bits1j > 0 {
|
||||
bits1j = (bits1j + trim_offset[j]).max(0);
|
||||
}
|
||||
@@ -361,27 +360,27 @@ pub fn compute_allocation(
|
||||
bits1[j] = bits1j;
|
||||
bits2[j] = bits2j;
|
||||
}
|
||||
interp_bits2pulses(m, start, end, skip_start, &bits1, &bits2, &thresh, cap, total, skip_rsv, intensity_rsv, dual_stereo_rsv, c, lm, enc)
|
||||
let interpolation =
|
||||
AllocationInterpolation { skip_start, bits1: &bits1, bits2: &bits2, thresh: &thresh, cap, total, skip_rsv, intensity_rsv, dual_stereo_rsv };
|
||||
interp_bits2pulses(m, frame, interpolation, enc)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn interp_bits2pulses(
|
||||
m: &Mode,
|
||||
start: usize,
|
||||
end: usize,
|
||||
/// Bracketing allocation vectors and signalling reserves for the interpolation stage.
|
||||
struct AllocationInterpolation<'a> {
|
||||
skip_start: usize,
|
||||
bits1: &[i32; NB_EBANDS],
|
||||
bits2: &[i32; NB_EBANDS],
|
||||
thresh: &[i32; NB_EBANDS],
|
||||
cap: &[i32; NB_EBANDS],
|
||||
mut total: i32,
|
||||
bits1: &'a [i32; NB_EBANDS],
|
||||
bits2: &'a [i32; NB_EBANDS],
|
||||
thresh: &'a [i32; NB_EBANDS],
|
||||
cap: &'a [i32; NB_EBANDS],
|
||||
total: i32,
|
||||
skip_rsv: i32,
|
||||
mut intensity_rsv: i32,
|
||||
mut dual_stereo_rsv: i32,
|
||||
c: usize,
|
||||
lm: usize,
|
||||
enc: &mut RangeEncoder,
|
||||
) -> Allocation {
|
||||
intensity_rsv: i32,
|
||||
dual_stereo_rsv: i32,
|
||||
}
|
||||
|
||||
fn interp_bits2pulses(m: &Mode, frame: CeltFrame, interpolation: AllocationInterpolation<'_>, enc: &mut RangeEncoder) -> Allocation {
|
||||
let CeltFrame { start, end, channels: c, lm } = frame;
|
||||
let AllocationInterpolation { skip_start, bits1, bits2, thresh, cap, mut total, skip_rsv, mut intensity_rsv, mut dual_stereo_rsv } = interpolation;
|
||||
let ci = c as i32;
|
||||
let alloc_floor = ci << BITRES;
|
||||
let stereo = (c > 1) as i32;
|
||||
@@ -393,7 +392,7 @@ fn interp_bits2pulses(
|
||||
let mut psum = 0;
|
||||
let mut done = false;
|
||||
for j in (start..end).rev() {
|
||||
let tmp = bits1[j] + (mid * bits2[j] >> ALLOC_STEPS);
|
||||
let tmp = bits1[j] + ((mid * bits2[j]) >> ALLOC_STEPS);
|
||||
if tmp >= thresh[j] || done {
|
||||
done = true;
|
||||
psum += tmp.min(cap[j]);
|
||||
@@ -411,7 +410,7 @@ fn interp_bits2pulses(
|
||||
let mut psum = 0;
|
||||
let mut done = false;
|
||||
for j in (start..end).rev() {
|
||||
let mut tmp = bits1[j] + (lo * bits2[j] >> ALLOC_STEPS);
|
||||
let mut tmp = bits1[j] + ((lo * bits2[j]) >> ALLOC_STEPS);
|
||||
if tmp < thresh[j] && !done {
|
||||
tmp = if tmp >= alloc_floor { alloc_floor } else { 0 };
|
||||
} else {
|
||||
@@ -500,9 +499,9 @@ fn interp_bits2pulses(
|
||||
if n == 2 {
|
||||
offset += (den << BITRES) >> 2;
|
||||
}
|
||||
if bits[j] + offset < den * 2 << BITRES {
|
||||
if bits[j] + offset < (den * 2) << BITRES {
|
||||
offset += nclogn >> 2;
|
||||
} else if bits[j] + offset < den * 3 << BITRES {
|
||||
} else if bits[j] + offset < (den * 3) << BITRES {
|
||||
offset += nclogn >> 3;
|
||||
}
|
||||
let mut eb = (bits[j] + offset + (den << (BITRES - 1))).max(0);
|
||||
@@ -513,7 +512,7 @@ fn interp_bits2pulses(
|
||||
eb = eb.min(MAX_FINE_BITS);
|
||||
ebits[j] = eb;
|
||||
fine_priority[j] = (eb * (den << BITRES) >= bits[j] + offset) as i32;
|
||||
bits[j] -= ci * eb << BITRES;
|
||||
bits[j] -= (ci * eb) << BITRES;
|
||||
} else {
|
||||
excess = (bit - (ci << BITRES)).max(0);
|
||||
bits[j] = bit - excess;
|
||||
@@ -523,7 +522,7 @@ fn interp_bits2pulses(
|
||||
if excess > 0 {
|
||||
let extra_fine = (excess >> (stereo + BITRES as i32)).min(MAX_FINE_BITS - ebits[j]);
|
||||
ebits[j] += extra_fine;
|
||||
let extra_bits = extra_fine * ci << BITRES;
|
||||
let extra_bits = (extra_fine * ci) << BITRES;
|
||||
fine_priority[j] = (extra_bits >= excess - balance) as i32;
|
||||
excess -= extra_bits;
|
||||
}
|
||||
|
||||
@@ -16,8 +16,12 @@ mod pulses;
|
||||
#[allow(dead_code)]
|
||||
pub(crate) mod tables;
|
||||
|
||||
use lpc::*;
|
||||
use tables::*;
|
||||
use lpc::{MAX_LPC_ORDER, div32_varq, inverse32_varq, nlsf2a, rshift_round, sat16, smlawb, smulwb, smulww};
|
||||
use tables::{
|
||||
DELTA_GAIN, GAIN_MSB, LTP_FILTER, LTP_PERIODICITY, LTP_SCALE, LTP_TAPS_0, LTP_TAPS_1, LTP_TAPS_2, MID_ONLY, NLSF_EXT, NLSF_INTERP, NLSF_SEL_NBMB,
|
||||
NLSF_SEL_WB, NLSF_STAGE1, NLSF_STAGE2, PITCH_CONTOUR, PITCH_HIGH, PITCH_LOW, STEREO_PRED_JOINT, STEREO_WEIGHTS_Q13, TYPE_ACTIVE, TYPE_INACTIVE, UNIFORM3,
|
||||
UNIFORM4, UNIFORM5, UNIFORM8,
|
||||
};
|
||||
|
||||
use crate::range::RangeEncoder;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Encoder-side signal analysis for SILK (own design): windowed autocorrelation LPC, LPC → NLSF
|
||||
//! conversion, open-loop pitch search and LTP codebook search.
|
||||
|
||||
use super::tables::*;
|
||||
use super::tables::{CB_NB_20, CB_WB_20, LTP_FILTER, LTP_PERIODICITY, LTP_TAPS_0, LTP_TAPS_1, LTP_TAPS_2};
|
||||
|
||||
/// Short-term prediction coefficients `a` (prediction `x[n] ≈ Σ a[j] x[n-1-j]`) from the
|
||||
/// windowed segment `x`, with a Gaussian lag window and white-noise correction.
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
//! spec-derived `filmcraft-opus` decoder (MIT OR Apache-2.0): the encoder must reconstruct the
|
||||
//! quantised NLSFs and LPC coefficients bit-exactly as the decoder does.
|
||||
|
||||
use super::tables::*;
|
||||
use super::tables::{
|
||||
COS_Q12, LSF_ORDER_NBMB, LSF_ORDER_WB, NLSF_CB_NBMB, NLSF_CB_WB, NLSF_MIN_SPACING_NBMB, NLSF_MIN_SPACING_WB, NLSF_PRED_NBMB, NLSF_PRED_WB, NLSF_PSEL_NBMB,
|
||||
NLSF_PSEL_WB,
|
||||
};
|
||||
|
||||
pub const MAX_LPC_ORDER: usize = 16;
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
//! dequantisation exactly. The search strategy is our own.
|
||||
|
||||
use super::lpc::{MAX_LPC_ORDER, nlsf_decode, smlawb, sqrt_approx};
|
||||
use super::tables::*;
|
||||
use super::tables::{
|
||||
NLSF_CB_NBMB, NLSF_CB_WB, NLSF_EXT, NLSF_PRED_NBMB, NLSF_PRED_WB, NLSF_PSEL_NBMB, NLSF_PSEL_WB, NLSF_SEL_NBMB, NLSF_SEL_WB, NLSF_STAGE1, NLSF_STAGE2,
|
||||
};
|
||||
|
||||
/// Number of stage-1 candidates refined with stage 2.
|
||||
const SURVIVORS: usize = 8;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//! with LSB escapes, the recursive shell code, LSBs and signs, written in exactly the order the
|
||||
//! decoder reads them.
|
||||
|
||||
use super::tables::*;
|
||||
use super::tables::{EXC_LSB, EXC_SIGN, PULSE_COUNT, RATE_LEVEL, SHELL_2, SHELL_4, SHELL_8, SHELL_16};
|
||||
use crate::range::RangeEncoder;
|
||||
|
||||
/// Largest pulse magnitude the quantiser produces (keeps every 16-sample block codable).
|
||||
|
||||
Reference in New Issue
Block a user