Documentation
¶
Overview ¶
Package gopus implements the Opus audio codec in pure Go.
Opus is a lossy audio codec designed for interactive speech and music transmission. It supports bitrates from 6 to 510 kbit/s, sampling rates from 8 to 48 kHz, and frame sizes from 2.5 to 60 ms.
This implementation follows RFC 6716 and is compatible with the reference libopus implementation. It requires no cgo dependencies.
Quick Start ¶
Encoding:
enc, err := gopus.NewEncoder(48000, 2, gopus.ApplicationAudio)
if err != nil {
log.Fatal(err)
}
pcm := make([]float32, 960*2) // 20ms stereo at 48kHz
// ... fill pcm with audio samples ...
packet, err := enc.EncodeFloat32(pcm)
if err != nil {
log.Fatal(err)
}
Decoding:
cfg := gopus.DefaultDecoderConfig(48000, 2)
dec, err := gopus.NewDecoder(cfg)
if err != nil {
log.Fatal(err)
}
pcmOut := make([]float32, cfg.MaxPacketSamples*cfg.Channels)
n, err := dec.Decode(packet, pcmOut)
if err != nil {
log.Fatal(err)
}
Opus Modes ¶
Opus operates in three modes:
- SILK: speech-optimized, 8-24 kHz bandwidth
- CELT: audio-optimized, full 48 kHz bandwidth
- Hybrid: SILK for low frequencies + CELT for high frequencies
The encoder automatically selects the appropriate mode based on the Application hint provided to NewEncoder:
- ApplicationVoIP: Prefers SILK for speech
- ApplicationAudio: Prefers CELT/Hybrid for music
- ApplicationLowDelay: Uses CELT for minimum latency
Sample Formats ¶
Both int16 and float32 PCM formats are supported. float32 is the internal format and avoids conversion overhead. int16 is provided for compatibility with common audio APIs.
For float32, samples should be normalized to [-1.0, 1.0]. For int16, the full range [-32768, 32767] is used.
Stereo audio uses interleaved samples: L0, R0, L1, R1, ...
Thread Safety ¶
Encoder and Decoder instances are NOT safe for concurrent use. Each goroutine should create its own instance.
Buffer Sizing ¶
For caller-provided buffers:
- Decode output: max 5760 * channels samples (120ms at 48kHz, default cap)
- Encode output: 4000 bytes is sufficient for any Opus packet
Packet Loss Concealment ¶
When a packet is lost, pass nil to Decode to trigger packet loss concealment (PLC). The decoder will generate audio to conceal the gap:
if packetLost {
n, err = dec.Decode(nil, pcmOut) // PLC
} else {
n, err = dec.Decode(packet, pcmOut)
}
Packet Structure ¶
Each Opus packet starts with a TOC (Table of Contents) byte:
- Bits 7-3: Configuration (0-31)
- Bit 2: Stereo flag
- Bits 1-0: Frame count code (0-3)
Use ParseTOC to extract these fields, and ParsePacket to determine the frame boundaries within a packet.
Configuration ¶
The encoder supports various configuration options:
enc.SetBitrate(64000) // Target bitrate (6000-510000 bps) enc.SetComplexity(10) // Quality vs CPU (0-10) enc.SetFEC(true) // Forward error correction enc.SetDTX(true) // Discontinuous transmission enc.SetFrameSize(480) // Frame size (120-2880 samples)
Multistream (Surround Sound) ¶
For surround sound applications (5.1, 7.1, etc.), use MultistreamEncoder and MultistreamDecoder. These support 1-8 channels with standard Vorbis-style channel mapping per RFC 7845.
Multistream encoding example (5.1 surround):
enc, err := gopus.NewMultistreamEncoderDefault(48000, 6, gopus.ApplicationAudio)
if err != nil {
log.Fatal(err)
}
pcm := make([]float32, 960*6) // 20ms of 6-channel audio at 48kHz
// ... fill pcm with interleaved samples: FL, C, FR, RL, RR, LFE ...
packet, err := enc.EncodeFloat32(pcm)
if err != nil {
log.Fatal(err)
}
Multistream decoding example:
dec, err := gopus.NewMultistreamDecoderDefault(48000, 6)
if err != nil {
log.Fatal(err)
}
pcmOut := make([]float32, 960*6)
_, err = dec.Decode(packet, pcmOut)
if err != nil {
log.Fatal(err)
}
Supported channel configurations:
- 1: mono (1 stream, 0 coupled)
- 2: stereo (1 stream, 1 coupled)
- 3: 3.0 (2 streams, 1 coupled)
- 4: quad (2 streams, 2 coupled)
- 5: 5.0 (3 streams, 2 coupled)
- 6: 5.1 surround (4 streams, 2 coupled)
- 7: 6.1 surround (5 streams, 2 coupled)
- 8: 7.1 surround (5 streams, 3 coupled)
For custom channel mappings, use NewMultistreamEncoder and NewMultistreamDecoder with explicit stream and mapping parameters.
Example (RoundTrip) ¶
package main
import (
"fmt"
"math"
"github.com/thesyncim/gopus"
)
func main() {
// Complete encode-decode round trip
enc, _ := gopus.NewEncoder(48000, 1, gopus.ApplicationVoIP)
cfg := gopus.DefaultDecoderConfig(48000, 1)
dec, _ := gopus.NewDecoder(cfg)
pcmOut := make([]float32, cfg.MaxPacketSamples*cfg.Channels)
// 20ms of mono audio at 48kHz
input := make([]float32, 960)
for i := range input {
input[i] = float32(math.Sin(float64(i) * 0.02))
}
// Encode
packet, _ := enc.EncodeFloat32(input)
// Decode
n, _ := dec.Decode(packet, pcmOut)
fmt.Printf("Round trip: %d samples -> %d bytes -> %d samples\n",
len(input), len(packet), n)
}
Index ¶
- Constants
- Variables
- func ConfigFromParams(mode Mode, bandwidth Bandwidth, frameSize int) int
- func GenerateTOC(config uint8, stereo bool, frameCode uint8) byte
- func MultistreamPacketPad(data []byte, length, newLen, numStreams int) error
- func MultistreamPacketUnpad(data []byte, length, numStreams int) (int, error)
- func PacketPad(data []byte, length, newLen int) error
- func PacketUnpad(data []byte, length int) (int, error)
- func ValidConfig(config uint8) bool
- type Application
- type Bandwidth
- type BitrateMode
- type Decoder
- func (d *Decoder) Bandwidth() Bandwidth
- func (d *Decoder) Channels() int
- func (d *Decoder) DebugPrevMode() Mode
- func (d *Decoder) DebugPrevPacketStereo() bool
- func (d *Decoder) DebugPrevRedundancy() bool
- func (d *Decoder) Decode(data []byte, pcm []float32) (int, error)
- func (d *Decoder) DecodeInt16(data []byte, pcm []int16) (int, error)
- func (d *Decoder) DecodeWithFEC(data []byte, pcm []float32, fec bool) (int, error)
- func (d *Decoder) FinalRange() uint32
- func (d *Decoder) Gain() int
- func (d *Decoder) GetCELTDecoder() *celt.Decoder
- func (d *Decoder) GetSILKDecoder() *silk.Decoder
- func (d *Decoder) InDTX() bool
- func (d *Decoder) LastPacketDuration() int
- func (d *Decoder) Pitch() int
- func (d *Decoder) Reset()
- func (d *Decoder) SampleRate() int
- func (d *Decoder) SetGain(gainQ8 int) error
- type DecoderConfig
- type Encoder
- func (e *Encoder) Application() Application
- func (e *Encoder) Bandwidth() Bandwidth
- func (e *Encoder) Bitrate() int
- func (e *Encoder) BitrateMode() BitrateMode
- func (e *Encoder) Channels() int
- func (e *Encoder) Complexity() int
- func (e *Encoder) DTXEnabled() bool
- func (e *Encoder) Encode(pcm []float32, data []byte) (int, error)
- func (e *Encoder) EncodeFloat32(pcm []float32) ([]byte, error)
- func (e *Encoder) EncodeInt16(pcm []int16, data []byte) (int, error)
- func (e *Encoder) EncodeInt16Slice(pcm []int16) ([]byte, error)
- func (e *Encoder) FECEnabled() bool
- func (e *Encoder) FinalRange() uint32
- func (e *Encoder) ForceChannels() int
- func (e *Encoder) FrameSize() int
- func (e *Encoder) LSBDepth() int
- func (e *Encoder) Lookahead() int
- func (e *Encoder) MaxBandwidth() Bandwidth
- func (e *Encoder) PacketLoss() int
- func (e *Encoder) PhaseInversionDisabled() bool
- func (e *Encoder) PredictionDisabled() bool
- func (e *Encoder) Reset()
- func (e *Encoder) SampleRate() int
- func (e *Encoder) SetApplication(application Application) error
- func (e *Encoder) SetBandwidth(bandwidth Bandwidth) error
- func (e *Encoder) SetBitrate(bitrate int) error
- func (e *Encoder) SetBitrateMode(mode BitrateMode) error
- func (e *Encoder) SetComplexity(complexity int) error
- func (e *Encoder) SetDTX(enabled bool)
- func (e *Encoder) SetFEC(enabled bool)
- func (e *Encoder) SetForceChannels(channels int) error
- func (e *Encoder) SetFrameSize(samples int) error
- func (e *Encoder) SetLSBDepth(depth int) error
- func (e *Encoder) SetMaxBandwidth(bandwidth Bandwidth) error
- func (e *Encoder) SetPacketLoss(lossPercent int) error
- func (e *Encoder) SetPhaseInversionDisabled(disabled bool)
- func (e *Encoder) SetPredictionDisabled(disabled bool)
- func (e *Encoder) SetSignal(signal Signal) error
- func (e *Encoder) SetVBR(enabled bool)
- func (e *Encoder) SetVBRConstraint(constrained bool)
- func (e *Encoder) Signal() Signal
- func (e *Encoder) VBR() bool
- func (e *Encoder) VBRConstraint() bool
- type Mode
- type MultistreamDecoder
- func (d *MultistreamDecoder) Channels() int
- func (d *MultistreamDecoder) CoupledStreams() int
- func (d *MultistreamDecoder) Decode(data []byte, pcm []float32) (int, error)
- func (d *MultistreamDecoder) DecodeInt16(data []byte, pcm []int16) (int, error)
- func (d *MultistreamDecoder) Reset()
- func (d *MultistreamDecoder) SampleRate() int
- func (d *MultistreamDecoder) Streams() int
- type MultistreamEncoder
- func (e *MultistreamEncoder) Application() Application
- func (e *MultistreamEncoder) Bandwidth() Bandwidth
- func (e *MultistreamEncoder) Bitrate() int
- func (e *MultistreamEncoder) BitrateMode() BitrateMode
- func (e *MultistreamEncoder) Channels() int
- func (e *MultistreamEncoder) Complexity() int
- func (e *MultistreamEncoder) CoupledStreams() int
- func (e *MultistreamEncoder) DTXEnabled() bool
- func (e *MultistreamEncoder) Encode(pcm []float32, data []byte) (int, error)
- func (e *MultistreamEncoder) EncodeFloat32(pcm []float32) ([]byte, error)
- func (e *MultistreamEncoder) EncodeInt16(pcm []int16, data []byte) (int, error)
- func (e *MultistreamEncoder) EncodeInt16Slice(pcm []int16) ([]byte, error)
- func (e *MultistreamEncoder) FECEnabled() bool
- func (e *MultistreamEncoder) FinalRange() uint32
- func (e *MultistreamEncoder) ForceChannels() int
- func (e *MultistreamEncoder) GetFinalRange() uint32
- func (e *MultistreamEncoder) LSBDepth() int
- func (e *MultistreamEncoder) Lookahead() int
- func (e *MultistreamEncoder) MaxBandwidth() Bandwidth
- func (e *MultistreamEncoder) PacketLoss() int
- func (e *MultistreamEncoder) PhaseInversionDisabled() bool
- func (e *MultistreamEncoder) PredictionDisabled() bool
- func (e *MultistreamEncoder) Reset()
- func (e *MultistreamEncoder) SampleRate() int
- func (e *MultistreamEncoder) SetApplication(application Application) error
- func (e *MultistreamEncoder) SetBandwidth(bw Bandwidth) error
- func (e *MultistreamEncoder) SetBitrate(bitrate int) error
- func (e *MultistreamEncoder) SetBitrateMode(mode BitrateMode) error
- func (e *MultistreamEncoder) SetComplexity(complexity int) error
- func (e *MultistreamEncoder) SetDTX(enabled bool)
- func (e *MultistreamEncoder) SetFEC(enabled bool)
- func (e *MultistreamEncoder) SetForceChannels(channels int) error
- func (e *MultistreamEncoder) SetLSBDepth(depth int) error
- func (e *MultistreamEncoder) SetMaxBandwidth(bw Bandwidth) error
- func (e *MultistreamEncoder) SetPacketLoss(lossPercent int) error
- func (e *MultistreamEncoder) SetPhaseInversionDisabled(disabled bool)
- func (e *MultistreamEncoder) SetPredictionDisabled(disabled bool)
- func (e *MultistreamEncoder) SetSignal(signal Signal) error
- func (e *MultistreamEncoder) SetVBR(enabled bool)
- func (e *MultistreamEncoder) SetVBRConstraint(constrained bool)
- func (e *MultistreamEncoder) Signal() Signal
- func (e *MultistreamEncoder) Streams() int
- func (e *MultistreamEncoder) VBR() bool
- func (e *MultistreamEncoder) VBRConstraint() bool
- type PacketInfo
- type PacketReader
- type PacketSink
- type Reader
- type Repacketizer
- type SampleFormat
- type Signal
- type TOC
- type Writer
- func (w *Writer) Channels() int
- func (w *Writer) Flush() error
- func (w *Writer) Reset()
- func (w *Writer) SampleRate() int
- func (w *Writer) SetBitrate(bitrate int) error
- func (w *Writer) SetComplexity(complexity int) error
- func (w *Writer) SetDTX(enabled bool)
- func (w *Writer) SetFEC(enabled bool)
- func (w *Writer) Write(p []byte) (int, error)
Examples ¶
Constants ¶
const ( // SignalAuto lets the encoder detect the signal type automatically. SignalAuto = types.SignalAuto // SignalVoice hints that the input is speech, biasing toward SILK mode. SignalVoice = types.SignalVoice // SignalMusic hints that the input is music, biasing toward CELT mode. SignalMusic = types.SignalMusic )
const ( // BitrateModeVBR enables unconstrained variable bitrate mode. BitrateModeVBR = encoder.ModeVBR // BitrateModeCVBR enables constrained variable bitrate mode. BitrateModeCVBR = encoder.ModeCVBR // BitrateModeCBR enables constant bitrate mode. BitrateModeCBR = encoder.ModeCBR )
const ( ModeSILK = types.ModeSILK // SILK-only mode (configs 0-11) ModeHybrid = types.ModeHybrid // Hybrid SILK+CELT (configs 12-15) ModeCELT = types.ModeCELT // CELT-only mode (configs 16-31) )
Re-export mode constants for convenience.
const ( BandwidthNarrowband = types.BandwidthNarrowband // 4kHz audio, 8kHz sample rate BandwidthMediumband = types.BandwidthMediumband // 6kHz audio, 12kHz sample rate BandwidthWideband = types.BandwidthWideband // 8kHz audio, 16kHz sample rate BandwidthSuperwideband = types.BandwidthSuperwideband // 12kHz audio, 24kHz sample rate BandwidthFullband = types.BandwidthFullband // 20kHz audio, 48kHz sample rate )
Re-export bandwidth constants for convenience.
Variables ¶
var ( // ErrInvalidSampleRate indicates an unsupported sample rate. // Valid sample rates are: 8000, 12000, 16000, 24000, 48000. ErrInvalidSampleRate = errors.New("gopus: invalid sample rate (must be 8000, 12000, 16000, 24000, or 48000)") // ErrInvalidChannels indicates an unsupported channel count. // Valid channel counts are 1 (mono) or 2 (stereo). ErrInvalidChannels = errors.New("gopus: invalid channels (must be 1 or 2)") // ErrInvalidMaxPacketSamples indicates an invalid max packet sample cap. ErrInvalidMaxPacketSamples = errors.New("gopus: invalid max packet samples (must be > 0)") // ErrInvalidMaxPacketBytes indicates an invalid max packet size cap. ErrInvalidMaxPacketBytes = errors.New("gopus: invalid max packet bytes (must be > 0)") // ErrPacketTooLarge indicates the packet exceeds configured limits. ErrPacketTooLarge = errors.New("gopus: packet exceeds configured limits") // ErrBufferTooSmall indicates the output buffer is too small for the decoded frame. // The buffer must be at least frameSize * channels samples. ErrBufferTooSmall = errors.New("gopus: output buffer too small") // ErrInvalidFrameSize indicates the input frame size doesn't match expected. // The PCM input length must be frameSize * channels. ErrInvalidFrameSize = errors.New("gopus: invalid frame size") // ErrInvalidBitrate indicates the bitrate is out of valid range. // Valid bitrates are 6000 to 510000 bits per second. ErrInvalidBitrate = errors.New("gopus: invalid bitrate (must be 6000-510000)") // ErrInvalidBitrateMode indicates an invalid bitrate mode. // Valid modes are BitrateModeVBR, BitrateModeCVBR, and BitrateModeCBR. ErrInvalidBitrateMode = errors.New("gopus: invalid bitrate mode") // ErrInvalidComplexity indicates the complexity is out of valid range. // Valid complexity values are 0 to 10. ErrInvalidComplexity = errors.New("gopus: invalid complexity (must be 0-10)") // ErrInvalidApplication indicates an invalid application hint. // Valid values are ApplicationVoIP, ApplicationAudio, or ApplicationLowDelay. ErrInvalidApplication = errors.New("gopus: invalid application") // ErrInvalidPacketLoss indicates an invalid packet loss percentage. // Valid range is 0 to 100. ErrInvalidPacketLoss = errors.New("gopus: invalid packet loss percentage (must be 0-100)") // ErrInvalidStreams indicates an invalid stream count for multistream encoding/decoding. // Valid stream counts are 1 to 255. ErrInvalidStreams = errors.New("gopus: invalid stream count (must be 1-255)") // ErrInvalidCoupledStreams indicates an invalid coupled streams count. // Coupled streams must be between 0 and total streams. ErrInvalidCoupledStreams = errors.New("gopus: invalid coupled streams (must be 0 to streams)") // ErrInvalidMapping indicates an invalid channel mapping table. // The mapping table length must equal the channel count. ErrInvalidMapping = errors.New("gopus: invalid mapping table") // ErrInvalidBandwidth indicates an invalid bandwidth for the current mode. // For SILK-only mode, only NB, MB, and WB are valid (not SWB or FB). ErrInvalidBandwidth = errors.New("gopus: invalid bandwidth for mode") // ErrInvalidSignal indicates an invalid signal type hint. // Valid values are SignalAuto, SignalVoice, or SignalMusic. ErrInvalidSignal = errors.New("gopus: invalid signal type (must be SignalAuto, SignalVoice, or SignalMusic)") // ErrInvalidLSBDepth indicates an invalid LSB depth. // Valid range is 8 to 24 bits. ErrInvalidLSBDepth = errors.New("gopus: invalid LSB depth (must be 8-24)") // ErrInvalidForceChannels indicates an invalid force channels value. // Valid values are -1 (auto), 1 (mono), or 2 (stereo). ErrInvalidForceChannels = errors.New("gopus: invalid force channels (must be -1, 1, or 2)") // ErrNoFECData indicates no FEC (LBRR) data is available for recovery. // This occurs when FEC decode is requested but the previous packet // was CELT-only mode or didn't contain LBRR data. ErrNoFECData = errors.New("gopus: no FEC data available for recovery") // ErrInvalidArgument indicates one or more function arguments are invalid. ErrInvalidArgument = errors.New("gopus: invalid argument") // ErrInvalidGain indicates an invalid decoder gain value. // Valid range is -32768 to 32767 (Q8 dB). ErrInvalidGain = errors.New("gopus: invalid gain (must be -32768 to 32767)") )
Public error types for encoding and decoding operations.
var ( ErrPacketTooShort = errors.New("opus: packet too short") ErrInvalidFrameCount = errors.New("opus: invalid frame count (M > 48)") ErrInvalidPacket = errors.New("opus: invalid packet structure") )
Errors returned by packet parsing functions.
Functions ¶
func ConfigFromParams ¶
ConfigFromParams returns the config index for given mode, bandwidth, and frame size. Returns -1 if the combination is invalid.
func GenerateTOC ¶
GenerateTOC creates a TOC byte from encoding parameters. config: Configuration index 0-31 (from configTable) stereo: True for stereo, false for mono frameCode: Frame count code 0-3
0: 1 frame 1: 2 equal-sized frames 2: 2 different-sized frames 3: arbitrary number of frames
func MultistreamPacketPad ¶
MultistreamPacketPad pads the final stream packet inside a multistream packet.
func MultistreamPacketUnpad ¶
MultistreamPacketUnpad removes padding from all streams in a multistream packet. It returns the new packet length.
func PacketPad ¶
PacketPad pads a packet in-place to newLen bytes.
data must have capacity for at least newLen bytes. length is the current packet length in data.
func PacketUnpad ¶
PacketUnpad removes packet padding in-place and returns the new packet length.
func ValidConfig ¶
ValidConfig returns true if the configuration index is valid.
Types ¶
type Application ¶
type Application int
Application hints the encoder for optimization.
const ( // ApplicationVoIP optimizes for speech transmission with low latency. // Prefers SILK mode for speech frequencies. ApplicationVoIP Application = iota // ApplicationAudio optimizes for music and high-quality audio. // Prefers CELT/Hybrid mode for full-bandwidth audio. ApplicationAudio // ApplicationLowDelay minimizes algorithmic delay. // Uses CELT mode exclusively with small frame sizes. ApplicationLowDelay )
type BitrateMode ¶
type BitrateMode = encoder.BitrateMode
BitrateMode controls how the encoder sizes packets.
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
Decoder decodes Opus packets into PCM audio samples.
A Decoder instance maintains internal state and is NOT safe for concurrent use. Each goroutine should create its own Decoder instance.
The decoder supports all Opus modes (SILK, Hybrid, CELT) and automatically detects the mode from the TOC byte in each packet.
func NewDecoder ¶
func NewDecoder(cfg DecoderConfig) (*Decoder, error)
NewDecoder creates a new Opus decoder.
Example ¶
package main
import (
"fmt"
"log"
"github.com/thesyncim/gopus"
)
func main() {
// Create a decoder for 48kHz stereo audio
dec, err := gopus.NewDecoder(gopus.DefaultDecoderConfig(48000, 2))
if err != nil {
log.Fatal(err)
}
fmt.Printf("Decoder: %dHz, %d channels\n", dec.SampleRate(), dec.Channels())
}
Output: Decoder: 48000Hz, 2 channels
func (*Decoder) Bandwidth ¶
Bandwidth returns the bandwidth of the last successfully decoded packet.
func (*Decoder) DebugPrevMode ¶
DebugPrevMode returns the previous decode mode (SILK/Hybrid/CELT). This is intended for testing/debugging parity with libopus.
func (*Decoder) DebugPrevPacketStereo ¶
DebugPrevPacketStereo returns the last packet's stereo flag. This is intended for testing/debugging parity with libopus.
func (*Decoder) DebugPrevRedundancy ¶
DebugPrevRedundancy reports whether the previous frame used CELT redundancy. This is intended for testing/debugging parity with libopus.
func (*Decoder) Decode ¶
Decode decodes an Opus packet into float32 PCM samples.
data: Opus packet data, or nil for Packet Loss Concealment (PLC). pcm: Output buffer for decoded samples. Must be large enough to hold frameSize * frameCount * channels samples, where frameSize and frameCount are determined from the packet TOC and frame code.
Returns the number of samples per channel decoded, or an error.
When data is nil, the decoder performs packet loss concealment using the last successfully decoded frame parameters.
Buffer sizing: For 60ms frames at 48kHz stereo, pcm must have at least 2880 * 2 = 5760 elements. For multi-frame packets (code 1/2/3), the buffer must be large enough for all frames combined.
Multi-frame packets (RFC 6716 Section 3.2):
- Code 0: 1 frame (most common)
- Code 1: 2 equal-sized frames
- Code 2: 2 different-sized frames
- Code 3: Arbitrary number of frames (1-48)
Example ¶
package main
import (
"fmt"
"log"
"math"
"github.com/thesyncim/gopus"
)
func main() {
// Create encoder and decoder
enc, _ := gopus.NewEncoder(48000, 2, gopus.ApplicationAudio)
cfg := gopus.DefaultDecoderConfig(48000, 2)
dec, _ := gopus.NewDecoder(cfg)
pcmOut := make([]float32, cfg.MaxPacketSamples*cfg.Channels)
// Generate and encode a test signal
pcm := make([]float32, 960*2)
for i := range pcm {
pcm[i] = float32(math.Sin(float64(i) * 0.01))
}
packet, _ := enc.EncodeFloat32(pcm)
// Decode the packet
n, err := dec.Decode(packet, pcmOut)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Decoded %d bytes to %d samples\n", len(packet), n)
}
Example (PacketLoss) ¶
package main
import (
"fmt"
"log"
"github.com/thesyncim/gopus"
)
func main() {
cfg := gopus.DefaultDecoderConfig(48000, 2)
dec, _ := gopus.NewDecoder(cfg)
pcmOut := make([]float32, cfg.MaxPacketSamples*cfg.Channels)
// First, decode a real packet to initialize state
enc, _ := gopus.NewEncoder(48000, 2, gopus.ApplicationAudio)
pcm := make([]float32, 960*2)
packet, _ := enc.EncodeFloat32(pcm)
_, _ = dec.Decode(packet, pcmOut)
// Simulate packet loss by passing nil
// Decoder uses PLC to generate concealment audio
n, err := dec.Decode(nil, pcmOut)
if err != nil {
log.Fatal(err)
}
fmt.Printf("PLC generated %d samples\n", n)
}
func (*Decoder) DecodeInt16 ¶
DecodeInt16 decodes an Opus packet into int16 PCM samples.
data: Opus packet data, or nil for PLC. pcm: Output buffer for decoded samples. Must be large enough to hold all frames in multi-frame packets (frameSize * frameCount * channels samples).
Returns the number of samples per channel decoded, or an error.
The samples are converted from float32 with proper clamping to [-32768, 32767].
func (*Decoder) DecodeWithFEC ¶
DecodeWithFEC decodes an Opus packet, optionally recovering a lost frame using FEC.
If fec is true and the previous packet contained LBRR redundancy data, the decoder will use that data to recover the lost frame instead of using PLC extrapolation. This produces better audio quality during packet loss.
If fec is true but no LBRR data is available, the decoder falls back to standard PLC. If fec is false, this behaves identically to Decode().
Parameters:
- data: Opus packet data, or nil to trigger FEC/PLC for a lost packet
- pcm: Output buffer for decoded samples
- fec: If true and data is nil, attempt FEC recovery before falling back to PLC
Returns the number of samples per channel decoded, or an error.
Usage pattern for handling packet loss:
// When packet N is lost: // 1. First decode packet N+1's FEC data to recover N samples, _ := decoder.DecodeWithFEC(packetN1, pcmN, true) // 2. Then decode packet N+1 normally samples, _ := decoder.Decode(packetN1, pcmN1)
Note: FEC recovery uses LBRR (Low Bitrate Redundancy) data that is encoded at the encoder side when the encoder has FEC enabled. LBRR data is only available in SILK and Hybrid modes, not in CELT-only mode.
func (*Decoder) FinalRange ¶
FinalRange returns the final range coder state after decoding. This matches libopus OPUS_GET_FINAL_RANGE and is used for bitstream verification. Must be called after Decode() to get a meaningful value.
Per libopus, the final range is XORed with any redundancy frame's range. If the packet length was <= 1, FinalRange returns 0.
func (*Decoder) GetCELTDecoder ¶
GetCELTDecoder returns the internal CELT decoder for debugging purposes. This allows access to internal state like preemph_state and overlap_buffer.
func (*Decoder) GetSILKDecoder ¶
GetSILKDecoder returns the internal SILK decoder for debugging purposes. This allows access to internal state like resampler state and sMid buffer.
func (*Decoder) LastPacketDuration ¶
LastPacketDuration returns the duration (in samples per channel at 48kHz scale) of the last decoded packet.
func (*Decoder) Pitch ¶
Pitch returns the most recent CELT postfilter pitch period.
This mirrors OPUS_GET_PITCH behavior for decoded CELT/hybrid content. Returns 0 when no pitch information is available.
func (*Decoder) Reset ¶
func (d *Decoder) Reset()
Reset clears the decoder state for a new stream. Call this when starting to decode a new audio stream.
func (*Decoder) SampleRate ¶
SampleRate returns the sample rate in Hz.
type DecoderConfig ¶
type DecoderConfig struct {
// SampleRate must be one of: 8000, 12000, 16000, 24000, 48000.
SampleRate int
// Channels must be 1 (mono) or 2 (stereo).
Channels int
// MaxPacketSamples caps the maximum decoded samples per channel per packet.
// If zero, defaultMaxPacketSamples is used.
MaxPacketSamples int
// MaxPacketBytes caps the maximum Opus packet size in bytes.
// If zero, defaultMaxPacketBytes is used.
MaxPacketBytes int
}
DecoderConfig configures a Decoder instance.
func DefaultDecoderConfig ¶
func DefaultDecoderConfig(sampleRate, channels int) DecoderConfig
DefaultDecoderConfig returns a config with default caps for the given stream format.
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
Encoder encodes PCM audio samples into Opus packets.
An Encoder instance maintains internal state and is NOT safe for concurrent use. Each goroutine should create its own Encoder instance.
The encoder supports three modes:
- SILK: optimized for speech at lower bitrates
- CELT: optimized for music and high-quality audio
- Hybrid: combines SILK and CELT for wideband speech
The mode is automatically selected based on the Application hint and bandwidth settings.
Zero-allocation design: All scratch buffers are pre-allocated at construction time. The Encode and EncodeInt16 methods perform zero heap allocations in the hot path when called with properly sized caller-provided buffers.
func NewEncoder ¶
func NewEncoder(sampleRate, channels int, application Application) (*Encoder, error)
NewEncoder creates a new Opus encoder.
sampleRate must be one of: 8000, 12000, 16000, 24000, 48000. channels must be 1 (mono) or 2 (stereo). application hints the encoder for optimization.
Returns an error if the parameters are invalid.
Example ¶
package main
import (
"fmt"
"log"
"github.com/thesyncim/gopus"
)
func main() {
// Create an encoder for 48kHz stereo audio
enc, err := gopus.NewEncoder(48000, 2, gopus.ApplicationAudio)
if err != nil {
log.Fatal(err)
}
// Configure encoder settings
enc.SetBitrate(64000) // 64 kbps
enc.SetComplexity(10) // Maximum quality
fmt.Printf("Encoder: %dHz, %d channels\n", enc.SampleRate(), enc.Channels())
}
Output: Encoder: 48000Hz, 2 channels
func (*Encoder) Application ¶
func (e *Encoder) Application() Application
Application returns the current encoder application hint.
func (*Encoder) BitrateMode ¶
func (e *Encoder) BitrateMode() BitrateMode
BitrateMode returns the active encoder bitrate control mode.
func (*Encoder) Complexity ¶
Complexity returns the current complexity setting.
func (*Encoder) DTXEnabled ¶
DTXEnabled returns whether DTX is enabled.
func (*Encoder) Encode ¶
Encode encodes float32 PCM samples into an Opus packet.
pcm: Input samples (interleaved if stereo). Length must be frameSize * channels. data: Output buffer for the encoded packet. Recommended size is 4000 bytes.
Returns the number of bytes written to data, or an error. Returns 0 bytes written if DTX suppresses the frame (silence detected).
Buffer sizing: 4000 bytes is sufficient for any Opus packet.
func (*Encoder) EncodeFloat32 ¶
EncodeFloat32 encodes float32 PCM samples and returns a new byte slice.
This is a convenience method that allocates the output buffer. For performance-critical code, use Encode with a pre-allocated buffer.
pcm: Input samples (interleaved if stereo).
Returns the encoded packet or an error.
Example ¶
package main
import (
"fmt"
"log"
"github.com/thesyncim/gopus"
)
func main() {
enc, err := gopus.NewEncoder(48000, 2, gopus.ApplicationAudio)
if err != nil {
log.Fatal(err)
}
// Generate 20ms of stereo silence (960 samples per channel)
pcm := make([]float32, 960*2)
// Encode the frame
packet, err := enc.EncodeFloat32(pcm)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Encoded %d samples to %d bytes\n", len(pcm)/2, len(packet))
// Output will vary based on encoder state
}
func (*Encoder) EncodeInt16 ¶
EncodeInt16 encodes int16 PCM samples into an Opus packet.
pcm: Input samples (interleaved if stereo). Length must be frameSize * channels. data: Output buffer for the encoded packet.
Returns the number of bytes written to data, or an error.
The samples are converted from int16 by dividing by 32768.
func (*Encoder) EncodeInt16Slice ¶
EncodeInt16Slice encodes int16 PCM samples and returns a new byte slice.
This is a convenience method that allocates the output buffer. For performance-critical code, use EncodeInt16 with a pre-allocated buffer.
pcm: Input samples (interleaved if stereo).
Returns the encoded packet or an error.
func (*Encoder) FECEnabled ¶
FECEnabled returns whether FEC is enabled.
func (*Encoder) FinalRange ¶
FinalRange returns the final range coder state after encoding. This matches libopus OPUS_GET_FINAL_RANGE and is used for bitstream verification. Must be called after Encode() to get a meaningful value.
func (*Encoder) ForceChannels ¶
ForceChannels returns the forced channel count (-1 = auto).
func (*Encoder) Lookahead ¶
Lookahead returns the encoder's algorithmic delay in samples.
Matches libopus OPUS_GET_LOOKAHEAD behavior:
- Base lookahead is Fs/400 (2.5ms)
- Delay compensation Fs/250 is included for VoIP/Audio
- Delay compensation is omitted for LowDelay
func (*Encoder) MaxBandwidth ¶
MaxBandwidth returns the current maximum bandwidth limit.
func (*Encoder) PacketLoss ¶
PacketLoss returns the configured expected packet loss percentage.
func (*Encoder) PhaseInversionDisabled ¶
PhaseInversionDisabled returns whether stereo phase inversion is disabled.
func (*Encoder) PredictionDisabled ¶
PredictionDisabled returns whether inter-frame prediction is disabled.
func (*Encoder) Reset ¶
func (e *Encoder) Reset()
Reset clears the encoder state for a new stream. Call this when starting to encode a new audio stream.
func (*Encoder) SampleRate ¶
SampleRate returns the sample rate in Hz.
func (*Encoder) SetApplication ¶
func (e *Encoder) SetApplication(application Application) error
SetApplication updates the encoder application hint.
Valid values are ApplicationVoIP, ApplicationAudio, and ApplicationLowDelay.
func (*Encoder) SetBandwidth ¶
SetBandwidth sets the target audio bandwidth.
func (*Encoder) SetBitrate ¶
SetBitrate sets the target bitrate in bits per second.
Valid range is 6000 to 510000 (6 kbps to 510 kbps). Returns ErrInvalidBitrate if out of range.
Example ¶
package main
import (
"fmt"
"log"
"github.com/thesyncim/gopus"
)
func main() {
enc, _ := gopus.NewEncoder(48000, 2, gopus.ApplicationAudio)
// Set bitrate to 128 kbps
err := enc.SetBitrate(128000)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Bitrate set to %d bps\n", enc.Bitrate())
}
Output: Bitrate set to 128000 bps
func (*Encoder) SetBitrateMode ¶
func (e *Encoder) SetBitrateMode(mode BitrateMode) error
SetBitrateMode sets the encoder bitrate control mode.
func (*Encoder) SetComplexity ¶
SetComplexity sets the encoder's computational complexity.
complexity must be 0-10, where:
- 0-1: Minimal processing, fastest encoding
- 2-4: Basic analysis, good for real-time with limited CPU
- 5-7: Moderate analysis, balanced quality/speed
- 8-10: Thorough analysis, highest quality
Returns ErrInvalidComplexity if out of range.
Example ¶
package main
import (
"fmt"
"log"
"github.com/thesyncim/gopus"
)
func main() {
enc, _ := gopus.NewEncoder(48000, 2, gopus.ApplicationAudio)
// Set complexity to maximum quality
err := enc.SetComplexity(10)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Complexity: %d\n", enc.Complexity())
}
Output: Complexity: 10
func (*Encoder) SetDTX ¶
SetDTX enables or disables Discontinuous Transmission.
When enabled, the encoder reduces bitrate during silence by:
- Suppressing packets entirely during silence
- Sending periodic comfort noise frames
DTX is useful for VoIP applications to reduce bandwidth.
Example ¶
package main
import (
"fmt"
"github.com/thesyncim/gopus"
)
func main() {
enc, _ := gopus.NewEncoder(48000, 1, gopus.ApplicationVoIP)
// Enable DTX for bandwidth savings during silence
enc.SetDTX(true)
fmt.Printf("DTX enabled: %v\n", enc.DTXEnabled())
}
Output: DTX enabled: true
func (*Encoder) SetFEC ¶
SetFEC enables or disables in-band Forward Error Correction.
When enabled, the encoder includes redundant information for loss recovery. FEC is most effective when the receiver can request retransmission of lost packets.
Example ¶
package main
import (
"fmt"
"github.com/thesyncim/gopus"
)
func main() {
enc, _ := gopus.NewEncoder(48000, 2, gopus.ApplicationVoIP)
// Enable FEC for packet loss recovery
enc.SetFEC(true)
fmt.Printf("FEC enabled: %v\n", enc.FECEnabled())
}
Output: FEC enabled: true
func (*Encoder) SetForceChannels ¶
SetForceChannels forces the encoder to use a specific channel count.
channels must be one of:
- -1: automatic (use input channels)
- 1: force mono output
- 2: force stereo output
Note: Forcing stereo on mono input will duplicate the channel. Forcing mono on stereo input will downmix to mono.
Returns ErrInvalidForceChannels if the value is not valid.
func (*Encoder) SetFrameSize ¶
SetFrameSize sets the frame size in samples at 48kHz.
Valid sizes depend on the encoding mode:
- SILK: 480, 960, 1920, 2880 (10, 20, 40, 60 ms)
- CELT: 120, 240, 480, 960 (2.5, 5, 10, 20 ms)
- Hybrid: 480, 960 (10, 20 ms)
Default is 960 (20ms).
func (*Encoder) SetLSBDepth ¶
SetLSBDepth sets the bit depth of the input signal.
depth must be 8-24. This affects DTX silence detection: lower bit depths have a higher noise floor, so the encoder adjusts its silence threshold accordingly.
Default is 24 (full precision). Returns ErrInvalidLSBDepth if out of range.
func (*Encoder) SetMaxBandwidth ¶
SetMaxBandwidth sets the maximum audio bandwidth.
The encoder will not use a bandwidth higher than this limit. This is useful for limiting bandwidth without changing the sample rate.
Valid values are:
- BandwidthNarrowband (4kHz)
- BandwidthMediumband (6kHz)
- BandwidthWideband (8kHz)
- BandwidthSuperwideband (12kHz)
- BandwidthFullband (20kHz)
func (*Encoder) SetPacketLoss ¶
SetPacketLoss sets the expected packet loss percentage.
lossPercent must be in the range [0, 100].
func (*Encoder) SetPhaseInversionDisabled ¶
SetPhaseInversionDisabled disables stereo phase inversion.
Phase inversion is a technique used to improve stereo decorrelation. Some audio processing pipelines may have issues with phase-inverted audio. Disabling it (true) ensures no phase inversion is applied.
Default is false (phase inversion enabled).
func (*Encoder) SetPredictionDisabled ¶
SetPredictionDisabled disables inter-frame prediction.
When disabled (true), each frame can be decoded independently, which improves error resilience at the cost of compression efficiency. This is useful for applications with high packet loss.
Default is false (prediction enabled).
func (*Encoder) SetSignal ¶
SetSignal sets the signal type hint for mode selection.
signal must be one of:
- SignalAuto: automatically detect signal type
- SignalVoice: optimize for speech (biases toward SILK)
- SignalMusic: optimize for music (biases toward CELT)
Returns ErrInvalidSignal if the value is not valid.
func (*Encoder) SetVBR ¶
SetVBR enables or disables VBR mode.
Disabling VBR switches to CBR. Enabling VBR restores VBR while preserving the current VBR constraint state.
func (*Encoder) SetVBRConstraint ¶
SetVBRConstraint enables or disables VBR constraint.
This setting is remembered even while VBR is disabled.
func (*Encoder) VBRConstraint ¶
VBRConstraint returns whether VBR constraint is enabled.
type MultistreamDecoder ¶
type MultistreamDecoder struct {
// contains filtered or unexported fields
}
MultistreamDecoder decodes Opus multistream packets into multi-channel PCM audio.
A MultistreamDecoder instance maintains internal state and is NOT safe for concurrent use. Each goroutine should create its own MultistreamDecoder instance.
Multistream decoding is used for surround sound configurations (5.1, 7.1, etc.) where multiple coupled (stereo) and uncoupled (mono) streams are combined.
Reference: RFC 6716 Appendix B, RFC 7845 Section 5.1.1
func NewMultistreamDecoder ¶
func NewMultistreamDecoder(sampleRate, channels, streams, coupledStreams int, mapping []byte) (*MultistreamDecoder, error)
NewMultistreamDecoder creates a new multistream decoder with explicit configuration.
Parameters:
- sampleRate: output sample rate (8000, 12000, 16000, 24000, or 48000 Hz)
- channels: total output channels (1-255)
- streams: total elementary streams (N, 1-255)
- coupledStreams: number of coupled stereo streams (M, 0 to streams)
- mapping: channel mapping table (length must equal channels)
The mapping table determines how decoded audio is routed to output channels:
- Values 0 to 2*M-1: from coupled streams (even=left, odd=right of stereo pair)
- Values 2*M to N+M-1: from uncoupled (mono) streams
- Value 255: silent channel (output zeros)
func NewMultistreamDecoderDefault ¶
func NewMultistreamDecoderDefault(sampleRate, channels int) (*MultistreamDecoder, error)
NewMultistreamDecoderDefault creates a multistream decoder with default Vorbis-style mapping for standard channel configurations (1-8 channels).
This is a convenience function that calls the internal DefaultMapping() to get the appropriate streams, coupledStreams, and mapping for the given channel count.
Supported channel counts:
- 1: mono (1 stream, 0 coupled)
- 2: stereo (1 stream, 1 coupled)
- 3: 3.0 (2 streams, 1 coupled)
- 4: quad (2 streams, 2 coupled)
- 5: 5.0 (3 streams, 2 coupled)
- 6: 5.1 surround (4 streams, 2 coupled)
- 7: 6.1 surround (5 streams, 2 coupled)
- 8: 7.1 surround (5 streams, 3 coupled)
func (*MultistreamDecoder) Channels ¶
func (d *MultistreamDecoder) Channels() int
Channels returns the number of audio channels.
func (*MultistreamDecoder) CoupledStreams ¶
func (d *MultistreamDecoder) CoupledStreams() int
CoupledStreams returns the number of coupled (stereo) streams.
func (*MultistreamDecoder) Decode ¶
func (d *MultistreamDecoder) Decode(data []byte, pcm []float32) (int, error)
Decode decodes an Opus multistream packet into float32 PCM samples.
data: Opus multistream packet data, or nil for Packet Loss Concealment (PLC). pcm: Output buffer for decoded samples. Must be large enough to hold frameSize * channels samples.
Returns the number of samples per channel decoded, or an error.
When data is nil, the decoder performs packet loss concealment using the last successfully decoded frame parameters.
func (*MultistreamDecoder) DecodeInt16 ¶
func (d *MultistreamDecoder) DecodeInt16(data []byte, pcm []int16) (int, error)
DecodeInt16 decodes an Opus multistream packet into int16 PCM samples.
data: Opus multistream packet data, or nil for PLC. pcm: Output buffer for decoded samples.
Returns the number of samples per channel decoded, or an error.
func (*MultistreamDecoder) Reset ¶
func (d *MultistreamDecoder) Reset()
Reset clears the decoder state for a new stream. Call this when starting to decode a new audio stream.
func (*MultistreamDecoder) SampleRate ¶
func (d *MultistreamDecoder) SampleRate() int
SampleRate returns the sample rate in Hz.
func (*MultistreamDecoder) Streams ¶
func (d *MultistreamDecoder) Streams() int
Streams returns the total number of elementary streams.
type MultistreamEncoder ¶
type MultistreamEncoder struct {
// contains filtered or unexported fields
}
MultistreamEncoder encodes multi-channel PCM audio into Opus multistream packets.
A MultistreamEncoder instance maintains internal state and is NOT safe for concurrent use. Each goroutine should create its own MultistreamEncoder instance.
Multistream encoding is used for surround sound configurations (5.1, 7.1, etc.) where multiple coupled (stereo) and uncoupled (mono) streams are combined.
Reference: RFC 6716 Appendix B, RFC 7845 Section 5.1.1
func NewMultistreamEncoder ¶
func NewMultistreamEncoder(sampleRate, channels, streams, coupledStreams int, mapping []byte, application Application) (*MultistreamEncoder, error)
NewMultistreamEncoder creates a new multistream encoder with explicit configuration.
Parameters:
- sampleRate: input sample rate (8000, 12000, 16000, 24000, or 48000 Hz)
- channels: total input channels (1-255)
- streams: total elementary streams (N, 1-255)
- coupledStreams: number of coupled stereo streams (M, 0 to streams)
- mapping: channel mapping table (length must equal channels)
- application: application hint for encoder optimization
The mapping table determines how input audio is routed to stream encoders:
- Values 0 to 2*M-1: to coupled streams (even=left, odd=right of stereo pair)
- Values 2*M to N+M-1: to uncoupled (mono) streams
- Value 255: silent channel (input ignored)
Example for 5.1 surround (6 channels, 4 streams, 2 coupled):
mapping = [0, 4, 1, 2, 3, 5] Input 0 (FL): mapping[0]=0 -> coupled stream 0, left Input 1 (C): mapping[1]=4 -> uncoupled stream 2 (2*2+0) Input 2 (FR): mapping[2]=1 -> coupled stream 0, right Input 3 (RL): mapping[3]=2 -> coupled stream 1, left Input 4 (RR): mapping[4]=3 -> coupled stream 1, right Input 5 (LFE): mapping[5]=5 -> uncoupled stream 3 (2*2+1)
func NewMultistreamEncoderDefault ¶
func NewMultistreamEncoderDefault(sampleRate, channels int, application Application) (*MultistreamEncoder, error)
NewMultistreamEncoderDefault creates a multistream encoder with default Vorbis-style mapping for standard channel configurations (1-8 channels).
This is a convenience function that calls the internal DefaultMapping() to get the appropriate streams, coupledStreams, and mapping for the given channel count.
Supported channel counts:
- 1: mono (1 stream, 0 coupled)
- 2: stereo (1 stream, 1 coupled)
- 3: 3.0 (2 streams, 1 coupled)
- 4: quad (2 streams, 2 coupled)
- 5: 5.0 (3 streams, 2 coupled)
- 6: 5.1 surround (4 streams, 2 coupled)
- 7: 6.1 surround (5 streams, 2 coupled)
- 8: 7.1 surround (5 streams, 3 coupled)
func (*MultistreamEncoder) Application ¶
func (e *MultistreamEncoder) Application() Application
Application returns the current encoder application hint.
func (*MultistreamEncoder) Bandwidth ¶
func (e *MultistreamEncoder) Bandwidth() Bandwidth
Bandwidth returns the currently configured target bandwidth.
func (*MultistreamEncoder) Bitrate ¶
func (e *MultistreamEncoder) Bitrate() int
Bitrate returns the current total target bitrate in bits per second.
func (*MultistreamEncoder) BitrateMode ¶
func (e *MultistreamEncoder) BitrateMode() BitrateMode
BitrateMode returns the active bitrate control mode.
func (*MultistreamEncoder) Channels ¶
func (e *MultistreamEncoder) Channels() int
Channels returns the number of audio channels.
func (*MultistreamEncoder) Complexity ¶
func (e *MultistreamEncoder) Complexity() int
Complexity returns the current complexity setting.
func (*MultistreamEncoder) CoupledStreams ¶
func (e *MultistreamEncoder) CoupledStreams() int
CoupledStreams returns the number of coupled (stereo) streams.
func (*MultistreamEncoder) DTXEnabled ¶
func (e *MultistreamEncoder) DTXEnabled() bool
DTXEnabled returns whether DTX is enabled.
func (*MultistreamEncoder) Encode ¶
func (e *MultistreamEncoder) Encode(pcm []float32, data []byte) (int, error)
Encode encodes float32 PCM samples into an Opus multistream packet.
pcm: Input samples (interleaved). Length must be frameSize * channels. data: Output buffer for the encoded packet. Recommended size is 4000 bytes per stream.
Returns the number of bytes written to data, or an error. Returns 0 bytes written if DTX suppresses all frames (silence detected in all streams).
func (*MultistreamEncoder) EncodeFloat32 ¶
func (e *MultistreamEncoder) EncodeFloat32(pcm []float32) ([]byte, error)
EncodeFloat32 encodes float32 PCM samples and returns a new byte slice.
This is a convenience method that allocates the output buffer. For performance-critical code, use Encode with a pre-allocated buffer.
pcm: Input samples (interleaved).
Returns the encoded packet or an error.
func (*MultistreamEncoder) EncodeInt16 ¶
func (e *MultistreamEncoder) EncodeInt16(pcm []int16, data []byte) (int, error)
EncodeInt16 encodes int16 PCM samples into an Opus multistream packet.
pcm: Input samples (interleaved). Length must be frameSize * channels. data: Output buffer for the encoded packet.
Returns the number of bytes written to data, or an error.
func (*MultistreamEncoder) EncodeInt16Slice ¶
func (e *MultistreamEncoder) EncodeInt16Slice(pcm []int16) ([]byte, error)
EncodeInt16Slice encodes int16 PCM samples and returns a new byte slice.
This is a convenience method that allocates the output buffer. For performance-critical code, use EncodeInt16 with a pre-allocated buffer.
pcm: Input samples (interleaved).
Returns the encoded packet or an error.
func (*MultistreamEncoder) FECEnabled ¶
func (e *MultistreamEncoder) FECEnabled() bool
FECEnabled returns whether FEC is enabled.
func (*MultistreamEncoder) FinalRange ¶
func (e *MultistreamEncoder) FinalRange() uint32
FinalRange returns the final range coder state.
func (*MultistreamEncoder) ForceChannels ¶
func (e *MultistreamEncoder) ForceChannels() int
ForceChannels returns the forced channel count (-1 = auto).
func (*MultistreamEncoder) GetFinalRange ¶
func (e *MultistreamEncoder) GetFinalRange() uint32
GetFinalRange returns the final range coder state for all streams. The values from all streams are XOR combined to produce a single verification value. This matches libopus OPUS_GET_FINAL_RANGE for multistream encoders. Must be called after Encode() to get a meaningful value.
func (*MultistreamEncoder) LSBDepth ¶
func (e *MultistreamEncoder) LSBDepth() int
LSBDepth returns the current LSB depth setting.
func (*MultistreamEncoder) Lookahead ¶
func (e *MultistreamEncoder) Lookahead() int
Lookahead returns the encoder's algorithmic delay in samples.
Matches libopus OPUS_GET_LOOKAHEAD behavior:
- Base lookahead is Fs/400 (2.5ms)
- Delay compensation Fs/250 is included for VoIP/Audio
- Delay compensation is omitted for LowDelay
func (*MultistreamEncoder) MaxBandwidth ¶
func (e *MultistreamEncoder) MaxBandwidth() Bandwidth
MaxBandwidth returns the maximum bandwidth limit.
func (*MultistreamEncoder) PacketLoss ¶
func (e *MultistreamEncoder) PacketLoss() int
PacketLoss returns expected packet loss percentage.
func (*MultistreamEncoder) PhaseInversionDisabled ¶
func (e *MultistreamEncoder) PhaseInversionDisabled() bool
PhaseInversionDisabled reports whether stereo phase inversion is disabled.
func (*MultistreamEncoder) PredictionDisabled ¶
func (e *MultistreamEncoder) PredictionDisabled() bool
PredictionDisabled reports whether inter-frame prediction is disabled.
func (*MultistreamEncoder) Reset ¶
func (e *MultistreamEncoder) Reset()
Reset clears the encoder state for a new stream. Call this when starting to encode a new audio stream.
func (*MultistreamEncoder) SampleRate ¶
func (e *MultistreamEncoder) SampleRate() int
SampleRate returns the sample rate in Hz.
func (*MultistreamEncoder) SetApplication ¶
func (e *MultistreamEncoder) SetApplication(application Application) error
SetApplication updates the encoder application hint.
Valid values are ApplicationVoIP, ApplicationAudio, and ApplicationLowDelay.
func (*MultistreamEncoder) SetBandwidth ¶
func (e *MultistreamEncoder) SetBandwidth(bw Bandwidth) error
SetBandwidth sets the target audio bandwidth.
func (*MultistreamEncoder) SetBitrate ¶
func (e *MultistreamEncoder) SetBitrate(bitrate int) error
SetBitrate sets the total target bitrate in bits per second.
The bitrate is distributed across streams with coupled streams getting proportionally more bits than mono streams.
Valid range is 6000 to 510000 per channel.
func (*MultistreamEncoder) SetBitrateMode ¶
func (e *MultistreamEncoder) SetBitrateMode(mode BitrateMode) error
SetBitrateMode sets the multistream encoder bitrate control mode.
func (*MultistreamEncoder) SetComplexity ¶
func (e *MultistreamEncoder) SetComplexity(complexity int) error
SetComplexity sets the encoder's computational complexity for all streams.
complexity must be 0-10, where:
- 0-1: Minimal processing, fastest encoding
- 2-4: Basic analysis, good for real-time with limited CPU
- 5-7: Moderate analysis, balanced quality/speed
- 8-10: Thorough analysis, highest quality
Returns ErrInvalidComplexity if out of range.
func (*MultistreamEncoder) SetDTX ¶
func (e *MultistreamEncoder) SetDTX(enabled bool)
SetDTX enables or disables Discontinuous Transmission for all streams.
When enabled, the encoders reduce bitrate during silence by:
- Suppressing packets entirely during silence
- Sending periodic comfort noise frames
func (*MultistreamEncoder) SetFEC ¶
func (e *MultistreamEncoder) SetFEC(enabled bool)
SetFEC enables or disables in-band Forward Error Correction for all streams.
When enabled, the encoders include redundant information for loss recovery.
func (*MultistreamEncoder) SetForceChannels ¶
func (e *MultistreamEncoder) SetForceChannels(channels int) error
SetForceChannels forces channel count on all stream encoders.
channels must be -1 (auto), 1 (mono), or 2 (stereo).
func (*MultistreamEncoder) SetLSBDepth ¶
func (e *MultistreamEncoder) SetLSBDepth(depth int) error
SetLSBDepth sets the input signal's LSB depth for all stream encoders. Valid range is 8-24 bits. This affects DTX sensitivity. Returns an error if the depth is out of range.
func (*MultistreamEncoder) SetMaxBandwidth ¶
func (e *MultistreamEncoder) SetMaxBandwidth(bw Bandwidth) error
SetMaxBandwidth sets the maximum bandwidth limit for all stream encoders. The actual bandwidth will be clamped to this limit.
func (*MultistreamEncoder) SetPacketLoss ¶
func (e *MultistreamEncoder) SetPacketLoss(lossPercent int) error
SetPacketLoss sets expected packet loss percentage for all stream encoders.
lossPercent must be in the range [0, 100].
func (*MultistreamEncoder) SetPhaseInversionDisabled ¶
func (e *MultistreamEncoder) SetPhaseInversionDisabled(disabled bool)
SetPhaseInversionDisabled toggles stereo phase inversion on all stream encoders.
func (*MultistreamEncoder) SetPredictionDisabled ¶
func (e *MultistreamEncoder) SetPredictionDisabled(disabled bool)
SetPredictionDisabled toggles inter-frame prediction on all stream encoders.
func (*MultistreamEncoder) SetSignal ¶
func (e *MultistreamEncoder) SetSignal(signal Signal) error
SetSignal sets the signal type hint for all stream encoders. Use SignalVoice for speech content, SignalMusic for music content, or SignalAuto (default) for automatic detection.
func (*MultistreamEncoder) SetVBR ¶
func (e *MultistreamEncoder) SetVBR(enabled bool)
SetVBR enables or disables VBR mode.
Disabling VBR switches to CBR. Enabling VBR restores VBR while preserving the current VBR constraint state.
func (*MultistreamEncoder) SetVBRConstraint ¶
func (e *MultistreamEncoder) SetVBRConstraint(constrained bool)
SetVBRConstraint enables or disables constrained VBR mode. This setting is remembered even while VBR is disabled.
func (*MultistreamEncoder) Signal ¶
func (e *MultistreamEncoder) Signal() Signal
Signal returns the current signal type hint. Returns SignalAuto, SignalVoice, or SignalMusic.
func (*MultistreamEncoder) Streams ¶
func (e *MultistreamEncoder) Streams() int
Streams returns the total number of elementary streams.
func (*MultistreamEncoder) VBR ¶
func (e *MultistreamEncoder) VBR() bool
VBR reports whether VBR mode is enabled.
func (*MultistreamEncoder) VBRConstraint ¶
func (e *MultistreamEncoder) VBRConstraint() bool
VBRConstraint reports whether constrained VBR mode is enabled.
type PacketInfo ¶
type PacketInfo struct {
TOC TOC // Parsed TOC byte
FrameCount int // Number of frames (1-48 for code 3)
FrameSizes []int // Size in bytes of each frame
Padding int // Padding bytes (code 3 only)
TotalSize int // Total packet size
}
PacketInfo contains parsed information about an Opus packet.
func ParsePacket ¶
func ParsePacket(data []byte) (PacketInfo, error)
ParsePacket parses an Opus packet and returns information about its structure. It determines the frame boundaries based on the TOC byte's frame code (0-3).
type PacketReader ¶
type PacketReader interface {
// ReadPacketInto fills dst with the next Opus packet and returns the byte count.
// Returns io.EOF when stream ends. Return 0, nil to trigger PLC.
ReadPacketInto(dst []byte) (int, uint64, error)
}
PacketReader provides Opus packets for streaming decode. Implementations should return io.EOF when no more packets are available.
type PacketSink ¶
type PacketSink interface {
// WritePacket writes an encoded Opus packet.
// Returns number of bytes written and any error.
WritePacket(packet []byte) (int, error)
}
PacketSink receives encoded Opus packets from streaming encode.
type Reader ¶
type Reader struct {
// contains filtered or unexported fields
}
Reader decodes an Opus stream, implementing io.Reader. Output is PCM samples in the configured format.
The Reader handles frame boundaries internally, buffering decoded PCM samples and serving byte-oriented reads.
Example:
reader, err := gopus.NewReader(gopus.DefaultDecoderConfig(48000, 2), source, gopus.FormatFloat32LE) io.Copy(audioOutput, reader)
func NewReader ¶
func NewReader(cfg DecoderConfig, source PacketReader, format SampleFormat) (*Reader, error)
NewReader creates a streaming decoder.
Parameters:
- cfg: decoder configuration
- source: provides Opus packets for decoding
- format: output sample format (FormatFloat32LE or FormatInt16LE)
func (*Reader) Read ¶
Read implements io.Reader, reading decoded PCM bytes.
The Reader handles frame boundaries internally, fetching and decoding packets as needed to fill the buffer.
func (*Reader) Reset ¶
func (r *Reader) Reset()
Reset clears buffers and decoder state for a new stream.
func (*Reader) SampleRate ¶
SampleRate returns the sample rate in Hz.
type Repacketizer ¶
type Repacketizer struct {
// contains filtered or unexported fields
}
Repacketizer accumulates Opus packet frames and emits new packets assembled from any contiguous frame range.
It mirrors libopus repacketizer behavior:
- all added packets must share TOC bits 7..2,
- total stored duration must not exceed 120ms.
func NewRepacketizer ¶
func NewRepacketizer() *Repacketizer
NewRepacketizer creates a new repacketizer state.
func (*Repacketizer) Cat ¶
func (r *Repacketizer) Cat(packet []byte) error
Cat adds one Opus packet to the repacketizer state.
func (*Repacketizer) NumFrames ¶
func (r *Repacketizer) NumFrames() int
NumFrames returns the number of frames currently accumulated.
func (*Repacketizer) Out ¶
func (r *Repacketizer) Out(data []byte) (int, error)
Out assembles all accumulated frames into one Opus packet.
type SampleFormat ¶
type SampleFormat int
SampleFormat specifies the PCM sample format for streaming.
const ( // FormatFloat32LE is 32-bit float, little-endian (4 bytes per sample). FormatFloat32LE SampleFormat = iota // FormatInt16LE is 16-bit signed integer, little-endian (2 bytes per sample). FormatInt16LE )
func (SampleFormat) BytesPerSample ¶
func (f SampleFormat) BytesPerSample() int
BytesPerSample returns the number of bytes per sample for the format.
type Signal ¶
Signal represents a hint about the input signal type. This helps the encoder optimize for speech or music content.
type TOC ¶
type TOC struct {
Config uint8 // Configuration 0-31
Mode Mode // Derived from config
Bandwidth Bandwidth // Derived from config
FrameSize int // Frame size in samples at 48kHz
Stereo bool // True if stereo
FrameCode uint8 // Code 0-3
}
TOC represents the parsed Table of Contents byte from an Opus packet.
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer encodes PCM samples to an Opus stream, implementing io.Writer. Input is PCM samples in the configured format.
The Writer buffers input samples until a complete frame is accumulated, then encodes and sends the packet to the sink.
Example:
writer, err := gopus.NewWriter(48000, 2, sink, gopus.FormatFloat32LE, gopus.ApplicationAudio) io.Copy(writer, audioInput) writer.Flush() // encode any remaining buffered samples
func NewWriter ¶
func NewWriter(sampleRate, channels int, sink PacketSink, format SampleFormat, application Application) (*Writer, error)
NewWriter creates a streaming encoder.
Parameters:
- sampleRate: input sample rate (8000, 12000, 16000, 24000, or 48000)
- channels: number of audio channels (1 or 2)
- sink: receives encoded Opus packets
- format: input sample format (FormatFloat32LE or FormatInt16LE)
- application: encoder application hint
func (*Writer) Flush ¶
Flush encodes any buffered samples. If samples don't fill a complete frame, they are zero-padded. Call Flush before closing the stream to ensure all audio is encoded.
func (*Writer) Reset ¶
func (w *Writer) Reset()
Reset clears buffers and encoder state for a new stream.
func (*Writer) SampleRate ¶
SampleRate returns the sample rate in Hz.
func (*Writer) SetBitrate ¶
SetBitrate sets the target bitrate in bits per second. Valid range is 6000 to 510000 (6 kbps to 510 kbps).
func (*Writer) SetComplexity ¶
SetComplexity sets the encoder's computational complexity (0-10).
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package celt implements the CELT decoder per RFC 6716 Section 4.3.
|
Package celt implements the CELT decoder per RFC 6716 Section 4.3. |
|
container
|
|
|
ogg
Package ogg implements the Ogg container format for Opus audio.
|
Package ogg implements the Ogg container format for Opus audio. |
|
Package encoder provides bitrate and bandwidth control for the Opus encoder.
|
Package encoder provides bitrate and bandwidth control for the Opus encoder. |
|
examples
|
|
|
bench-decode
command
Package main benchmarks Opus decode throughput for gopus vs ffmpeg/libopus.
|
Package main benchmarks Opus decode throughput for gopus vs ffmpeg/libopus. |
|
bench-encode
command
Package main benchmarks Opus encode throughput for gopus vs ffmpeg/libopus.
|
Package main benchmarks Opus encode throughput for gopus vs ffmpeg/libopus. |
|
decode-play
command
Package main demonstrates decoding an Ogg Opus file to WAV with optional playback.
|
Package main demonstrates decoding an Ogg Opus file to WAV with optional playback. |
|
encode-play
command
Package main demonstrates encoding audio with gopus and playing the result.
|
Package main demonstrates encoding audio with gopus and playing the result. |
|
ffmpeg-interop
command
Package main demonstrates gopus interoperability with ffmpeg.
|
Package main demonstrates gopus interoperability with ffmpeg. |
|
ogg-file
command
Package main demonstrates Ogg Opus file creation and reading.
|
Package main demonstrates Ogg Opus file creation and reading. |
|
roundtrip
command
Package main demonstrates gopus encode-decode roundtrip with quality metrics.
|
Package main demonstrates gopus encode-decode roundtrip with quality metrics. |
|
Package hybrid implements the Hybrid decoder for Opus.
|
Package hybrid implements the Hybrid decoder for Opus. |
|
internal
|
|
|
Package multistream implements the multistream decoder for Opus surround sound.
|
Package multistream implements the multistream decoder for Opus surround sound. |
|
Package plc implements Packet Loss Concealment (PLC) for Opus.
|
Package plc implements Packet Loss Concealment (PLC) for Opus. |
|
Package rangecoding implements the range coder used by Opus per RFC 6716 Section 4.1.
|
Package rangecoding implements the range coder used by Opus per RFC 6716 Section 4.1. |
|
Package silk implements LBRR (Low Bitrate Redundancy) encoding for FEC.
|
Package silk implements LBRR (Low Bitrate Redundancy) encoding for FEC. |
|
Package testvectors provides utilities for parsing and validating against official RFC 8251 Opus test vectors.
|
Package testvectors provides utilities for parsing and validating against official RFC 8251 Opus test vectors. |
|
benchguard
command
|
|
|
Package types defines shared types used across gopus packages.
|
Package types defines shared types used across gopus packages. |
|
Package util provides common utility functions for the gopus codec.
|
Package util provides common utility functions for the gopus codec. |