Example #1
0
        unsafe void decode_frame_header(BitReader bitreader, FlacFrame frame)
        {
            int header_start = bitreader.Position;

            if (bitreader.readbits(15) != 0x7FFC)
            {
                throw new Exception("invalid frame");
            }
            uint vbs = bitreader.readbit();

            frame.bs_code0 = (int)bitreader.readbits(4);
            uint sr_code0 = bitreader.readbits(4);

            frame.ch_mode = (ChannelMode)bitreader.readbits(4);
            uint bps_code = bitreader.readbits(3);

            if (Flake.flac_bitdepths[bps_code] != PCM.BitsPerSample)
            {
                throw new Exception("unsupported bps coding");
            }
            uint t1 = bitreader.readbit();             // == 0?????

            if (t1 != 0)
            {
                throw new Exception("unsupported frame coding");
            }
            frame.frame_number = (int)bitreader.read_utf8();

            // custom block size
            if (frame.bs_code0 == 6)
            {
                frame.bs_code1  = (int)bitreader.readbits(8);
                frame.blocksize = frame.bs_code1 + 1;
            }
            else if (frame.bs_code0 == 7)
            {
                frame.bs_code1  = (int)bitreader.readbits(16);
                frame.blocksize = frame.bs_code1 + 1;
            }
            else
            {
                frame.blocksize = Flake.flac_blocksizes[frame.bs_code0];
            }

            // custom sample rate
            if (sr_code0 < 1 || sr_code0 > 11)
            {
                // sr_code0 == 12 -> sr == bitreader.readbits(8) * 1000;
                // sr_code0 == 13 -> sr == bitreader.readbits(16);
                // sr_code0 == 14 -> sr == bitreader.readbits(16) * 10;
                throw new Exception("invalid sample rate mode");
            }

            int frame_channels = (int)frame.ch_mode + 1;

            if (frame_channels > 11)
            {
                throw new Exception("invalid channel mode");
            }
            if (frame_channels == 2 || frame_channels > 8)             // Mid/Left/Right Side Stereo
            {
                frame_channels = 2;
            }
            else
            {
                frame.ch_mode = ChannelMode.NotStereo;
            }
            if (frame_channels != PCM.ChannelCount)
            {
                throw new Exception("invalid channel mode");
            }

            // CRC-8 of frame header
            byte crc = do_crc ? crc8.ComputeChecksum(bitreader.Buffer, header_start, bitreader.Position - header_start) : (byte)0;

            frame.crc8 = (byte)bitreader.readbits(8);
            if (do_crc && frame.crc8 != crc)
            {
                throw new Exception("header crc mismatch");
            }
        }