Example #1
0
        unsafe void decode_subframes(BitReader bitreader, FlacFrame frame)
        {
            fixed(int *r = residualBuffer, s = samplesBuffer)
            for (int ch = 0; ch < PCM.ChannelCount; ch++)
            {
                // subframe header
                uint t1 = bitreader.readbit();                 // ?????? == 0

                if (t1 != 0)
                {
                    throw new Exception("unsupported subframe coding (ch == " + ch.ToString() + ")");
                }
                int type_code = (int)bitreader.readbits(6);

                frame.subframes[ch].wbits = (int)bitreader.readbit();
                if (frame.subframes[ch].wbits != 0)
                {
                    frame.subframes[ch].wbits += (int)bitreader.read_unary();
                }

                frame.subframes[ch].obits = PCM.BitsPerSample - frame.subframes[ch].wbits;
                switch (frame.ch_mode)
                {
                case ChannelMode.MidSide: frame.subframes[ch].obits += ch; break;

                case ChannelMode.LeftSide: frame.subframes[ch].obits += ch; break;

                case ChannelMode.RightSide: frame.subframes[ch].obits += 1 - ch; break;
                }

                frame.subframes[ch].best.type  = (SubframeType)type_code;
                frame.subframes[ch].best.order = 0;

                if ((type_code & (uint)SubframeType.LPC) != 0)
                {
                    frame.subframes[ch].best.order = (type_code - (int)SubframeType.LPC) + 1;
                    frame.subframes[ch].best.type  = SubframeType.LPC;
                }
                else if ((type_code & (uint)SubframeType.Fixed) != 0)
                {
                    frame.subframes[ch].best.order = (type_code - (int)SubframeType.Fixed);
                    frame.subframes[ch].best.type  = SubframeType.Fixed;
                }

                frame.subframes[ch].best.residual = r + ch * Flake.MAX_BLOCKSIZE;
                frame.subframes[ch].samples       = s + ch * Flake.MAX_BLOCKSIZE;

                // subframe
                switch (frame.subframes[ch].best.type)
                {
                case SubframeType.Constant:
                    decode_subframe_constant(bitreader, frame, ch);
                    break;

                case SubframeType.Verbatim:
                    decode_subframe_verbatim(bitreader, frame, ch);
                    break;

                case SubframeType.Fixed:
                    decode_subframe_fixed(bitreader, frame, ch);
                    break;

                case SubframeType.LPC:
                    decode_subframe_lpc(bitreader, frame, ch);
                    break;

                default:
                    throw new Exception("invalid subframe type");
                }
            }
        }