ζ₯ζ¬θͺ | English
github.com/darui3018823/opus is a stateful, Pure Go Opus codec library with
no runtime CGO dependency. It provides single-stream, multistream, surround,
projection/Ambisonics, packet transformation, and Ogg Opus APIs.
The decoder passes all 12 official RFC 8251 vectors with RMSE below 0.001 and is cross-checked against libopus 1.6.1. The encoder produces standards-compatible CELT, SILK-only, and hybrid packets, but is not bit-exact with libopus and does not reproduce every libopus mode/rate/quality decision. The authoritative implementation snapshot is docs/CURRENT_IMPLEMENTATION.md.
go get github.com/darui3018823/opusThe module currently declares Go 1.24.11 in go.mod.
package main
import (
"fmt"
"log"
"github.com/darui3018823/opus"
)
func main() {
const channels = 2
encoder, err := opus.NewEncoder(
opus.SampleRate48kHz,
channels,
opus.ApplicationAudio,
)
if err != nil {
log.Fatal(err)
}
// frameSize is samples per channel; PCM is interleaved.
pcm := make([]int16, opus.FrameSize20ms*channels)
packet, err := encoder.Encode(pcm, opus.FrameSize20ms)
if err != nil {
log.Fatal(err)
}
decoder, err := opus.NewDecoder(opus.SampleRate48kHz, channels)
if err != nil {
log.Fatal(err)
}
decoded := make([]int16, opus.MaxFrameSize*channels)
samplesPerChannel, err := decoder.Decode(packet, decoded)
if err != nil {
log.Fatal(err)
}
decoded = decoded[:samplesPerChannel*channels]
fmt.Println(samplesPerChannel, len(decoded)) // 960 1920
}Executable examples are included in the root package documentation and Ogg Opus package documentation.
| Area | Support |
|---|---|
| Sample rates | 8, 12, 16, 24, and 48 kHz |
| Single-stream channels | Mono and stereo |
| PCM APIs | Interleaved int16, signed 24-bit-in-int32, float32, and float64 |
| Encoder packet durations | CELT 2.5/5/10 ms; exact 20 ms multiples through 120 ms |
| Decoder packet durations | Valid Opus packets up to 120 ms |
| Coding modes | CELT encode/decode; voice-oriented SILK-only and hybrid encode; SILK/hybrid decode |
| Loss handling | Explicit-duration CELT/SILK/hybrid PLC and SILK LBRR in-band FEC in int16, signed 24-bit-in-int32, float32, and float64 |
| Multistream/surround | RFC self-delimited framing; families 0, 1 (through 7.1), and 255; matching PLC/FEC PCM variants |
| Projection/Ambisonics | RFC 8486 families 2 and 3; predefined first- through fifth-order family-3 matrices |
| Packet tools | Inspection, repacketizing, padding, soft clipping, LBRR detection, extensions |
| Ogg Opus | CRC/lacing, headers/tags, timing trims, chained reading, per-link seek, single-link writing |
| Runtime dependencies | Pure Go; CGO/libopus is optional and test-only under opusref |
MaxFrameSize is 5760 samples per channel at 48 kHz (120 ms).
MaxFrameBytes is the 1275-byte compressed-frame limit. MaxPacketSize is a
conservative bound for an unpadded single-stream packet; explicit padding may
exceed it.
DecodePLC, DecodePLC24, DecodePLCFloat32, and DecodePLCFloat conceal an
explicit missing duration. The duration may be any positive 2.5 ms multiple
through 120 ms. Before the first successfully decoded packet, and after
Reset, PLC returns zero concealment.
For in-band FEC, prefer DecodeFECWithDuration for int16 or the explicit-
duration DecodeFEC24, DecodeFECFloat32, and DecodeFECFloat variants. They
recover LBRR from the first Opus frame in the carrier and use PLC for an
unrecoverable prefix or when FEC is unavailable. The original DecodeFEC
remains a compatibility wrapper that infers the missing duration from the
carrier and retains its legacy CELT-only error behavior. MultistreamDecoder
provides the same PCM variants and duration contract; SurroundDecoder
inherits them. A returned FEC error does not commit partial decoder state.
Encoder, decoder, multistream, surround, projection, repacketizer, and Ogg
reader/writer values are stateful and are not safe for concurrent use. Use one
instance per logical stream, process packets in order, and serialize every
operation on an instance, including getters, controls, child stream access,
seeking, and Reset. Distinct instances may run concurrently. Do not copy an
instance after first use.
Codec methods borrow per-call PCM, packet, and destination slices only until
the call returns. Constructors copy mappings and matrices. Returned packet,
PCM, mapping, and matrix slices are caller-owned copies. Ogg readers and writers
borrow their io.Reader/io.Writer for the instance lifetime and do not close
it.
Where a codec type exposes Reset, it clears codec history and last-packet
observations while retaining configuration such as bitrate, application,
output gain, and phase-inversion controls. Reuse an instance after Reset only
for a new stream with the same configuration, or apply new controls explicitly.
CI downloads the unmodified RFC 8251 vector archive and runs all 12 decoder
vectors. Vector data is not committed, so local vector tests skip when
testdata/opus_newvectors/ is absent.
go test -count=1 ./...
go test -count=1 -run TestOfficialVectors .Optional opusref tests require a C toolchain and libopus. They compare decoder
output, interoperability, final ranges, FEC/PLC, multistream, projection, and
selected encoder quality behavior against libopus 1.6.1. They are reference
checks, not runtime dependencies.
go test -count=1 -tags opusref ./...The current CELT constrained-VBR and TF-allocation corrections are guarded by a 140-cell opt-in corpus scoreboard; the measured one-second byte totals stayed unchanged while the targeted music/mixed worst cases improved. Surround channel-role masking improved the weighted SNR of the deterministic 5.1 and 7.1 fixtures without changing elementary packet lengths. SILK scratch reuse is guarded by packet/final-range digests and reduced allocations in the recorded Windows amd64 benchmarks. These are regression fixtures and local measurements, not universal quality or performance guarantees; see the real-corpus scoreboard and the performance baseline for conditions and values.
Public decoder and packet/container parsing paths are designed to reject malformed input with errors instead of panicking. Stateful decoder sequences, PLC/FEC interleaving, encoder controls and extreme PCM (including floating-point edge cases), packet extensions, multistream framing, repacketizing, and Ogg Reader/Writer round trips have dedicated fuzz targets. CI runs the target set nightly on Linux amd64 and arm64.
This is a bounded API guarantee, not a claim that fuzzing proves correctness. Callers must still enforce application-level packet, stream, CPU, and memory budgets; fuzz coverage does not guarantee audio quality, timing availability, or protection against every denial-of-service pattern. Report suspected security issues through SECURITY.md, not a public issue.
Example local runs:
go test -run='^$' -fuzz='^FuzzDecoderSequence$' -fuzztime=60s .
go test -run='^$' -fuzz='^FuzzOggOpusReaderWriter$' -fuzztime=60s ./oggopus- Encoder output is standards-compatible but not bit-exact with libopus.
- SILK/hybrid encoding is voice-oriented and does not implement every libopus mode boundary, rate-control decision, or quality heuristic.
- DRED and QEXT packet extensions are transported opaquely; their codecs/DSP are not implemented.
- Projection family 3 uses predefined libopus 1.6.1 matrices; arbitrary custom encoder matrix generation is not provided.
- The Ogg Opus reader supports chained logical streams but not multiplexed physical-stream demultiplexing. Each Writer emits one logical stream.
- Not every libopus single-stream or multistream CTL has a public equivalent.
SetLSBDepthis retained as a compatibility hint but currently does not affect codec decisions.
go generate ./...
git diff --exit-code
go fmt ./...
go vet ./...
go test -count=1 ./...
go test -race -count=1 ./...
go test -run='^$' -bench '^BenchmarkPerf/' -benchmem .Normal CI runs native tests on Linux, macOS, and Windows for both amd64 and
arm64. The Windows arm64 runner is currently a GitHub public-preview image.
Generated-file drift, vet, and official vectors are separate Ubuntu jobs, and
the opusref workflow stays on Ubuntu with libopus. See the workflow files for
the exact current matrix.
- Go API reference
- Ogg Opus API reference
- Current implementation snapshot
- CTL and helper parity
- Performance baseline and benchmark method
- Historical architecture and design background
- Mode/rate policy differences
- Real-corpus scoreboard
- Developer guide
- Release checklist
- Possible v2 API changes
- Security policy
- Contributing guide
BSD 2-Clause License. See LICENSE.