gopus
May 5, 2026 ยท View on GitHub
Pure Go Opus codec for Go applications.
gopus implements Opus (RFC 6716) and Ogg Opus (RFC 7845) in pure Go. It is built for real-time use: no cgo, no C toolchain, and caller-owned buffers on the main encode/decode hot path.
Status
gopus is usable today, but it is still pre-v1.
- Recommended starting surface:
Encoder,Decoder,MultistreamEncoder,MultistreamDecoder,Reader,Writer, andcontainer/ogg. - The main API target is the zero-allocation caller-owned path:
func (d *Decoder) Decode(data []byte, pcm []float32) (int, error)func (e *Encoder) Encode(pcm []float32, data []byte) (int, error)
- The default build intentionally does not support every optional libopus build-time extension. It supports
SetDNNBlob(...); QEXT and DRED are tag-gated, and OSCE BWE remains quarantine-only. See Optional Extensions for the supported, tag-gated, and unsupported matrix. - Low-level packages such as
celt,silk,hybrid,rangecoding, andplcare implementation detail, not a stable public contract yet. - Validation and parity work is pinned against libopus 1.6.1.
- No tagged release has been published yet. If you adopt
gopusbeforev0.1.0, pin the exact version you validate.
Trust And Verification
- Released version: none yet.
docs/releases/v0.1.0.mdis prepared release notes, butv0.1.0is not a release until the tag and GitHub Release are both published. - Latest release evidence: after publication, inspect the
release-evidence-v0.1.0.mdsummary andrelease-evidence-v0.1.0.tar.gzbundle attached to the GitHub Release; before then, runmake release-evidencelocally. - CI guardrails: required checks and branch protection.
- Security policy: private reporting and supported versions.
- Release process: release checklist.
- Supply chain: Dependabot, Scorecard, action review, and release provenance plan.
- Downstream import check: external consumer smoke test, run by
make test-consumer-smoke.
Installation
go get github.com/thesyncim/gopus
Requirements:
- Go 1.25+
- No cgo or external C toolchain for normal builds
Performance Snapshot
Official RFC 8251 test-vector decode benchmarks use pinned libopus 1.6.1 as the baseline, with the same preloaded packets, reset cadence, and 48 kHz stereo output. Current checked-in results were measured on Apple M4 Max with Go 1.26.0 and Go PGO profile default.pgo; the full report uses median-of-3 runs at 200ms, 1s, and 5s minimum run times. The table below highlights the 5s row. Ratios above 1.00x mean gopus is slower than libopus.
| Path | gopus ns/sample | libopus ns/sample | gopus/libopus | gopus allocs/op |
|---|---|---|---|---|
| Float32 decode | 19.78 | 19.36 | 1.02x | 0 |
| Int16 decode | 20.07 | 19.52 | 1.03x | 0 |
See the full Markdown report in Official Test Vector Decode Performance. Reproduce it with BENCH_TESTVECTORS_COMPARE_CASES=aggregate BENCH_TESTVECTORS_COMPARE_PATHS=all BENCH_TESTVECTORS_COMPARE_TIMES=200,1000,5000 BENCH_TESTVECTORS_COMPARE_COUNT=3 make bench-testvectors-compare.
Quick Start
Use caller-owned buffers in real-time paths.
package main
import (
"log"
"github.com/thesyncim/gopus"
)
func main() {
const sampleRate = 48000
const channels = 2
enc, err := gopus.NewEncoder(gopus.EncoderConfig{
SampleRate: sampleRate,
Channels: channels,
Application: gopus.ApplicationAudio,
})
if err != nil {
log.Fatal(err)
}
decCfg := gopus.DefaultDecoderConfig(sampleRate, channels)
dec, err := gopus.NewDecoder(decCfg)
if err != nil {
log.Fatal(err)
}
pcmIn := make([]float32, 960*channels)
packetBuf := make([]byte, 4000)
pcmOut := make([]float32, decCfg.MaxPacketSamples*channels)
nPacket, err := enc.Encode(pcmIn, packetBuf)
if err != nil {
log.Fatal(err)
}
if nPacket == 0 {
return
}
nSamples, err := dec.Decode(packetBuf[:nPacket], pcmOut)
if err != nil {
log.Fatal(err)
}
decoded := pcmOut[:nSamples*channels]
_ = decoded
}
Packet loss concealment uses dec.Decode(nil, pcmOut). If you prefer convenience over zero-allocation behavior, allocating helpers such as EncodeFloat32 and EncodeInt16Slice are also available.
Support Matrix
| Area | Status | Notes |
|---|---|---|
| Mono/stereo encode/decode | Supported | Encoder / Decoder with caller-owned buffers |
| Multistream encode/decode | Supported | Default mappings for 1-8 channels; explicit mappings up to 255 channels |
| Ogg Opus container | Supported | container/ogg reader/writer |
| Streaming facade | Supported | Reader / Writer |
| Allocating convenience helpers | Supported | Simpler to use, but not zero-allocation |
| Low-level codec packages | Experimental | May change before v1 |
| Optional libopus build-time extensions | Mixed | Default builds support SetDNNBlob(...) only. QEXT requires -tags gopus_qext; DRED control/standalone surfaces require -tags gopus_dred; OSCE BWE remains unsupported outside quarantine builds. See Optional Extensions |
Environment and codec expectations:
| Topic | Current expectation |
|---|---|
| Go versions | Go 1.25+ is required; scheduled safety automation also exercises Go 1.26 |
| CI platforms | Linux, macOS, and Windows |
| Optimized architectures | amd64 and arm64 have tuned assembly kernels; other architectures use pure Go fallbacks |
| Sample rates | 8000, 12000, 16000, 24000, 48000 Hz |
| Frame durations | 2.5 ms to 120 ms, depending on mode |
| Channels | Encoder / Decoder: 1-2; default multistream: 1-8; explicit multistream: up to 255 channels |
Encoder, Decoder, MultistreamEncoder, and MultistreamDecoder are not safe for concurrent use. Use one instance per goroutine.
Verification
If you want to evaluate or contribute to the codec, these are the main entry points:
go test ./...make test-qualitymake bench-guardmake bench-testvectorsmake bench-testvectors-comparemake verify-production
make ensure-libopus bootstraps the pinned libopus 1.6.1 reference used by parity and quality checks. make ensure-testvectors fetches the official RFC 8251 vectors; benchmark targets that need them run it automatically. Some verification paths also expect ffmpeg and opusdec to be available.
Docs and Project Hygiene
- Go package docs
- Official test-vector performance
- Optional extension policy
- Examples guide
- Release notes
- Contributing guide
- Security policy
- Code of conduct
- Maintainer docs
- Assembly notes
License
BSD 3-Clause. See LICENSE.