Example #1
0
        unsafe void decode_residual(BitReader bitreader, FlacFrame frame, int ch)
        {
            // rice-encoded block
            // coding method
            frame.subframes[ch].best.rc.coding_method = (int)bitreader.readbits(2);             // ????? == 0
            if (frame.subframes[ch].best.rc.coding_method != 0 && frame.subframes[ch].best.rc.coding_method != 1)
            {
                throw new Exception("unsupported residual coding");
            }
            // partition order
            frame.subframes[ch].best.rc.porder = (int)bitreader.readbits(4);
            if (frame.subframes[ch].best.rc.porder > 8)
            {
                throw new Exception("invalid partition order");
            }
            int psize   = frame.blocksize >> frame.subframes[ch].best.rc.porder;
            int res_cnt = psize - frame.subframes[ch].best.order;

            int rice_len = 4 + frame.subframes[ch].best.rc.coding_method;
            // residual
            int  j = frame.subframes[ch].best.order;
            int *r = frame.subframes[ch].best.residual + j;

            for (int p = 0; p < (1 << frame.subframes[ch].best.rc.porder); p++)
            {
                if (p == 1)
                {
                    res_cnt = psize;
                }
                int n = Math.Min(res_cnt, frame.blocksize - j);

                int k = frame.subframes[ch].best.rc.rparams[p] = (int)bitreader.readbits(rice_len);
                if (k == (1 << rice_len) - 1)
                {
                    k = frame.subframes[ch].best.rc.esc_bps[p] = (int)bitreader.readbits(5);
                    for (int i = n; i > 0; i--)
                    {
                        *(r++) = bitreader.readbits_signed((int)k);
                    }
                }
                else
                {
                    bitreader.read_rice_block(n, (int)k, r);
                    r += n;
                }
                j += n;
            }
        }