nx_bitio.nx source
↩ module page · 51 lines · 2047 B
1// nx_bitio.nx -- MSB-first bit-level writer/reader over a byte buffer.
2//
3// Reusable across every sub-byte-coded codec: ACELP pulse-position/sign
4// indices, VQ/RVQ codebook indices, packed gain indices, entropy fields.
5// The voice/video codecs currently pack in whole bytes or nibbles, which
6// wastes bits at low bitrate -- this lets a field be exactly as wide as it
7// needs (e.g. a 17-bit G.729 fixed-codebook index, a 7-bit pitch lag).
8//
9// Functional / positional: the caller owns the bit cursor (so one function
10// can return the value while the caller advances by the known width). The
11// writer tolerates a DIRTY buffer (it both sets and clears each touched
12// bit), so callers need not pre-zero. Big-endian bit order within the
13// stream (MSB of the field emitted first) -- matches ITU/3GPP bit packing.
14//
15// genealogy_id: itu_g729_bitstream + 3gpp_amr_packing
16// lineage_id: nishi_bitio_msb
17
18// Write the low `nbits` bits of `value`, MSB-first, starting at `bitpos`.
19// Returns the new bit cursor (bitpos + nbits).
20func nx_bw_put(buf: *u8, bitpos: i64, value: i64, nbits: i64) -> i64 {
21 var k: i64 = 0
22 while k < nbits {
23 let bit: i64 = (value >> (nbits - 1 - k)) & 1
24 let bp: i64 = bitpos + k
25 let byte: i64 = bp >> 3
26 let off: i64 = 7 - (bp & 7)
27 if bit != 0 { buf[byte] = buf[byte] | (1 << off) }
28 else { buf[byte] = buf[byte] & (255 - (1 << off)) }
29 k = k + 1
30 }
31 return bitpos + nbits
32}
33
34// Read `nbits` bits, MSB-first, starting at `bitpos`. Returns the value
35// (unsigned). The caller advances its cursor by nbits.
36func nx_br_get(buf: *u8, bitpos: i64, nbits: i64) -> i64 {
37 var v: i64 = 0
38 var k: i64 = 0
39 while k < nbits {
40 let bp: i64 = bitpos + k
41 let byte: i64 = bp >> 3
42 let off: i64 = 7 - (bp & 7)
43 let bit: i64 = (buf[byte] >> off) & 1
44 v = (v << 1) | bit
45 k = k + 1
46 }
47 return v
48}
49
50// Bytes needed to hold `bits` bits (rounds up).
51func nx_bits_bytes(bits: i64) -> i64 { return (bits + 7) >> 3 }