// decoder.mbt
//
// Vorbis 解码主循环:读 mode、解 floor/residue、反耦合、IMDCT、加窗重叠,输出 PCM。

///|
/// 有状态的解码器。
pub struct Decoder {
  info : VorbisInfo
  setup : VorbisSetup
  window0 : Array[Float]
  window1 : Array[Float]
  previous_window : Array[Array[Float]]
  previous_length : Array[Int]
}

///|
/// 构造解码器,预计算两个 block size 的 window,并按声道数分配重叠缓冲。
pub fn Decoder::new(info : VorbisInfo, setup : VorbisSetup) -> Decoder {
  let window0 = compute_window(info.blocksize0 >> 1)
  let window1 = compute_window(info.blocksize1 >> 1)
  let previous_window : Array[Array[Float]] = []
  let previous_length : Array[Int] = []
  for _ in 0..> 1) {
      w.push(0)
    }
    previous_window.push(w)
    previous_length.push(0)
  }
  { info, setup, window0, window1, previous_window, previous_length, }
}

///|
/// 解码一个音频 packet,返回每声道的 PCM 样本(首帧为空)。
pub fn Decoder::decode_packet(
  self : Decoder,
  br : BitReader,
) -> Result[Array[Array[Float]], String] {
  // 音频 packet 的第一个 bit 是 packet type(0 = audio,1 = header)
  if br.read_bits(1) != 0 {
    return Err("not an audio packet")
  }
  let mode_number = br.read_bits(ilog(self.setup.modes.length() - 1))
  let mode = self.setup.modes[mode_number]
  let blockflag = mode.blockflag
  let n = if blockflag == 1 {
    self.info.blocksize1
  } else {
    self.info.blocksize0
  }
  let n2 = n >> 1
  let prev = if blockflag == 1 { br.read_bits(1) } else { 0 }
  let next = if blockflag == 1 { br.read_bits(1) } else { 0 }

  // window 边界:长短块切换时,sin 窗口区域按小块的尺寸收窄
  let left_start = if blockflag == 1 && prev == 0 {
    (n - self.info.blocksize0) >> 2
  } else {
    0
  }
  let right_start = if blockflag == 1 && next == 0 {
    (3 * n - self.info.blocksize0) >> 2
  } else {
    n2
  }
  let right_end = if blockflag == 1 && next == 0 {
    (3 * n + self.info.blocksize0) >> 2
  } else {
    n
  }

  let mapping = self.setup.mappings[mode.mapping]
  let channels = self.info.channels

  // floor 解码:解出本声道的包络曲线,并记下它是否真的给了数据
  let floor_curves : Array[Array[Float]] = []
  let has_floor : Array[Int] = []
  for ch in 0.. 1 { mapping.mux[ch] } else { 0 }
    let floor = self.setup.floors[mapping.floor[mux]]
    match floor {
      Floor::Type1(f1) => {
        // floor 1 自带一位「floor 已用」标志;未置位时本声道没有包络。
        if br.read_bits(1) == 0 {
          has_floor.push(0)
          floor_curves.push([])
          continue
        }
        let final_y = match f1.decode(br, self.setup.codebooks) {
          Ok(y) => y
          Err(e) => return Err(e)
        }
        has_floor.push(1)
        floor_curves.push(f1.synthesize(final_y, n2))
      }
      Floor::Type0(f0) => {
        // floor 0 没有独立的标志位:幅度为 0 就表示本帧没有 floor 数据。
        // 这一点要读完幅度才知道,所以只能先解再看。
        let memo = match f0.decode(br, self.setup.codebooks) {
          Ok(m) => m
          Err(e) => return Err(e)
        }
        match memo {
          Some(lsp) => {
            has_floor.push(1)
            floor_curves.push(f0.synthesize(lsp, n2))
          }
          None => {
            has_floor.push(0)
            floor_curves.push([])
          }
        }
      }
    }
  }

  // 每声道系数缓冲(长度 n,容纳 type 2 的 2*n2 个系数)
  let channel_buffers : Array[Array[Float]] = []
  for _ in 0.. 1 { mapping.mux[ch] } else { 0 }
      if mux == s && has_floor[ch] == 1 {
        any_floor = true
      }
    }
    if any_floor {
      let residue = self.setup.residues[mapping.residue[s]]
      let sub_targets : Array[Array[Float]] = []
      for ch in 0.. 1 { mapping.mux[ch] } else { 0 }
        if mux == s {
          sub_targets.push(channel_buffers[ch])
        }
      }
      match residue.decode(br, self.setup.codebooks, sub_targets, n2) {
        Ok(_) => ()
        Err(e) => return Err(e)
      }
    }
  }

  // 反耦合:从最后一对耦合逆序还原 magnitude/angle 为左右声道
  for i in 0.. 0 {
        if a2 > 0 {
          m[j] = m2
          a[j] = m2 - a2
        } else {
          a[j] = m2
          m[j] = m2 + a2
        }
      } else if a2 > 0 {
        m[j] = m2
        a[j] = m2 + a2
      } else {
        a[j] = m2
        m[j] = m2 - a2
      }
    }
  }

  // floor 曲线应用:residue × floor(floor=0 的声道清零)
  for ch in 0.. 0 {
    self.previous_length[0] > 0
  } else {
    false
  }
  let out : Array[Array[Float]] = []
  for ch in 0.. 0 {
      let w = if pn == self.info.blocksize0 >> 1 {
        self.window0
      } else {
        self.window1
      }
      for j in 0..