Documentation
¶
Overview ¶
Package entcode provides entropy coding (range coding) for Opus, bit-exact with the range coder in libopus 1.3.1 (celt/entcode.c, celt/entenc.c, celt/entdec.c).
Index ¶
- Constants
- func ILog(val uint32) int
- func Log2Ceiling(n int) int
- type Decoder
- func (dec *Decoder) AdvanceTellTo(bits int)
- func (dec *Decoder) BytesLeft() int
- func (dec *Decoder) Decode(ft uint32) uint32
- func (dec *Decoder) DecodeBit(prob uint16) bool
- func (dec *Decoder) DecodeBitLogp(logp uint) bool
- func (dec *Decoder) DecodeBits(nbits uint) uint32
- func (dec *Decoder) DecodeGetCumu(ft uint32) uint32
- func (dec *Decoder) DecodeIcdf(icdf []uint8, ftb int) int
- func (dec *Decoder) DecodeLaplace(fs uint32, decay int) int
- func (dec *Decoder) DecodeUint(ft uint32) uint32
- func (dec *Decoder) DecodeUintTrace(ft uint32) uint32
- func (dec *Decoder) DecodeUpdate(fl, fh, ft uint32)
- func (dec *Decoder) ECTell() int
- func (dec *Decoder) Error() error
- func (dec *Decoder) GetDif() uint32
- func (dec *Decoder) GetEndOffs() int
- func (dec *Decoder) GetNendBits() uint
- func (dec *Decoder) GetPos() int
- func (dec *Decoder) GetRem() int
- func (dec *Decoder) GetRng() uint32
- func (dec *Decoder) ShrinkStorage(n int)
- func (dec *Decoder) Tell() int
- func (dec *Decoder) TellFrac() int
- type Encoder
- func (enc *Encoder) Bytes() []byte
- func (enc *Encoder) ECTell() int
- func (enc *Encoder) Encode(fl, fh, ft uint32)
- func (enc *Encoder) EncodeBit(bit bool, prob uint16)
- func (enc *Encoder) EncodeBitLogp(bit bool, logp uint)
- func (enc *Encoder) EncodeBits(fl uint32, nbits uint)
- func (enc *Encoder) EncodeExact(fl, fh, ft uint32)
- func (enc *Encoder) EncodeIcdf(symbol int, icdf []uint8, ftb int)
- func (enc *Encoder) EncodeLaplace(value *int, fs uint32, decay int)
- func (enc *Encoder) EncodeUint(val, ft uint32)
- func (enc *Encoder) Flush()
- func (enc *Encoder) GetExt() uint32
- func (enc *Encoder) GetRem() int
- func (enc *Encoder) GetRng() uint32
- func (enc *Encoder) GetVal() uint32
- func (enc *Encoder) Shrink(newSize int)
- func (enc *Encoder) Tell() int
- func (enc *Encoder) TellFrac() int
- func (enc *Encoder) UsedBytes() int
Constants ¶
const ( // EC_SYM_BITS: number of bits per symbol output. SymBits = 8 // EC_CODE_BITS: total bits in the code register. CodeBits = 32 // EC_SYM_MAX: (1<<EC_SYM_BITS)-1 = 255. SymMax = (1 << SymBits) - 1 // EC_CODE_SHIFT: EC_CODE_BITS - EC_SYM_BITS - 1 = 23. CodeShift = CodeBits - SymBits - 1 // EC_CODE_TOP: 1<<(EC_CODE_BITS-1) = 0x80000000. CodeTop = uint32(1 << (CodeBits - 1)) // EC_CODE_BOT: EC_CODE_TOP >> EC_SYM_BITS = 0x00800000. CodeBot = CodeTop >> SymBits // EC_CODE_EXTRA: (EC_CODE_BITS-2)%EC_SYM_BITS+1 = 7. CodeExtra = (CodeBits-2)%SymBits + 1 // EC_UINT_BITS: number of bits for the high part of ec_enc_uint. UintBits = 8 )
Range coding constants matching libopus.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
Decoder is a range decoder bit-exact with libopus ec_dec (celt/entdec.c).
libopus uses a TOP-DOWN convention:
- rng: current range
- dif: difference = (top of range) - (coded value)
- rem: remainder from byte-unpacking (EC_CODE_EXTRA bits)
The decoder reads bytes and combines them using the EC_CODE_EXTRA (7-bit) overlap scheme from libopus.
func NewDecoder ¶
NewDecoder creates a new range decoder from encoded data. Matches ec_dec_init in libopus.
func (*Decoder) AdvanceTellTo ¶
AdvanceTellTo pretends that bits have been consumed up to the supplied libopus ec_tell position without changing the range. CELT uses this for packets carrying the silence flag.
func (*Decoder) Decode ¶
Decode returns the CDF position for a symbol from [0, ft). Must be followed by DecodeUpdate. Matches ec_decode in libopus.
In top-down convention, dif/r gives position from top.
func (*Decoder) DecodeBit ¶
DecodeBit decodes a single bit. prob is probability of false on 0-32768 scale. Matches the custom EncodeBit in encoder.go (not a libopus API).
Encoder: split = rng - (rng >> 15) * prob
true: val += split, rng -= split (true at top in val-space) false: rng = split (false at bottom in val-space)
Top-down: true => dif in [0, rng-split), false => dif in [rng-split, rng) rng - split = (rng >> 15) * prob
func (*Decoder) DecodeBitLogp ¶
DecodeBitLogp decodes a single bit with probability 1/(1<<logp) of being 1. Matches ec_dec_bit_logp in libopus.
Encoder convention (ec_enc_bit_logp):
r = rng >> logp if bit: val += rng - r; rng = r (true at top, width r) else: rng -= r (false at bottom, width rng-r)
Top-down decoder: dif < r => true, dif >= r => false.
func (*Decoder) DecodeBits ¶
DecodeBits decodes raw bits from the end of the packet, matching ec_dec_bits.
func (*Decoder) DecodeGetCumu ¶
DecodeGetCumu returns the cumulative frequency position of the current symbol in [0, ft). This is equivalent to Decode but named for use with explicit-frequency protocols such as recursive PVQ splitting.
func (*Decoder) DecodeIcdf ¶
DecodeIcdf decodes a symbol from a descending ICDF table with ft = 1<<ftb. Bit-exact with ec_dec_icdf in libopus.
The libopus algorithm iterates through icdf entries:
s = rng; d = dif; r = rng >> ftb; ret = -1;
do { t = s; s = r * icdf[++ret]; } while (d < s);
dif = d - s; rng = t - s; normalize();
func (*Decoder) DecodeLaplace ¶
DecodeLaplace decodes an integer value assumed to be Laplace-distributed.
fs is Pr(X==0)×32768; decay is the per-step decay×32768.
Matches ec_laplace_decode in libopus celt/laplace.c.
func (*Decoder) DecodeUint ¶
DecodeUint decodes a value in [0, ft) using ec_dec_uint scheme from libopus.
func (*Decoder) DecodeUintTrace ¶
DecodeUintTrace is a debug version of DecodeUint that prints intermediate steps.
func (*Decoder) DecodeUpdate ¶
DecodeUpdate updates decoder state after Decode. fl, fh are CDF bounds [fl, fh) out of [0, ft). Matches ec_dec_update in libopus.
func (*Decoder) ECTell ¶
ECTell returns bits consumed using the libopus ec_tell convention (== 1 immediately after init). Our internal Tell() reports ec_tell-1, so this is simply Tell()+1. Use this where porting libopus guards verbatim.
func (*Decoder) GetEndOffs ¶
func (*Decoder) GetNendBits ¶
func (*Decoder) ShrinkStorage ¶
ShrinkStorage reduces the decoder's effective buffer length by n bytes, matching libopus `dec->storage -= n`. Raw bits (DecodeBits) are read from the end of the buffer, so shrinking storage keeps the main range decoder from reading into trailing bytes reserved for a redundant frame. Forward range reads (pos) are unaffected as long as they have not yet reached the new end.
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
Encoder is a range encoder bit-exact with libopus ec_enc (celt/entenc.c).
State uses the carry-propagation scheme from libopus:
- val (uint32): 31-bit accumulator (values in [0, CodeTop))
- rng (uint32): current range, always in (CodeBot, CodeTop] after normalize
- rem (int): pending output byte (-1 = empty)
- ext (uint32): count of pending 0xFF bytes (carry chain)
- buf ([]byte): output buffer
func NewEncoder ¶
NewEncoder creates a new range encoder. capacity is the intended packet size in bytes; it sets where end-of-packet raw bits are placed (the absolute end).
func (*Encoder) Bytes ¶
Bytes returns the encoded packet. Call Flush first.
When no raw end-of-packet bits were written, this returns the minimal range- coded front buffer (preserving the historical byte-length semantics relied on by size-measuring tests). When raw bits exist, it assembles the libopus-style layout: forward range bytes at the front, a zeroed gap, and the raw bytes at the absolute end (so the decoder's DecodeBits reads them from the end). The packet is sized to capacity when that leaves room, matching a fixed-size Opus payload; otherwise it grows to fit.
func (*Encoder) ECTell ¶ added in v1.1.0
ECTell returns bits consumed using the libopus ec_tell convention (== 1 immediately after init). Our internal Tell() reports ec_tell-1, so this is Tell()+1, matching the decoder's ECTell(). Use this where porting libopus guards verbatim so encoder and decoder budget decisions stay symmetric.
func (*Encoder) Encode ¶
Encode encodes a symbol in [fl, fh) out of [0, ft). Uses the same CDF-mapping convention as DecodeIcdf/Decode: symbol at CDF [fl, fh) maps to sub-range [r*fl, r*fh) with remainder going to the fl=0 (bottom) symbol.
func (*Encoder) EncodeBit ¶
EncodeBit encodes a single bit. prob is probability of false on a 0-32768 scale.
func (*Encoder) EncodeBitLogp ¶
EncodeBitLogp encodes a single bit with probability 1/(1<<logp) of being 1. Matches ec_enc_bit_logp in libopus.
func (*Encoder) EncodeBits ¶
EncodeBits writes nbits raw bits to the END of the packet, LSB first. Bit-exact with libopus ec_enc_bits (celt/entenc.c): symmetric with the decoder's DecodeBits, which reads raw bits from the end of the packet.
func (*Encoder) EncodeExact ¶
EncodeExact encodes a symbol given its exact cumulative frequency range. fl: cumulative frequency of symbols < symbol fh: cumulative frequency of symbols <= symbol ft: total frequency (may be non-power-of-2)
func (*Encoder) EncodeIcdf ¶
EncodeIcdf encodes a symbol using a descending ICDF table with ft = 1<<ftb. icdf[s] = ft - CDF(s+1), last entry must be 0. Bit-exact with ec_enc_icdf in libopus.
func (*Encoder) EncodeLaplace ¶
EncodeLaplace encodes an integer value assumed to be Laplace-distributed.
value is passed by pointer; it may be clamped to the maximum representable value if the range coder runs out of precision, matching libopus behaviour.
fs is Pr(X==0)×32768; decay is the per-step decay×32768.
Matches ec_laplace_encode in libopus celt/laplace.c.
func (*Encoder) EncodeUint ¶
EncodeUint encodes val in [0, ft) using the ec_enc_uint scheme from libopus.
func (*Encoder) Flush ¶
func (enc *Encoder) Flush()
Flush finalizes encoding. Must be called before Bytes().
The libopus ec_enc_done operates on a fixed-size pre-allocated buffer. Our encoder uses a dynamic buffer, so we directly compute the byte sequence that the decoder's init + normalize will reconstruct as a value within the final [val, val+rng) interval.
func (*Encoder) Shrink ¶ added in v1.1.0
Shrink reduces the encoder's capacity (storage) to newSize bytes. This is the equivalent of libopus ec_enc_shrink: for VBR mode, after encoding all symbols, the packet can be shrunk so that the decoder sees a smaller packet and computes its allocation accordingly. The raw end-of-packet bits are logically relocated to the new end position.
In libopus the raw tail bytes must be memmove'd because they live at the end of a single flat buffer. Our encoder keeps endBytes in a separate slice, so only the capacity field needs updating — Bytes() already places the tail at offset capacity-1.
Precondition: newSize >= len(buf) + len(endBytes) (the range-coded front and raw tail must both fit).
func (*Encoder) Tell ¶
Tell returns the number of bits used so far, including end-of-packet raw bits (mirrors libopus ec_tell, whose nbits_total counts raw bits via ec_enc_bits).