Phase 0 of the DRED integration (docs/PRD-dred-integration.md). No behavior change: inband FEC stays ON, no DRED, same bitrate, same quality. This commit unblocks Phase 1+ by getting us onto libopus 1.5.2 where DRED lives. Rationale for going straight to a custom DecoderHandle: opusic-c::Decoder's inner *mut OpusDecoder pointer is pub(crate), so we cannot reach it for the Phase 3 DRED reconstruction path. Running two parallel decoders (one for audio, one for DRED) would drift because the DRED decoder wouldn't see normal decode calls. Single unified DecoderHandle over raw opusic-sys is the only correct architecture, so we build it in Phase 0 rather than rewriting opus_dec.rs twice. Changes: - Cargo.toml (workspace + wzp-codec): remove audiopus 0.3.0-rc.0, add opusic-c 1.5.5 (bundled + dred features), opusic-sys 0.6.0 (bundled), bytemuck 1. Pinned exactly for reproducible libopus 1.5.2. - opus_enc.rs: rewritten against opusic_c::Encoder. Argument order for Encoder::new swapped (Channels first). set_inband_fec(bool) now maps to InbandFec::Mode1 (the libopus 1.5 equivalent of 1.3's LBRR). encode uses bytemuck::cast_slice<i16,u16> at the &[u16] boundary. - dred_ffi.rs (new): DecoderHandle wrapping *mut OpusDecoder directly via opusic-sys. Owns the allocation, frees on Drop. Exposes decode, decode_lost, and a pub(crate) as_raw_ptr() for the future Phase 3 DRED reconstruction. Send+Sync justified via &mut self access discipline. - opus_dec.rs: rewritten as a thin AudioDecoder impl over DecoderHandle. Behavior identical to pre-swap. Verification (Phase 0 acceptance gates): - cargo check --workspace: clean (30 pre-existing warnings in jni_bridge.rs unrelated to this work; zero in changed files). - cargo test -p wzp-codec: 53 tests pass (50 pre-swap + 6 new: 3 in dred_ffi.rs for DecoderHandle lifecycle, 3 in opus_enc.rs for version check and roundtrip). - linked_libopus_is_1_5 test asserts opusic_c::version() contains "1.5" — hard signal that the swap landed correctly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
35 lines
1.0 KiB
TOML
35 lines
1.0 KiB
TOML
[package]
|
|
name = "wzp-codec"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
rust-version.workspace = true
|
|
description = "WarzonePhone audio codec layer — Opus + Codec2 encoding/decoding"
|
|
|
|
[dependencies]
|
|
wzp-proto = { workspace = true }
|
|
tracing = { workspace = true }
|
|
|
|
# Opus bindings — libopus 1.5.2.
|
|
# opusic-c for the encoder (set_dred_duration lives here in Phase 1).
|
|
# opusic-sys for the decoder — we wrap the raw *mut OpusDecoder ourselves
|
|
# because opusic-c::Decoder.inner is pub(crate), blocking the unified
|
|
# decoder + DRED path we need in Phase 3.
|
|
opusic-c = { workspace = true }
|
|
opusic-sys = { workspace = true }
|
|
|
|
# Zero-cost slice reinterpretation for the i16 ↔ u16 boundary between
|
|
# our PCM buffers and opusic-c's encode API.
|
|
bytemuck = { workspace = true }
|
|
|
|
# Pure-Rust Codec2 implementation
|
|
codec2 = { workspace = true }
|
|
|
|
# RNG for comfort noise generation
|
|
rand = { workspace = true }
|
|
|
|
# ML-based noise suppression (pure-Rust port of RNNoise)
|
|
nnnoiseless = "0.5"
|
|
|
|
[dev-dependencies]
|