// celt_anti_collapse.mbt
//
// 反塌缩处理(RFC 6716 §4.3.5 Anti-collapse Processing)。
//
// 瞬态帧的多个短 MDCT 可能让某些带在某些短块上能量归零,产生刺耳
// 伪影。解码端在瞬态且预算够时读一个反塌缩位;置位则对每个「塌缩」
// 的短块注入伪随机信号,幅度由该带两帧历史能量的较小者导出,注入后
// 对带区间重新归一化以保持能量守恒(§4.3.5 的两句要求)。
//
// 对应参考实现 celt_bands.c 的 anti_collapse(浮点路径)与
// celt_vq.c 的 renormalise_vector:
//
//   - 能量域与 §4.3.2 状态一致(log2 幅度),Ediff = logE −
//     min(prev1, prev2) 下限 0;单声道解码还要与 2*nbEBands 布局里
//     本带的声道 1 槽位取 max(参考实现 `!encode && C==1` 分支);
//   - 注入幅度 r = min(thresh, 2·2^(−Ediff)·[LM=3 ×√2]) / √(N0<> LM / −8) 按 1/8 bit 深度衰减;
//   - 塌缩判定读 collapse mask 的 bit k(短块序号),噪声符号来自
//     celt_lcg_rand 的 bit15,整段按 uint32 环绕;
//   - 频谱布局与 MDCT 一致:带 i 的带内下标是 (j< Int64 {
  (seed * 1664525L + 1013904223L) & 0xFFFFFFFFL
}

///|
/// 带区间重新归一化(celt_vq.c 的 renormalise_vector,浮点路径):
/// `x *= gain / sqrt(EPSILON + Σx²)`,就地修改 `x[off.. Unit {
  let mut e = 0.000000000000001
  for j in 0..rng 的拷贝)。
pub fn celt_anti_collapse(
  x : Array[Double],
  collapse_masks : Array[Int],
  lm : Int,
  start : Int,
  end : Int,
  band_log_e : Array[Double],
  prev1_log_e : Array[Double],
  prev2_log_e : Array[Double],
  pulses : Array[Int],
  seed : Int64,
) -> Unit {
  let m = 1 << lm
  let nb = CEL_NB_EBANDS
  let mut rng = seed
  for i in start..> lm
    let thresh = 0.5 *
      @math.exp(0.6931471805599453094 * (-0.125 * depth.to_double()))
    let sqrt_1 = 1.0 / @math.pow((n0 << lm).to_double(), 0.5)
    // 单声道解码:prev 与 2*nbEBands 布局的声道 1 槽位取 max
    let mut prev1 = prev1_log_e[i]
    let mut prev2 = prev2_log_e[i]
    if prev1_log_e[nb + i] > prev1 {
      prev1 = prev1_log_e[nb + i]
    }
    if prev2_log_e[nb + i] > prev2 {
      prev2 = prev2_log_e[nb + i]
    }
    let mut ediff = band_log_e[i] - (if prev1 < prev2 { prev1 } else { prev2 })
    // 下限 0 照搬参考实现(其定点路径用它防 exp2 上溢)。浮点路径里这
    // 一步不可观测:ediff≤0 时 r≥2 而 thresh≤0.5,随后 min 恒取 thresh,
    // 截不截断结果相同——故变异验证不覆盖此行(等效变异)。
    if ediff < 0.0 {
      ediff = 0.0
    }
    let mut r = 2.0 * @math.exp(0.6931471805599453094 * -ediff)
    if lm == 3 {
      r = r * 1.41421356
    }
    if thresh < r {
      r = thresh
    }
    r = r * sqrt_1
    let base = celt_eband(i, m)
    let mut renormalize = false
    for k in 0..> k) & 1) == 0 {
        for j in 0.. Int {
  if is_transient && lm >= 2 && bits >= (lm + 2) << CEL_BITRES {
    1 << CEL_BITRES
  } else {
    0
  }
}

///|
/// 反塌缩标志位解码(celt_decoder.c:预留了才读,读 1 个 raw bit)。
pub fn celt_decode_anti_collapse_flag(dec : RangeDecoder, rsv : Int) -> Int {
  if rsv > 0 {
    dec.dec_bits(1)
  } else {
    0
  }
}