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 < 4 || 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"); }