예제 #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");
                }
            }
        }