// 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..