Exemplo n.º 1
0
        byte secondSyncByte = 2; // set to invalid reserved value

        public bool FindSync()
        {
            const byte FirstSyncByte      = 0xFF;
            const byte SecondSyncByte     = 0xF8;
            const byte SecondSyncByteMask = 0xFC;

            int  b     = BaseStream.ReadByte();
            bool found = false;

            while (b >= 0)
            {
                if (b == FirstSyncByte)
                {
                    b = BaseStream.ReadByte();
                    if (b >= 0 && (b & SecondSyncByteMask) == SecondSyncByte)
                    {
                        // sync found
                        secondSyncByte = (byte)b;
                        recordType     = FlacRecordType.Sync;
                        found          = true;
                        break;
                    }
                }
                else
                {
                    b = BaseStream.ReadByte();
                }
            }
            return(found);
        }
Exemplo n.º 2
0
        private void ReadMetadataBlock()
        {
            // read header
            int headerType = BaseStream.ReadByte();

            if (headerType < 0)
            {
                throw new FlacException("Unexepted end of stream: metadata block expected");
            }

            isLastMetadataBlock = (headerType & 0x80) != 0;

            metadataBlockType = (FlacMetadataBlockType)(headerType & 0x7F);

            byte[] metadataBlockLengthBytes = ReadExactly(3);
            int    metadataBlockLength      = metadataBlockLengthBytes[0] << 16 |
                                      metadataBlockLengthBytes[1] << 8 |
                                      metadataBlockLengthBytes[2];

            recordType = FlacRecordType.MetadataBlock;

            if (metadataBlockType == FlacMetadataBlockType.Streaminfo)
            {
                ReadStreaminfo(metadataBlockLength);
            }
            else
            {
                // TODO read other block types
                SkipData(metadataBlockLength);
            }
        }
Exemplo n.º 3
0
        public bool Read()
        {
            if (recordType == FlacRecordType.Eof)
            {
                return(false);
            }

            try
            {
                switch (recordType)
                {
                case FlacRecordType.None:
                    ReadFrame();
                    break;

                case FlacRecordType.Frame:
                    subframeIndex = 0;
                    ReadSubframe();
                    break;

                case FlacRecordType.Subframe:
                    if (!dataRead)
                    {
                        SkipSampleValues();
                    }
                    if (++subframeIndex < FrameChannelCount)
                    {
                        ReadSubframe();
                    }
                    else
                    {
                        ReadFrameFooter();
                    }
                    break;

                case FlacRecordType.FrameFooter:
                    ReadFrame();
                    break;

                case FlacRecordType.Error:
                    throw new FlacException("Reader in error state");

                case FlacRecordType.Sync:
                    ReadFrame();
                    break;

                default:
                    throw new NotImplementedException();
                }
                return(recordType != FlacRecordType.Eof);
            }
            catch
            {
                recordType = FlacRecordType.Error;
                throw;
            }
        }
Exemplo n.º 4
0
        public byte[] ReadFrameRawData()
        {
            if (recordType != FlacRecordType.Frame)
            {
                throw new FlacException("Cannot read non-frame data");
            }

            MemoryStream ms = new MemoryStream();

            ms.Write(lastFrameHeaderData, 0, lastFrameHeaderData.Length);

            // replace bitReader
            ushort currentCrc16 = bitReader.Complete();

            bitReader = new FlacBitStreamReader(
                new SinkedStream(BaseStream, ms), currentCrc16);

            // read subframes
            for (int i = 0; i < FrameChannelCount; i++)
            {
                ReadSubframe();
                SkipSampleValues();
            }
            bitReader.Complete();
            bitReader = null;

            // read footer
            byte[] crc16 = ReadExactly(2);
            recordType = FlacRecordType.FrameFooter;

            int frameDataLength = checked ((int)ms.Length);

            ms.Write(crc16, 0, crc16.Length);

            byte[] frameData = ms.ToArray();

            // check CRC16
            ushort dataCrc16 = CrcUtils.Crc16(0, frameData, 0, frameDataLength);
            int    footerCrc = (crc16[0] << 8) | crc16[1];

            if (dataCrc16 != footerCrc)
            {
                throw new FlacException("Invalid frame footer CRC16");
            }

            return(frameData);
        }
Exemplo n.º 5
0
        private void ReadFrameFooter()
        {
            ushort crc16 = bitReader.Complete();

            bitReader = null;

            byte[] data        = ReadExactly(2);
            int    footerCrc16 = data[0] << 8 | data[1];

            if (crc16 != footerCrc16)
            {
                throw new FlacException("Invalid frame footer CRC16");
            }

            subframeIndex = 0;

            this.recordType = FlacRecordType.FrameFooter;
        }
Exemplo n.º 6
0
        public bool Read()
        {
            if (recordType == FlacRecordType.Eof)
            {
                return(false);
            }

            try
            {
                switch (recordType)
                {
                case FlacRecordType.None:
                    ReadStream();
                    break;

                case FlacRecordType.Stream:
                    ReadMetadataBlock();
                    break;

                case FlacRecordType.MetadataBlock:
                    if (isLastMetadataBlock)
                    {
                        return(false);
                    }
                    else
                    {
                        ReadMetadataBlock();
                    }
                    break;

                case FlacRecordType.Error:
                    throw new FlacException("Reader in error state");

                default:
                    throw new NotImplementedException();
                }
                return(recordType != FlacRecordType.Eof);
            }
            catch
            {
                recordType = FlacRecordType.Error;
                throw;
            }
        }
Exemplo n.º 7
0
        private void ReadStream()
        {
            byte[] marker = new byte[FlacCommons.StreamMarker.Length];
            int    read   = BaseStream.Read(marker, 0, marker.Length);

            if (read != marker.Length)
            {
                throw new FlacException("Unexpected end of stream: fLaC is expected");
            }

            for (int i = 0; i < marker.Length; i++)
            {
                if (marker[i] != FlacCommons.StreamMarker[i])
                {
                    throw new FlacException("Invalid stream marker: fLaC is expected");
                }
            }

            recordType = FlacRecordType.Stream;
        }
Exemplo n.º 8
0
        private void ReadStream()
        {
            byte[] marker = new byte[FlacCommons.StreamMarker.Length];
            int read = BaseStream.Read(marker, 0, marker.Length);
            if (read != marker.Length)
                throw new FlacException("Unexpected end of stream: fLaC is expected");

            for (int i = 0; i < marker.Length; i++)
            {
                if (marker[i] != FlacCommons.StreamMarker[i])
                    throw new FlacException("Invalid stream marker: fLaC is expected");
            }

            recordType = FlacRecordType.Stream;
        }
Exemplo n.º 9
0
        public bool Read()
        {
            if (recordType == FlacRecordType.Eof)
                return false;

            try
            {
                switch (recordType)
                {
                    case FlacRecordType.None:
                        ReadStream();
                        break;
                    case FlacRecordType.Stream:
                        ReadMetadataBlock();
                        break;
                    case FlacRecordType.MetadataBlock:
                        if (isLastMetadataBlock)
                            ReadFrame();
                        else
                            ReadMetadataBlock();
                        break;
                    case FlacRecordType.Frame:
                        subframeIndex = 0;
                        ReadSubframe();
                        break;
                    case FlacRecordType.Subframe:
                        if (!dataRead)
                        {
                            SkipSampleValues();
                        }

                        if (++subframeIndex < FrameChannelCount)
                            ReadSubframe();
                        else
                            ReadFrameFooter();
                        break;
                    case FlacRecordType.FrameFooter:
                        ReadFrame();
                        break;
                    case FlacRecordType.Error:
                        throw new FlacException("Reader in error state");
                    case FlacRecordType.Sync:
                        ReadFrame();
                        break;
                    default:
                        throw new NotImplementedException();
                }
                return recordType != FlacRecordType.Eof;
            }
            catch
            {
                recordType = FlacRecordType.Error;
                throw;
            }
        }
Exemplo n.º 10
0
        public bool FindSync()
        {
            const byte FirstSyncByte = 0xFF;
            const byte SecondSyncByte = 0xF8;
            const byte SecondSyncByteMask = 0xFC;

            int b = BaseStream.ReadByte();
            bool found = false;
            while (b >= 0)
            {
                if (b == FirstSyncByte)
                {
                    b = BaseStream.ReadByte();
                    if (b >= 0 && (b & SecondSyncByteMask) == SecondSyncByte)
                    {
                        // sync found
                        secondSyncByte = (byte)b;
                        recordType = FlacRecordType.Sync;
                        found = true;
                        break;
                    }
                }
                else
                {
                    b = BaseStream.ReadByte();
                }
            }
            return found;
        }
Exemplo n.º 11
0
        private void ReadSubframe()
        {
            uint zeroPadding = bitReader.ReadBits(1);

            if (zeroPadding != 0)
            {
                throw new FlacException("Subframe zero padding is not zero");
            }
            int subframeType = (int)bitReader.ReadBits(6);

            SubframeType type;
            int          order = 0;

            if (subframeType == FlacCommons.ConstantSubframeType)
            {
                type = SubframeType.SubframeConstant;
            }
            else if (subframeType == FlacCommons.VerbatimSubframeType)
            {
                type = SubframeType.SubframeVerbatim;
            }
            else if (FlacCommons.FixedSubframeTypeStart <= subframeType &&
                     subframeType <= FlacCommons.FixedSubframeTypeEnd)
            {
                type  = SubframeType.SubframeFixed;
                order = subframeType - FlacCommons.FixedSubframeTypeStart;
            }
            else if (subframeType >= FlacCommons.LpcSubframeTypeStart)
            {
                type  = SubframeType.SubframeLpc;
                order = subframeType - FlacCommons.LpcSubframeTypeStart + 1;
            }
            else
            {
                throw new FlacException("Subframe type is set to reserved");
            }

            uint wastedBitsPerSampleFlag = bitReader.ReadBits(1);

            if (wastedBitsPerSampleFlag > 0)
            {
                this.wastedBitsPerSample = 1 + (int)bitReader.ReadUnary();
            }
            else
            {
                this.wastedBitsPerSample = 0;
            }

            this.subframeType = type;

            int subframeBitsPerSample = FrameBitsPerSample;

            if (ChannelAssignment[subframeIndex] == SoundChannelAssignment.Difference)
            {
                subframeBitsPerSample++; // undocumented
            }

            switch (type)
            {
            case SubframeType.SubframeConstant:
                PrepareConstantSubframe(subframeBitsPerSample);
                break;

            case SubframeType.SubframeVerbatim:
                PrepareVerbatimSubframe(subframeBitsPerSample);
                break;

            case SubframeType.SubframeLpc:
                PrepareLpcSubframe(order, subframeBitsPerSample);
                break;

            case SubframeType.SubframeFixed:
                PrepareFixedSubframe(order, subframeBitsPerSample);
                break;
            }

            this.recordType = FlacRecordType.Subframe;
            this.dataRead   = false;
        }
Exemplo n.º 12
0
        private void ReadFrame()
        {
            const int FrameHeaderLength            = 2 + 1 + 1;
            const int FrameSync                    = 0xFFF8;
            const int FrameSyncMask                = 0xFFFC;
            const int ReservedBlockSizeSamplesType = 0;
            const int InvalidSampleRateType        = 15;

            int read;

            byte[] data = new byte[FrameHeaderLength];
            if (recordType != FlacRecordType.Sync)
            {
                read = BaseStream.Read(data, 0, FrameHeaderLength);
                if (read < FrameHeaderLength)
                {
                    if (read <= 0)
                    {
                        recordType = FlacRecordType.Eof;
                        return;
                    }
                    throw new FlacException("Unexpected eof of stream: invalid frame header length");
                }

                if (((data[0] << 8 | data[1]) & FrameSyncMask) != FrameSync)
                {
                    throw new FlacException("Frame sync is expected");
                }
            }
            else
            {
                const int SyncReadLength = 2;
                read = BaseStream.Read(data, SyncReadLength, FrameHeaderLength - SyncReadLength);
                if (read + SyncReadLength < FrameHeaderLength)
                {
                    throw new FlacException("Unexpected eof of stream: invalid frame header length");
                }

                data[0] = (byte)(FrameSync >> 8); data[1] = secondSyncByte;
            }

            if ((data[1] & 0x02) != 0)
            {
                throw new FlacException("Frame header reserved bit (15) shall not be 1");
            }

            this.variableBlockSize = (data[1] & 0x01) != 0;

            int blockSizeSamplesType = data[2] >> 4;

            if (blockSizeSamplesType == ReservedBlockSizeSamplesType)
            {
                throw new FlacException("Frame header block size samples shall not be set to reserved");
            }

            int previousBlockSize = this.blockSize;

            this.blockSize = FlacCommons.StaticBlockSizeSamples[blockSizeSamplesType];

            int sampleRateType = data[2] & 0x0F;

            if (sampleRateType == InvalidSampleRateType)
            {
                throw new FlacException("Frame header sample rate type is invalid");
            }

            this.sampleRate = FlacCommons.StaticSampleRates[sampleRateType];

            int channelAssignmentType = data[3] >> 4;

            if (channelAssignmentType >= FlacCommons.StaticChannelAssignments.Length)
            {
                throw new FlacException("Frame header channel assignments are defined as reserved");
            }

            this.channelAssignmentType = (SoundChannelAssignmentType)channelAssignmentType;
            this.channelAssignment     = FlacCommons.StaticChannelAssignments[channelAssignmentType];
            if (channelAssignment == null)
            {
                throw new FlacException("Frame header channel assignment are not defined");
            }

            this.channelCount = channelAssignment.Length;

            int sampleSizeInBitsType = (data[3] >> 1) & 0x07;

            if (sampleSizeInBitsType == FlacCommons.StreaminfoSizeInBitsType)
            {
                this.sampleSizeInBits = Streaminfo.BitsPerSample;
            }
            else if (FlacCommons.StaticSampleSizeInBits[sampleSizeInBitsType] > 0)
            {
                this.sampleSizeInBits = FlacCommons.StaticSampleSizeInBits[sampleSizeInBitsType];
            }
            else
            {
                throw new FlacException("Frame header sample size is defined as reserved");
            }

            if ((data[3] & 1) != 0)
            {
                throw new FlacException("Frame header reserved bit (31) shall not be 1");
            }

            MemoryStream ms = new MemoryStream(20);

            ms.Write(data, 0, FrameHeaderLength);

            byte[] numberData;
            if (variableBlockSize)
            {
                ReadUtf8Number(out this.sampleNumber, out numberData);
                if (numberData.Length > 7)
                {
                    throw new FlacException("Invalid variable block size");
                }
            }
            else
            {
                ReadUtf8Number(out this.frameNumber, out numberData);
                if (numberData.Length > 6)
                {
                    throw new FlacException("Invalid frame number");
                }
                this.sampleNumber = this.frameNumber == 0 ? 0 :
                                    previousBlockSize *this.frameNumber;
            }
            ms.Write(numberData, 0, numberData.Length);

            byte[] blockSizeData = null;
            switch (blockSizeSamplesType)
            {
            case FlacCommons.Bit8BlockSizeSamplesType:
                blockSizeData  = ReadExactly(1);
                this.blockSize = (int)blockSizeData[0] + 1;
                break;

            case FlacCommons.Bit16BlockSizeSamplesType:
                blockSizeData  = ReadExactly(2);
                this.blockSize = (blockSizeData[0] << 8 | blockSizeData[1]) + 1;
                break;
            }
            if (blockSizeData != null)
            {
                ms.Write(blockSizeData, 0, blockSizeData.Length);
            }

            byte[] sampleRateData = null;
            switch (sampleRateType)
            {
            case FlacCommons.StreaminfoSampleRateType:
                this.sampleRate = Streaminfo.SampleRate;
                break;

            case FlacCommons.Bit8SampleRateType:
                sampleRateData  = ReadExactly(1);
                this.sampleRate = sampleRateData[0];
                break;

            case FlacCommons.Bit16SampleRateType:
                sampleRateData  = ReadExactly(2);
                this.sampleRate = sampleRateData[0] << 8 | sampleRateData[1];
                break;

            case FlacCommons.Bit16Mult10SampleRateType:
                sampleRateData  = ReadExactly(2);
                this.sampleRate = (sampleRateData[0] << 8 | sampleRateData[1]) * 10;
                break;
            }
            if (sampleRateData != null)
            {
                ms.Write(sampleRateData, 0, sampleRateData.Length);
            }

            byte[] readData   = ms.ToArray();
            byte   crc8       = CrcUtils.Crc8(0, readData);
            int    headerCrc8 = BaseStream.ReadByte();

            if (headerCrc8 < 0)
            {
                throw new FlacException("Unexpected end of stream: frame CRC8 expected");
            }
            else if (crc8 != headerCrc8)
            {
                throw new FlacException("Invalid frame CRC");
            }

            ushort currentCrc16 = CrcUtils.Crc16(
                CrcUtils.Crc16(0, readData), (byte)headerCrc8);

            bitReader = new FlacBitStreamReader(BaseStream, currentCrc16);

            lastFrameHeaderData = new byte[readData.Length + 1];
            Array.Copy(readData, lastFrameHeaderData, readData.Length);
            lastFrameHeaderData[readData.Length] = crc8;

            recordType = FlacRecordType.Frame;
        }
Exemplo n.º 13
0
        public byte[] ReadFrameRawData()
        {
            if(recordType != FlacRecordType.Frame)
                throw new FlacException("Cannot read non-frame data");

            MemoryStream ms = new MemoryStream();
            ms.Write(lastFrameHeaderData, 0, lastFrameHeaderData.Length);

            // replace bitReader
            ushort currentCrc16 = bitReader.Complete();
            bitReader = new FlacBitStreamReader(
                new SinkedStream(BaseStream, ms), currentCrc16);

            // read subframes
            for (int i = 0; i < FrameChannelCount; i++)
            {
                ReadSubframe();
                SkipSampleValues();
            }
            bitReader.Complete();
            bitReader = null;

            // read footer
            byte[] crc16 = ReadExactly(2);
            recordType = FlacRecordType.FrameFooter;

            int frameDataLength = checked((int)ms.Length);
            ms.Write(crc16, 0, crc16.Length);

            byte[] frameData = ms.ToArray();

            // check CRC16
            ushort dataCrc16 = CrcUtils.Crc16(0, frameData, 0, frameDataLength);
            int footerCrc = (crc16[0] << 8) | crc16[1];
            if(dataCrc16 != footerCrc)
                throw new FlacException("Invalid frame footer CRC16");

            return frameData;
        }
Exemplo n.º 14
0
        private void ReadFrame()
        {
            const int FrameHeaderLength = 2 + 1 + 1;
            const int FrameSync = 0xFFF8;
            const int FrameSyncMask = 0xFFFC;
            const int ReservedBlockSizeSamplesType = 0;
            const int InvalidSampleRateType = 15;

            int read;
            byte[] data = new byte[FrameHeaderLength];
            if (recordType != FlacRecordType.Sync)
            {
                read = BaseStream.Read(data, 0, FrameHeaderLength);
                if (read < FrameHeaderLength)
                {
                    if (read <= 0)
                    {
                        recordType = FlacRecordType.Eof;
                        return;
                    }
                    throw new FlacException("Unexpected eof of stream: invalid frame header length");
                }

                if (((data[0] << 8 | data[1]) & FrameSyncMask) != FrameSync)
                    throw new FlacException("Frame sync is expected");
            }
            else
            {
                const int SyncReadLength = 2;
                read = BaseStream.Read(data, SyncReadLength, FrameHeaderLength - SyncReadLength);
                if(read + SyncReadLength < FrameHeaderLength)
                    throw new FlacException("Unexpected eof of stream: invalid frame header length");

                data[0] = (byte)(FrameSync >> 8); data[1] = secondSyncByte;
            }

            if((data[1] & 0x02) != 0)
                throw new FlacException("Frame header reserved bit (15) shall not be 1");

            this.variableBlockSize = (data[1] & 0x01) != 0;

            int blockSizeSamplesType = data[2] >> 4;
            if(blockSizeSamplesType == ReservedBlockSizeSamplesType)
                throw new FlacException("Frame header block size samples shall not be set to reserved");

            int previousBlockSize = this.blockSize;

            this.blockSize = FlacCommons.StaticBlockSizeSamples[blockSizeSamplesType];

            int sampleRateType = data[2] & 0x0F;
            if(sampleRateType == InvalidSampleRateType)
                throw new FlacException("Frame header sample rate type is invalid");

            this.sampleRate = FlacCommons.StaticSampleRates[sampleRateType];

            int channelAssignmentType = data[3] >> 4;

            if (channelAssignmentType >= FlacCommons.StaticChannelAssignments.Length)
                throw new FlacException("Frame header channel assignments are defined as reserved");

            this.channelAssignmentType = (SoundChannelAssignmentType)channelAssignmentType;
            this.channelAssignment = FlacCommons.StaticChannelAssignments[channelAssignmentType];
            if (channelAssignment == null)
                throw new FlacException("Frame header channel assignment are not defined");

            this.channelCount = channelAssignment.Length;

            int sampleSizeInBitsType = (data[3] >> 1) & 0x07;
            if (sampleSizeInBitsType == FlacCommons.StreaminfoSizeInBitsType)
                this.sampleSizeInBits = Streaminfo.BitsPerSample;
            else if (FlacCommons.StaticSampleSizeInBits[sampleSizeInBitsType] > 0)
                this.sampleSizeInBits = FlacCommons.StaticSampleSizeInBits[sampleSizeInBitsType];
            else
                throw new FlacException("Frame header sample size is defined as reserved");

            if((data[3] & 1) != 0)
                throw new FlacException("Frame header reserved bit (31) shall not be 1");

            MemoryStream ms = new MemoryStream(20);
            ms.Write(data, 0, FrameHeaderLength);

            byte[] numberData;
            if (variableBlockSize)
            {
                ReadUtf8Number(out this.sampleNumber, out numberData);
                if (numberData.Length > 7)
                    throw new FlacException("Invalid variable block size");
            }
            else
            {
                ReadUtf8Number(out this.frameNumber, out numberData);
                if (numberData.Length > 6)
                    throw new FlacException("Invalid frame number");
                this.sampleNumber = this.frameNumber == 0 ? 0 :
                    previousBlockSize * this.frameNumber;
            }
            ms.Write(numberData, 0, numberData.Length);

            byte[] blockSizeData = null;
            switch (blockSizeSamplesType)
            {
                case FlacCommons.Bit8BlockSizeSamplesType:
                    blockSizeData = ReadExactly(1);
                    this.blockSize = (int)blockSizeData[0] + 1;
                    break;
                case FlacCommons.Bit16BlockSizeSamplesType:
                    blockSizeData = ReadExactly(2);
                    this.blockSize = (blockSizeData[0] << 8 | blockSizeData[1]) + 1;
                    break;
            }
            if(blockSizeData != null)
                ms.Write(blockSizeData, 0, blockSizeData.Length);

            byte[] sampleRateData = null;
            switch (sampleRateType)
            {
                case FlacCommons.StreaminfoSampleRateType:
                    this.sampleRate = Streaminfo.SampleRate;
                    break;
                case FlacCommons.Bit8SampleRateType:
                    sampleRateData = ReadExactly(1);
                    this.sampleRate = sampleRateData[0];
                    break;
                case FlacCommons.Bit16SampleRateType:
                    sampleRateData = ReadExactly(2);
                    this.sampleRate = sampleRateData[0] << 8 | sampleRateData[1];
                    break;
                case FlacCommons.Bit16Mult10SampleRateType:
                    sampleRateData = ReadExactly(2);
                    this.sampleRate = (sampleRateData[0] << 8 | sampleRateData[1]) * 10;
                    break;
            }
            if (sampleRateData != null)
                ms.Write(sampleRateData, 0, sampleRateData.Length);

            byte[] readData = ms.ToArray();
            byte crc8 = CrcUtils.Crc8(0, readData);
            int headerCrc8 = BaseStream.ReadByte();
            if (headerCrc8 < 0)
                throw new FlacException("Unexpected end of stream: frame CRC8 expected");
            else if(crc8 != headerCrc8)
                throw new FlacException("Invalid frame CRC");

            ushort currentCrc16 = CrcUtils.Crc16(
                CrcUtils.Crc16(0, readData), (byte)headerCrc8);

            bitReader = new FlacBitStreamReader(BaseStream, currentCrc16);

            lastFrameHeaderData = new byte[readData.Length + 1];
            Array.Copy(readData, lastFrameHeaderData, readData.Length);
            lastFrameHeaderData[readData.Length] = crc8;

            recordType = FlacRecordType.Frame;
        }
Exemplo n.º 15
0
        private void ReadSubframe()
        {
            uint zeroPadding = bitReader.ReadBits(1);
            if (zeroPadding != 0)
                throw new FlacException("Subframe zero padding is not zero");
            int subframeType = (int)bitReader.ReadBits(6);

            SubframeType type;
            int order = 0;
            if (subframeType == FlacCommons.ConstantSubframeType)
                type = SubframeType.SubframeConstant;
            else if (subframeType == FlacCommons.VerbatimSubframeType)
                type = SubframeType.SubframeVerbatim;
            else if (FlacCommons.FixedSubframeTypeStart <= subframeType &&
                subframeType <= FlacCommons.FixedSubframeTypeEnd)
            {
                type = SubframeType.SubframeFixed;
                order = subframeType - FlacCommons.FixedSubframeTypeStart;
            }
            else if (subframeType >= FlacCommons.LpcSubframeTypeStart)
            {
                type = SubframeType.SubframeLpc;
                order = subframeType - FlacCommons.LpcSubframeTypeStart + 1;
            }
            else
                throw new FlacException("Subframe type is set to reserved");

            uint wastedBitsPerSampleFlag = bitReader.ReadBits(1);
            if (wastedBitsPerSampleFlag > 0)
            {
                this.wastedBitsPerSample = 1 + (int)bitReader.ReadUnary();
            }
            else
                this.wastedBitsPerSample = 0;

            this.subframeType = type;

            int subframeBitsPerSample = FrameBitsPerSample;
            if (ChannelAssignment[subframeIndex] == SoundChannelAssignment.Difference)
            {
                subframeBitsPerSample++; // undocumented
            }

            switch (type)
            {
                case SubframeType.SubframeConstant:
                    PrepareConstantSubframe(subframeBitsPerSample);
                    break;
                case SubframeType.SubframeVerbatim:
                    PrepareVerbatimSubframe(subframeBitsPerSample);
                    break;
                case SubframeType.SubframeLpc:
                    PrepareLpcSubframe(order, subframeBitsPerSample);
                    break;
                case SubframeType.SubframeFixed:
                    PrepareFixedSubframe(order, subframeBitsPerSample);
                    break;
            }

            this.recordType = FlacRecordType.Subframe;
            this.dataRead = false;
        }
Exemplo n.º 16
0
        private void ReadFrameFooter()
        {
            ushort crc16 = bitReader.Complete();
            bitReader = null;

            byte[] data = ReadExactly(2);
            int footerCrc16 = data[0] << 8 | data[1];

            if (crc16 != footerCrc16)
                throw new FlacException("Invalid frame footer CRC16");

            subframeIndex = 0;

            this.recordType = FlacRecordType.FrameFooter;
        }
Exemplo n.º 17
0
        private void ReadMetadataBlock()
        {
            // read header
            int headerType = BaseStream.ReadByte();
            if (headerType < 0)
                throw new FlacException("Unexepted end of stream: metadata block expected");

            isLastMetadataBlock = (headerType & 0x80) != 0;

            metadataBlockType = (FlacMetadataBlockType)(headerType & 0x7F);

            byte[] metadataBlockLengthBytes = ReadExactly(3);
            int metadataBlockLength = metadataBlockLengthBytes[0] << 16 |
                metadataBlockLengthBytes[1] << 8 |
                metadataBlockLengthBytes[2];

            recordType = FlacRecordType.MetadataBlock;

            if (metadataBlockType == FlacMetadataBlockType.Streaminfo)
            {
                ReadStreaminfo(metadataBlockLength);
            }
            else
            {
                // TODO read other block types
                SkipData(metadataBlockLength);
            }
        }