纯 MoonBit 实现的 OGG/Opus 音频解码器,不依赖任何 C 库或系统编解码器
当前状态:进行中。 已完成 Ogg Opus 容器解封装(RFC 7845:页解析、跨页 packet 重组、OpusHead/OpusTags 解析与页序校验)、音频包结构解析 (RFC 6716 §3:TOC、code 0–3 帧打包、CBR/VBR、填充与畸形包分类)、 CELT 频域解码全链(RFC 6716 §4.3,见下)与帧合成模块(IMDCT、基音梳状 滤波),各模块均以双独立实现金标交叉验证。合成链路的端到端接线仍在 进行,尚未提供 PCM 输出;解码范围为 CELT-only(SILK 与 hybrid 模式不在范围内)。
import {
"LL728/moonopus",
}fn inspect(data : Bytes) {
match @moonopus.open_opus(data) {
Ok(stream) => println(
"\{stream.channels()} ch, pre-skip \{stream.pre_skip()}, \{stream.packet_count()} audio packets",
)
Err(e) => println("not a valid Ogg Opus stream: \{e}")
}
}fn inspect_packet(pkt : Bytes) {
match @moonopus.parse_opus_packet(pkt) {
Ok(p) => println(
"config \{p.config()}: \{p.frame_count()} frame(s), \{p.duration_48k()} samples @48k",
)
Err(e) => println("malformed packet: \{e}")
}
}moon test --target wasm-gc # 运行测试
moon test --target js
python tools/gen_fixtures.py # 重新生成测试样例(测试页由独立实现构造)pub struct CeltFrameHeader {
silence : Bool
postfilter_on : Bool
postfilter_pitch : Int
postfilter_gain : Double
postfilter_tapset : Int
is_transient : Bool
intra : Bool
}pub struct CeltFrameResult {
header : CeltFrameHeader
spectrum : Array[Double]
freq : Array[Double]
collapse_masks : Array[Int]
seed : Int64
}pub struct CeltPartitionLeaf {
n : Int
blocks : Int
lm : Int
b : Int
q : Int
used : Int
fill : Int
pulses : Array[Int]
}pub struct CeltPartitionResult {
splits : Array[CeltThetaSplit]
leaves : Array[CeltPartitionLeaf]
remaining_bits : Int
}pub struct CeltThetaSplit {
inv : Int
imid : Int
iside : Int
delta : Int
itheta : Int
qalloc : Int
qn : Int
}pub struct OggPage {
data : Bytes
offset : Int
header_type : Int
granule_position : Int64
serial_number : UInt
page_sequence : UInt
checksum : UInt
n_segments : Int
body_len : Int
}pub enum OpusBandwidth {
Nb
Mb
Wb
Swb
Fb
}pub enum OpusMode {
Silk
Hybrid
Celt
}pub struct OpusPacket {
config : Int
stereo : Bool
mode : OpusMode
bandwidth : OpusBandwidth
frame_samples : Int
frame_count : Int
frame_lengths : Array[Int]
is_vbr : Bool
padding_bytes : Int
}type PacketAssemblerpub struct RangeDecoder {
data : Bytes
nbytes : Int
offs : Int
leftover : Int
val : Int64
rng : Int64
raw_read : Int
skipped : Int
}let CEL_DEEMPH_COEF : Doublelet CEL_OVERLAP : Intfn cel_unquant_coarse_energy(dec : RangeDecoder, old_e : Array[Double], start : Int, end : Int, intra : Bool, lm : Int) -> Unitfn cel_unquant_energy_finalise(dec : RangeDecoder, old_e : Array[Double], start : Int, end : Int, fine_quant : Array[Int], fine_priority : Array[Int], bits_left : Int) -> Unitfn cel_unquant_fine_energy(dec : RangeDecoder, old_e : Array[Double], start : Int, end : Int, extra_quant : Array[Int]) -> Unitfn celt_anti_collapse_rsv(is_transient : Bool, lm : Int, bits : Int) -> Intfn celt_bitexact_cos(x : Int) -> Intfn celt_bitexact_log2tan(isin : Int, icos : Int) -> Intfn celt_bits2pulses(band : Int, lm : Int, bits : Int) -> Intfn celt_compute_allocation(dec : RangeDecoder, start : Int, end : Int, offsets : Array[Int], cap : Array[Int], alloc_trim : Int, total : Int, lm : Int) -> CeltAllocationfn celt_compute_qn(n : Int, b : Int, offset : Int, pulse_cap : Int, stereo : Bool) -> Intfn celt_compute_theta(dec : RangeDecoder, band : Int, lm : Int, n : Int, b : Int, blocks : Int, blocks0 : Int, stereo : Bool, intensity : Int, remaining_bits : Int, disable_inv : Bool, fill : Int) -> (CeltThetaSplit, Int, Int)fn celt_decode_alloc_flags(dec : RangeDecoder, start : Int, end : Int, cap : Array[Int], frame_bytes : Int, lm : Int) -> CeltAllocFlagsfn celt_decode_frame(dec : RangeDecoder, frame_bytes : Int, start : Int, end : Int, lm : Int, state : CeltDecoderState) -> CeltFrameResultfn celt_decode_frame_header(dec : RangeDecoder, frame_bytes : Int, start : Int, lm : Int) -> CeltFrameHeaderfn celt_decode_quant_partition(dec : RangeDecoder, band : Int, lm : Int, n : Int, b : Int, blocks : Int, fill : Int, remaining_bits : Int) -> CeltPartitionResultfn celt_decode_tf(dec : RangeDecoder, start : Int, end : Int, is_transient : Bool, lm : Int, frame_bytes : Int) -> Array[Int]fn celt_eband(i : Int, m : Int) -> Intfn celt_get_pulses(i : Int) -> Intfn celt_isqrt32(v : Int) -> Intfn celt_lcg_rand(seed : Int64) -> Int64fn celt_lm_of_frame_samples(samples : Int) -> Int?fn celt_max_bin(m : Int) -> Intfn celt_pulses2bits(band : Int, lm : Int, pulses : Int) -> Intfn celt_quant_all_bands(dec : RangeDecoder, x : Array[Double], start : Int, end : Int, lm : Int, short_blocks : Bool, pulses : Array[Int], tf_res : Array[Int], coded_bands : Int, total_bits : Int, balance : Int, spread : Int, seed : Int64, masks : Array[Int]) -> Int64fn celt_quant_band(dec : RangeDecoder, x : Array[Double], lowband : Array[Double], band : Int, lm : Int, n : Int, b : Int, blocks : Int, tf_change : Int, fill : Int, gain : Double, spread : Int, seed : Int64, remaining : Int, lowband_out : Array[Double]) -> (Int, Int64, Int)fn celt_window(i : Int, overlap : Int) -> Doublefn ogg_crc32(data : Bytes) -> UIntfn ogg_crc32_update(crc : UInt, data : Bytes, start : Int, len : Int) -> UIntInstall
Download zip纯 MoonBit 实现的 OGG/Opus 音频解码器,不依赖任何 C 库或系统编解码器