// decodeRiceResidual decodes a Rice encoded residual (error signal). func (subframe *Subframe) decodeRiceResidual(br *bits.Reader, k uint) error { // Read unary encoded most significant bits. high, err := br.ReadUnary() if err != nil { return unexpected(err) } // Read binary encoded least significant bits. low, err := br.Read(k) if err != nil { return unexpected(err) } residual := int32(high<<k | low) // ZigZag decode. residual = bits.ZigZag(residual) subframe.Samples = append(subframe.Samples, residual) return nil }
// parseHeader reads and parses the header of a subframe. func (subframe *Subframe) parseHeader(br *bits.Reader) error { // 1 bit: zero-padding. x, err := br.Read(1) if err != nil { return unexpected(err) } if x != 0 { return errors.New("frame.Subframe.parseHeader: non-zero padding") } // 6 bits: Pred. x, err = br.Read(6) if err != nil { return unexpected(err) } // The 6 bits are used to specify the prediction method and order as follows: // 000000: Constant prediction method. // 000001: Verbatim prediction method. // 00001x: reserved. // 0001xx: reserved. // 001xxx: // if (xxx <= 4) // Fixed prediction method; xxx=order // else // reserved. // 01xxxx: reserved. // 1xxxxx: FIR prediction method; xxxxx=order-1 switch { case x < 1: // 000000: Constant prediction method. subframe.Pred = PredConstant case x < 2: // 000001: Verbatim prediction method. subframe.Pred = PredVerbatim case x < 8: // 00001x: reserved. // 0001xx: reserved. return fmt.Errorf("frame.Subframe.parseHeader: reserved prediction method bit pattern (%06b)", x) case x < 16: // 001xxx: // if (xxx <= 4) // Fixed prediction method; xxx=order // else // reserved. order := int(x & 0x07) if order > 4 { return fmt.Errorf("frame.Subframe.parseHeader: reserved prediction method bit pattern (%06b)", x) } subframe.Pred = PredFixed subframe.Order = order case x < 32: // 01xxxx: reserved. return fmt.Errorf("frame.Subframe.parseHeader: reserved prediction method bit pattern (%06b)", x) default: // 1xxxxx: FIR prediction method; xxxxx=order-1 subframe.Pred = PredFIR subframe.Order = int(x&0x1F) + 1 } // 1 bit: hasWastedBits. x, err = br.Read(1) if err != nil { return unexpected(err) } if x != 0 { // k wasted bits-per-sample in source subblock, k-1 follows, unary coded; // e.g. k=3 => 001 follows, k=7 => 0000001 follows. x, err = br.ReadUnary() if err != nil { return unexpected(err) } subframe.Wasted = uint(x) + 1 } return nil }