public unsafe FlacMetadataStreamInfo(Stream stream, Int32 length, bool lastBlock)
            : base(FlacMetaDataType.StreamInfo, lastBlock, length)
        {
            //http://flac.sourceforge.net/format.html#metadata_block_streaminfo
            BinaryReader reader = new BinaryReader(stream, Encoding.ASCII);

            try
            {
                MinBlockSize = reader.ReadInt16();
                MaxBlockSize = reader.ReadInt16();
            }
            catch (IOException e)
            {
                throw new FlacException(e, FlacLayer.Metadata);
            }
            int bytesToRead = (240 / 8) - 16;

            byte[] buffer = reader.ReadBytes(bytesToRead);
            if (buffer.Length != bytesToRead)
                throw new FlacException(new EndOfStreamException("Could not read StreamInfo-content"), FlacLayer.Metadata);

            fixed(byte *b = buffer)
            {
                FlacBitReader bitreader = new FlacBitReader(b, 0);

                MinFrameSize  = bitreader.ReadBits(24);
                MaxFrameSize  = bitreader.ReadBits(24);
                SampleRate    = (int)bitreader.ReadBits(20);
                Channels      = 1 + (int)bitreader.ReadBits(3);
                BitsPerSample = 1 + (int)bitreader.ReadBits(5);
                TotalSamples  = (long)bitreader.ReadBits64(36);
                MD5           = new String(reader.ReadChars(16));
            }
        }
        /// <summary>
        ///     Initializes a new instance of the <see cref="FlacMetadataStreamInfo" /> class.
        /// </summary>
        /// <param name="stream">The stream which contains the <see cref="FlacMetadataStreamInfo"/>.</param>
        /// <param name="length">The length of the <see cref="FlacMetadataStreamInfo"/> inside of the stream in bytes. Does not include the metadata header.</param>
        /// <param name="lastBlock">
        ///     A value which indicates whether this is the last <see cref="FlacMetadata" /> block inside of
        ///     the stream. <c>true</c> means that this is the last <see cref="FlacMetadata" /> block inside of the stream.
        /// </param>
        public unsafe FlacMetadataStreamInfo(Stream stream, int length, bool lastBlock)
            : base(FlacMetaDataType.StreamInfo, lastBlock, length)
        {
            //http://flac.sourceforge.net/format.html#metadata_block_streaminfo
            var reader = new BinaryReader(stream, Encoding.ASCII);
            try
            {
                MinBlockSize = reader.ReadInt16();
                MaxBlockSize = reader.ReadInt16();
            }
            catch (IOException e)
            {
                throw new FlacException(e, FlacLayer.Metadata);
            }
            const int bytesToRead = (240 / 8) - 16;
            byte[] buffer = reader.ReadBytes(bytesToRead);
            if (buffer.Length != bytesToRead)
            {
                throw new FlacException(new EndOfStreamException("Could not read StreamInfo-content"),
                    FlacLayer.Metadata);
            }

            fixed (byte* b = buffer)
            {
                var bitreader = new FlacBitReader(b, 0);
                MinFrameSize = (int) bitreader.ReadBits(24);
                MaxFrameSize = (int) bitreader.ReadBits(24);
                SampleRate = (int) bitreader.ReadBits(20);
                Channels = 1 + (int) bitreader.ReadBits(3);
                BitsPerSample = 1 + (int) bitreader.ReadBits(5);
                TotalSamples = (long) bitreader.ReadBits64(36);
                Md5 = new String(reader.ReadChars(16));
            }
        }
 public FlacSubFrameConstant(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample)
     : base(header)
 {
     unchecked
     {
         var value = (int)reader.ReadBits(bitsPerSample);
         data.DestinationBuffer.Span.Fill(value);
     }
 }
Example #4
0
        public unsafe FlacSubFrameLPC(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bps, int order)
            : base(header)
        {
            //warmup
            _warmup = new int[FlacConstant.MAX_LPC_ORDER];
            for (int i = 0; i < order; i++)
            {
                _warmup[i] = data.residualBuffer[i] = reader.ReadBitsSigned(bps);
            }

            //header
            int u32 = (int)reader.ReadBits(FlacConstant.SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN);
            if (u32 == (1 << FlacConstant.SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1)
            {
                Debug.WriteLine("Invalid FlacLPC qlp coeff precision.");
                return; //return false;
            }
            _qlpCoeffPrecision = u32 + 1;

            int level = reader.ReadBitsSigned(FlacConstant.SUBFRAME_LPC_QLP_SHIFT_LEN);
            if (level < 0)
                throw new Exception("negative shift");
            _lpcShiftNeeded = level;

            _qlpCoeffs = new int[FlacConstant.MAX_LPC_ORDER];

            //qlp coeffs
            for (int i = 0; i < order; i++)
            {
                _qlpCoeffs[i] = reader.ReadBitsSigned(_qlpCoeffPrecision);
            }

            //QLPCoeffs = coeffs;

            Residual = new FlacResidual(reader, header, data, order);

            for (int i = 0; i < order; i++)
            {
                data.destBuffer[i] = data.residualBuffer[i];
            }

            if (bps + _qlpCoeffPrecision + CSMath.ILog(order) <= 32)
            {
                if (bps <= 16 && _qlpCoeffPrecision <= 16)
                    RestoreLPCSignal(data.residualBuffer + order, data.destBuffer + order, header.BlockSize - order, order); //Restore(data.residualBuffer + order, data.destBuffer, Header.BlockSize - order, order, order);
                else
                    RestoreLPCSignal(data.residualBuffer + order, data.destBuffer + order, header.BlockSize - order, order);
            }
            else
            {
                RestoreLPCSignalWide(data.residualBuffer + order, data.destBuffer + order, header.BlockSize - order, order);//RestoreWide(data.residualBuffer + order, data.destBuffer, Header.BlockSize - order, order, order);
            }

            //Warmup = warmup;
        }
Example #5
0
        public unsafe FlacSubFrameFixed(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bps, int order)
            : base(header)
        {
            for (int i = 0; i < order; i++)
            {
                data.residualBuffer[i] = data.destBuffer[i] = reader.ReadBitsSigned(bps);
            }

            Residual = new FlacResidual(reader, header, data, order);
            RestoreSignal(data, header.BlockSize - order, order);
        }
Example #6
0
        public unsafe FlacSubFrameLPC(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample, int order)
            : base(header)
        {
            var warmup = new int[order];
            for (int i = 0; i < order; i++)
            {
                warmup[i] = data.ResidualBuffer[i] = reader.ReadBitsSigned(bitsPerSample);
            }

            int coefPrecision = (int)reader.ReadBits(4) + 1;
            if (coefPrecision == 0x0F)
            {
                Debug.WriteLine("Invalid linear predictor coefficients' precision. Must not be 0x0F.");
                return;
            }

            int shiftNeeded = reader.ReadBitsSigned(5);
            if (shiftNeeded < 0)
                throw new FlacException("\"Quantized linear predictor coefficient shift needed.\" was negative.", FlacLayer.SubFrame);

            var q = new int[order];
            for (int i = 0; i < order; i++)
            {
                q[i] = reader.ReadBitsSigned(coefPrecision);
            }

            //decode the residual
            var residual = new FlacResidual(reader, header, data, order);
            for (int i = 0; i < order; i++)
            {
                data.DestinationBuffer[i] = data.ResidualBuffer[i];
            }

            int* residualBuffer0 = data.ResidualBuffer + order;
            int* destinationBuffer0 = data.DestinationBuffer + order;
            int blockSizeToProcess = header.BlockSize - order;

            if (bitsPerSample + coefPrecision + Log2(order) <= 32)
            {
                RestoreLPCSignal32(residualBuffer0, destinationBuffer0, blockSizeToProcess, order, q, shiftNeeded);
            }
            else
            {
                RestoreLPCSignal64(residualBuffer0, destinationBuffer0, blockSizeToProcess, order, q, shiftNeeded);
            }

            #if FLAC_DEBUG
            QLPCoeffPrecision = coefPrecision;
            LPCShiftNeeded = shiftNeeded;
            Warmup = warmup;
            Residual = residual;
            QLPCoeffs = q;
            #endif
        }
Example #7
0
        public unsafe FlacSubFrameFixed(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bps, int order)
            : base(header)
        {
            for (int i = 0; i < order; i++)
            {
                data.residualBuffer[i] = data.destBuffer[i] = reader.ReadBitsSigned(bps);
            }

            Residual = new FlacResidual(reader, header, data, order);
            RestoreSignal(data, header.BlockSize - order, order);
        }
        public FlacSubFrameLPC(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample,
                               int order)
            : base(header)
        {
            unchecked
            {
                var resi = data.ResidualBuffer.Span;
                var dest = data.DestinationBuffer.Span;

                for (var i = 0; i < order; i++)
                {
                    resi[i] = reader.ReadBitsSigned(bitsPerSample);
                }

                var coefPrecision = (int)reader.ReadBits(4);
                if (coefPrecision == 0x0F)
                {
                    throw new FlacException(
                              "Invalid \"quantized linear predictor coefficients' precision in bits\" was invalid. Must not be 0x0F.",
                              FlacLayer.SubFrame);
                }
                coefPrecision += 1;

                var shiftNeeded = reader.ReadBitsSigned(5);
                if (shiftNeeded < 0)
                {
                    throw new FlacException(
                              "'\"Quantized linear predictor coefficient shift needed in bits\" was negative.",
                              FlacLayer.SubFrame);
                }

                var q = new int[order];
                for (var i = 0; i < order; i++)
                {
                    q[i] = reader.ReadBitsSigned(coefPrecision);
                }

                //decode the residual
                new FlacResidual(reader, header, data, order);
                resi.Slice(0, order).CopyTo(dest);

                var blockSizeToProcess = header.BlockSize - order;

                if (bitsPerSample + coefPrecision + Log2(order) <= 32)
                {
                    RestoreLPCSignal32(resi, dest, blockSizeToProcess, order, q, shiftNeeded);
                }
                else
                {
                    RestoreLPCSignal64(resi, dest, blockSizeToProcess, order, q, shiftNeeded);
                }
            }
        }
Example #9
0
        public unsafe static FlacMetadata FromStream(Stream stream)
        {
            bool             lastBlock = false;
            FlacMetaDataType type      = FlacMetaDataType.Undef;
            int length = 0;

            byte[] b = new byte[4];
            if (stream.Read(b, 0, 4) <= 0)
            {
                throw new FlacException(new EndOfStreamException("Could not read metadata"), FlacLayer.Metadata);

                fixed(byte *headerBytes = b)
                {
                    FlacBitReader bitReader = new FlacBitReader(headerBytes, 0);

                    lastBlock = bitReader.ReadBits(1) == 1;
                    type      = (FlacMetaDataType)bitReader.ReadBits(7);
                    length    = (int)bitReader.ReadBits(24);
                    ////1000 0000
                    //if (((b[0] & 0x80) >> 7) == 1)
                    //    lastBlock = true;
                    //type = (FlacMetaDataType)(b[0] & 0x7F);
                    //int length = (b[1] + (b[2] << 8) + (b[3] << 16));
                }

                FlacMetadata data;
                long streamStartPosition = stream.Position;
                if ((int)type < 0 || (int)type > 6)
                    return(null); }
                else
                {
                    switch (type)
                    {
                    case FlacMetaDataType.StreamInfo:
                        data = new FlacMetadataStreamInfo(stream, length, lastBlock);
                        break;

                    case FlacMetaDataType.Seektable:
                        data = new FlacMetadataSeekTable(stream, length, lastBlock);
                        break;

                    default:
                        data = new FlacMetadata(type, lastBlock, length);
                        break;
                    }
                }

                stream.Seek(length - (stream.Position - streamStartPosition), SeekOrigin.Current);
                return(data);
        }
Example #10
0
        private unsafe void ReadSubFrames(int *ptrDestBuffer, int *ptrResidualBuffer)
        {
            List <FlacSubFrameBase> subFrames = new List <FlacSubFrameBase>();

            //alocateOutput
            var data = AllocOuputMemory(ptrDestBuffer, ptrResidualBuffer);

            _subFrameData = data;

            byte[] buffer = new byte[0x20000];
            if ((_streamInfo.MaxFrameSize * Header.Channels * Header.BitsPerSample * 2 >> 3) > buffer.Length)
            {
                buffer = new byte[(_streamInfo.MaxFrameSize * Header.Channels * Header.BitsPerSample * 2 >> 3) - FlacConstant.FrameHeaderSize];
            }

            int read = _stream.Read(buffer, 0, (int)Math.Min(buffer.Length, _stream.Length - _stream.Position));

            fixed(byte *ptrBuffer = buffer)
            {
                FlacBitReader reader = new FlacBitReader(ptrBuffer, 0);

                for (int c = 0; c < Header.Channels; c++)
                {
                    int bitsPerSample = Header.BitsPerSample;
                    if (Header.ChannelAssignment == ChannelAssignment.MidSide || Header.ChannelAssignment == ChannelAssignment.LeftSide)
                    {
                        bitsPerSample += c;
                    }
                    else if (Header.ChannelAssignment == ChannelAssignment.RightSide)
                    {
                        bitsPerSample += 1 - c;
                    }

                    var subframe = FlacSubFrameBase.GetSubFrame(reader, data[c], Header, bitsPerSample);
                    subFrames.Add(subframe);
                }

                reader.Flush(); //Zero-padding to byte alignment.

                //footer
                Crc16 = (short)reader.ReadBits(16);

                _stream.Position -= read - reader.Position;
                MapToChannels(_subFrameData);
            }

#if FLAC_DEBUG
            _subFrames = subFrames.AsReadOnly();
#endif
        }
Example #11
0
        public static unsafe FlacMetadata FromStream(Stream stream)
        {
            bool lastBlock = false;
            FlacMetaDataType type = FlacMetaDataType.Undef;
            int length = 0;

            byte[] b = new byte[4];
            if (stream.Read(b, 0, 4) <= 0)
                throw new FlacException(new EndOfStreamException("Could not read metadata"), FlacLayer.Metadata);

            fixed (byte* headerBytes = b)
            {
                FlacBitReader bitReader = new FlacBitReader(headerBytes, 0);

                lastBlock = bitReader.ReadBits(1) == 1;
                type = (FlacMetaDataType)bitReader.ReadBits(7);
                length = (int)bitReader.ReadBits(24);
                ////1000 0000
                //if (((b[0] & 0x80) >> 7) == 1)
                //    lastBlock = true;
                //type = (FlacMetaDataType)(b[0] & 0x7F);
                //int length = (b[1] + (b[2] << 8) + (b[3] << 16));
            }

            FlacMetadata data;
            long streamStartPosition = stream.Position;
            if ((int)type < 0 || (int)type > 6)
                return null;
            else
            {
                switch (type)
                {
                    case FlacMetaDataType.StreamInfo:
                        data = new FlacMetadataStreamInfo(stream, length, lastBlock);
                        break;

                    case FlacMetaDataType.Seektable:
                        data = new FlacMetadataSeekTable(stream, length, lastBlock);
                        break;

                    default:
                        data = new FlacMetadata(type, lastBlock, length);
                        break;
                }
            }

            stream.Seek(length - (stream.Position - streamStartPosition), SeekOrigin.Current);
            return data;
        }
Example #12
0
        private unsafe int ReadSubFrames()
        {
            List <FlacSubFrameBase> subFrames = new List <FlacSubFrameBase>();

            //alocateOutput
            var data = AllocOuputMemory();

            _data = data;

            byte[] buffer = new byte[0x20000];
            if ((_streamInfo.MaxFrameSize * Header.Channels * Header.BitsPerSample * 2 >> 3) > buffer.Length)
            {
                buffer = new byte[(_streamInfo.MaxFrameSize * Header.Channels * Header.BitsPerSample * 2 >> 3) - FlacConstant.FrameHeaderSize];
            }

            int read = _stream.Read(buffer, 0, (int)Math.Min(buffer.Length, _stream.Length - _stream.Position));

            fixed(byte *ptrBuffer = buffer)
            {
                FlacBitReader     reader            = new FlacBitReader(ptrBuffer, 0);
                ChannelAssignment channelAssignment = Header.ChannelAssignment;

                for (int c = 0; c < Header.Channels; c++)
                {
                    int bps = Header.BitsPerSample;
                    if (Header.ChannelAssignment == ChannelAssignment.MidSide || Header.ChannelAssignment == ChannelAssignment.LeftSide)
                    {
                        bps += c;
                    }
                    else if (Header.ChannelAssignment == ChannelAssignment.RightSide)
                    {
                        bps += 1 - c;
                    }

                    var subframe = FlacSubFrameBase.GetSubFrame(reader, data[c], Header, bps);

                    subFrames.Add(subframe);
                }

                reader.Flush();
                CRC16 = (ushort)reader.ReadBits(16);

                _stream.Position -= read - reader.Position;

                SamplesToBytes(_data);

                return(reader.Position);
            }
        }
Example #13
0
        public FlacResidual(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int order)
        {
            var codingMethod = (FlacResidualCodingMethod)reader.ReadBits(2); // 2 Bit

            if (codingMethod == FlacResidualCodingMethod.PartitionedRice || codingMethod == FlacResidualCodingMethod.PartitionedRice2)
            {
                var partitionOrder = (int)reader.ReadBits(4); //"Partition order." see https://xiph.org/flac/format.html#partitioned_rice and https://xiph.org/flac/format.html#partitioned_rice2

                FlacPartitionedRice.ProcessResidual(reader, header, data, order, partitionOrder, codingMethod);
            }
            else
            {
                throw new FlacException("Not supported RICE-Coding-Method. Stream unparseable!", FlacLayer.SubFrame);
            }
        }
Example #14
0
        public unsafe FlacSubFrameFixed(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample, int order)
            : base(header)
        {
            for (int i = 0; i < order; i++) //order = predictor order
            {
                data.ResidualBuffer[i] = data.DestinationBuffer[i] = reader.ReadBitsSigned(bitsPerSample);
            }

            var residual = new FlacResidual(reader, header, data, order); //necessary for decoding
            RestoreSignal(data, header.BlockSize - order, order);

            #if FLAC_DEBUG
            Residual = residual;
            #endif
        }
Example #15
0
        public unsafe FlacSubFrameFixed(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample, int order)
            : base(header)
        {
            for (int i = 0; i < order; i++) //order = predictor order
            {
                data.ResidualBuffer[i] = data.DestinationBuffer[i] = reader.ReadBitsSigned(bitsPerSample);
            }

            var residual = new FlacResidual(reader, header, data, order); //necessary for decoding

            RestoreSignal(data, header.BlockSize - order, order);

#if FLAC_DEBUG
            Residual = residual;
#endif
        }
        public FlacSubFrameVerbatim(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data,
                                    int bitsPerSample)
            : base(header)
        {
            unchecked
            {
                var dest = data.DestinationBuffer.Span;
                var resi = data.ResidualBuffer.Span;

                for (var i = 0; i < header.BlockSize; i++)
                {
                    var x = (int)reader.ReadBits(bitsPerSample);
                    dest[i] = resi[i] = x;
                }
            }
        }
Example #17
0
        public FlacSubFrameFixed(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample,
                                 int order)
            : base(header)
        {
            unchecked
            {
                var resi = data.ResidualBuffer.Span;
                var dest = data.DestinationBuffer.Span;
                for (var i = 0; i < order; i++) //order = predictor order
                {
                    resi[i] = dest[i] = reader.ReadBitsSigned(bitsPerSample);
                }

                new FlacResidual(reader, header, data, order); //necessary for decoding
                RestoreSignal(data, header.BlockSize - order, order);
            }
        }
Example #18
0
        public unsafe bool ProcessResidual(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int order)
        {
            data.Content.UpdateSize(PartitionOrder);

            int porder = PartitionOrder;
            FlacEntropyCoding codingMethod = CodingMethod;

            int psize   = header.BlockSize >> porder;
            int res_cnt = psize - order;

            int ricelength = 4 + (int)codingMethod; //4bit = RICE I | 5bit = RICE II

            //residual
            int  j = order;
            int *r = data.residualBuffer + j;

            int partitioncount = 1 << porder;

            for (int p = 0; p < partitioncount; p++)
            {
                if (p == 1)
                {
                    res_cnt = psize;
                }
                int n = Math.Min(res_cnt, header.BlockSize - j);

                int k = Content.parameters[p] = (int)reader.ReadBits(ricelength);
                if (k == (1 << ricelength) - 1)
                {
                    k = (int)reader.ReadBits(5);
                    for (int i = n; i > 0; i--)
                    {
                        *(r) = reader.ReadBitsSigned((int)k);
                    }
                }
                else
                {
                    ReadFlacRiceBlock(reader, n, (int)k, r);
                    r += n;
                }
                j += n;
            }

            return(true);
        }
Example #19
0
        private unsafe void ReadFlacRiceBlock(FlacBitReader reader, int nvals, int riceParameter, int *ptrDest)
        {
            fixed(byte *putable = FlacBitReader.UnaryTable)
            {
                uint mask = (1u << riceParameter) - 1;

                if (riceParameter == 0)
                {
                    for (int i = 0; i < nvals; i++)
                    {
                        *(ptrDest++) = reader.ReadUnarySigned();
                    }
                }
                else
                {
                    for (int i = 0; i < nvals; i++)
                    {
                        uint bits = putable[reader.Cache >> 24];
                        uint msbs = bits;

                        while (bits == 8)
                        {
                            reader.SeekBits(8);
                            bits  = putable[reader.Cache >> 24];
                            msbs += bits;
                        }

                        uint uval = 0;
                        if (riceParameter <= 16)
                        {
                            int btsk = riceParameter + (int)bits + 1;
                            uval = (msbs << riceParameter) | ((reader.Cache >> (32 - btsk)) & mask);
                            reader.SeekBits(btsk);
                        }
                        else
                        {
                            reader.SeekBits((int)(msbs & 7) + 1);
                            uval = (msbs << riceParameter) | ((reader.Cache >> (32 - riceParameter)));
                            reader.SeekBits(riceParameter);
                        }
                        *(ptrDest++) = (int)(uval >> 1 ^ -(int)(uval & 1));
                    }
                }
            }
        }
Example #20
0
        private unsafe void ReadFlacRiceBlock(FlacBitReader reader, int nvals, int riceParameter, int* ptrDest)
        {
            fixed (byte* putable = FlacBitReader.UnaryTable)
            {
                uint mask = (1u << riceParameter) - 1;
                if (riceParameter == 0)
                {
                    for (int i = 0; i < nvals; i++)
                    {
                        *(ptrDest++) = reader.ReadUnarySigned();
                    }
                }
                else
                {
                    for (int i = 0; i < nvals; i++)
                    {
                        uint bits = putable[reader.Cache >> 24];
                        uint msbs = bits;

                        while (bits == 8)
                        {
                            reader.SeekBits(8);
                            bits = putable[reader.Cache >> 24];
                            msbs += bits;
                        }

                        uint uval = 0;
                        if (riceParameter <= 16)
                        {
                            int btsk = riceParameter + (int)bits + 1;
                            uval = (msbs << riceParameter) | ((reader.Cache >> (32 - btsk)) & mask);
                            reader.SeekBits(btsk);
                        }
                        else
                        {
                            reader.SeekBits((int)(msbs & 7) + 1);
                            uval = (msbs << riceParameter) | ((reader.Cache >> (32 - riceParameter)));
                            reader.SeekBits(riceParameter);
                        }
                        *(ptrDest++) = (int)(uval >> 1 ^ -(int)(uval & 1));
                    }
                }
            }
        }
Example #21
0
        /// <summary>
        /// Reads and returns a single <see cref="FlacMetadata"/> from the specified <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">The stream which contains the <see cref="FlacMetadata"/>.</param>
        /// <returns>Returns the read <see cref="FlacMetadata"/>.</returns>
        public static unsafe FlacMetadata FromStream(Stream stream)
        {
            bool lastBlock;
            FlacMetaDataType type;
            int length;

            byte[] b = new byte[4];
            if (stream.Read(b, 0, 4) <= 0)
                throw new FlacException(new EndOfStreamException("Could not read metadata"), FlacLayer.Metadata);

            fixed (byte* headerBytes = b)
            {
                FlacBitReader bitReader = new FlacBitReader(headerBytes, 0);

                lastBlock = bitReader.ReadBits(1) == 1;
                type = (FlacMetaDataType)bitReader.ReadBits(7);
                length = (int)bitReader.ReadBits(24);
            }

            FlacMetadata data;
            long streamStartPosition = stream.Position;
            if ((int)type < 0 || (int)type > 6)
                return null;

            switch (type)
            {
                case FlacMetaDataType.StreamInfo:
                    data = new FlacMetadataStreamInfo(stream, length, lastBlock);
                    break;

                case FlacMetaDataType.Seektable:
                    data = new FlacMetadataSeekTable(stream, length, lastBlock);
                    break;

                default:
                    data = new FlacMetadata(type, lastBlock, length);
                    break;
            }

            stream.Seek(length - (stream.Position - streamStartPosition), SeekOrigin.Current);
            return data;
        }
Example #22
0
        public unsafe bool ProcessResidual(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int order)
        {
            data.Content.UpdateSize(PartitionOrder);

            int porder = PartitionOrder;
            FlacEntropyCoding codingMethod = CodingMethod;

            int psize = header.BlockSize >> porder;
            int res_cnt = psize - order;

            int ricelength = 4 + (int)codingMethod; //4bit = RICE I | 5bit = RICE II

            //residual
            int j = order;
            int* r = data.residualBuffer + j;

            int partitioncount = 1 << porder;

            for (int p = 0; p < partitioncount; p++)
            {
                if (p == 1) res_cnt = psize;
                int n = Math.Min(res_cnt, header.BlockSize - j);

                int k = Content.parameters[p] = (int)reader.ReadBits(ricelength);
                if (k == (1 << ricelength) - 1)
                {
                    k = (int)reader.ReadBits(5);
                    for (int i = n; i > 0; i--)
                    {
                        *(r) = reader.ReadBitsSigned((int)k);
                    }
                }
                else
                {
                    ReadFlacRiceBlock(reader, n, (int)k, r);
                    r += n;
                }
                j += n;
            }

            return true;
        }
Example #23
0
        /// <summary>
        /// Initializes the properties of the <see cref="FlacMetadata"/> by reading them from the <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">The stream which contains the metadata.</param>
        protected override unsafe void InitializeByStream(Stream stream)
        {
            //http://flac.sourceforge.net/format.html#metadata_block_streaminfo
            var reader = new BinaryReader(stream, Encoding.ASCII);

            try
            {
                MinBlockSize = reader.ReadInt16();
                MaxBlockSize = reader.ReadInt16();
            }
            catch (IOException e)
            {
                throw new FlacException(e, FlacLayer.Metadata);
            }
            const int bytesToRead = (240 / 8) - 16;
            var       buffer      = reader.ReadBytes(bytesToRead);

            if (buffer.Length != bytesToRead)
            {
                throw new FlacException(new EndOfStreamException("Could not read StreamInfo-content"),
                                        FlacLayer.Metadata);
            }

            fixed(byte *b = buffer)
            {
                var bitreader = new FlacBitReader(b, 0);

                MinFrameSize  = (int)bitreader.ReadBits(24);
                MaxFrameSize  = (int)bitreader.ReadBits(24);
                SampleRate    = (int)bitreader.ReadBits(20);
                Channels      = 1 + (int)bitreader.ReadBits(3);
                BitsPerSample = 1 + (int)bitreader.ReadBits(5);
                TotalSamples  = (long)bitreader.ReadBits64(36);
                Md5           = new string(reader.ReadChars(16));
            }
        }
Example #24
0
        public unsafe FlacSubFrameLPC(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample, int order)
            : base(header)
        {
            var warmup = new int[order];

            for (int i = 0; i < order; i++)
            {
                warmup[i] = data.ResidualBuffer[i] = reader.ReadBitsSigned(bitsPerSample);
            }

            int coefPrecision = (int)reader.ReadBits(4);

            if (coefPrecision == 0x0F)
            {
                throw new FlacException("Invalid \"quantized linear predictor coefficients' precision in bits\" was invalid. Must not be 0x0F.",
                                        FlacLayer.SubFrame);
            }
            coefPrecision += 1;

            int shiftNeeded = reader.ReadBitsSigned(5);

            if (shiftNeeded < 0)
            {
                throw new FlacException("'\"Quantized linear predictor coefficient shift needed in bits\" was negative.", FlacLayer.SubFrame);
            }

            var q = new int[order];

            for (int i = 0; i < order; i++)
            {
                q[i] = reader.ReadBitsSigned(coefPrecision);
            }

            //decode the residual
            var residual = new FlacResidual(reader, header, data, order);

            for (int i = 0; i < order; i++)
            {
                data.DestinationBuffer[i] = data.ResidualBuffer[i];
            }

            int *residualBuffer0    = data.ResidualBuffer + order;
            int *destinationBuffer0 = data.DestinationBuffer + order;
            int  blockSizeToProcess = header.BlockSize - order;

            if (bitsPerSample + coefPrecision + Log2(order) <= 32)
            {
                RestoreLPCSignal32(residualBuffer0, destinationBuffer0, blockSizeToProcess, order, q, shiftNeeded);
            }
            else
            {
                RestoreLPCSignal64(residualBuffer0, destinationBuffer0, blockSizeToProcess, order, q, shiftNeeded);
            }

#if FLAC_DEBUG
            QLPCoeffPrecision = coefPrecision;
            LPCShiftNeeded    = shiftNeeded;
            Warmup            = warmup;
            Residual          = residual;
            QLPCoeffs         = q;
#endif
        }
Example #25
0
        public unsafe static FlacSubFrameBase GetSubFrame(FlacBitReader reader, FlacSubFrameData data, FlacFrameHeader header, int bps)
        {
            uint x;
            int  wastedBits = 0, totalBits = 0, order = 0;

            x = reader.ReadBits(8);
            bool haswastedBits = (x & 1) != 0;

            x &= 0xFE; //1111 1110

            if (haswastedBits)
            {
                int u = (int)reader.ReadUnary();
                wastedBits = u + 1;
                bps       -= wastedBits;
                totalBits  = bps;
            }

            if ((x & 0x80) != 0)
            {
                Debug.WriteLine("Flacdecoder lost sync while reading FlacSubFrameHeader. [x & 0x80].");
                return(null);
            }

            FlacSubFrameBase subFrame = null;

            if ((x > 2 && x < 16) ||
                (x > 24 && x < 64))
            {
                Debug.WriteLine("Invalid FlacSubFrameHeader. [" + x.ToString("x") + "]");
                return(null);
            }
            else if (x == 0)
            {
                subFrame = new FlacSubFrameConstant(reader, header, data, bps);
            }
            else if (x == 2)
            {
                //verbatim
                subFrame = new FlacSubFrameVerbatim(reader, header, data, bps);
            }
            else if (x >= 16 && x <= 24)
            {
                //fixed
                order    = (int)((x >> 1) & 7);
                subFrame = new FlacSubFrameFixed(reader, header, data, bps, order);
            }
            else if (x >= 64)
            {
                //lpc
                order    = (int)(((x >> 1) & 31) + 1);
                subFrame = new FlacSubFrameLPC(reader, header, data, bps, order);
            }
            else
            {
                Debug.WriteLine("Invalid Flac-SubframeType: x = " + x + ".");
                return(null);
            }

            if (haswastedBits)
            {
                int *ptrDest = data.destBuffer;
                for (int i = 0; i < header.BlockSize; i++)
                {
                    *(ptrDest++) <<= wastedBits;
                }
            }

            //System.Diagnostics.Debug.WriteLine(subFrame.GetType().Name);

            if (subFrame != null)
            {
                subFrame.WastedBits = wastedBits;
            }
            else
            {
                Debug.WriteLine("Unknown error while reading FlacSubFrameHeader");
            }

            return(subFrame);
        }
Example #26
0
        public static unsafe FlacSubFrameBase GetSubFrame(FlacBitReader reader, FlacSubFrameData data, FlacFrameHeader header, int bitsPerSample)
        {
            int wastedBits = 0, order;

            uint firstByte = reader.ReadBits(8);

            if ((firstByte & 0x80) != 0) //Zero bit padding, to prevent sync-fooling string of 1s
            {
                Debug.WriteLine("Flacdecoder subframe-header got no zero-bit padding.");
                return null;
            }

            bool hasWastedBits = (firstByte & 1) != 0; //Wasted bits-per-sample' flag
            if (hasWastedBits)
            {
                int k = (int)reader.ReadUnary();
                wastedBits = k + 1; //"k-1" follows -> add 1
                bitsPerSample -= wastedBits;
            }

            FlacSubFrameBase subFrame;
            var subframeType = (firstByte & 0x7E) >> 1; //0111 1110

            if (subframeType == 0) //000000
            {
                subFrame = new FlacSubFrameConstant(reader, header, data, bitsPerSample);
            }
            else if (subframeType == 1) //000001
            {
                subFrame = new FlacSubFrameVerbatim(reader, header, data, bitsPerSample);
            }
            else if ((subframeType & 0x08) != 0) //001000 = 0x08
            {
                order = (int) (subframeType & 0x07);
                subFrame = new FlacSubFrameFixed(reader, header, data, bitsPerSample, order);
            }
            else if ((subframeType & 0x20) != 0) //100000 = 0x20
            {
                order = (int) (subframeType & 0x1F) + 1;
                subFrame = new FlacSubFrameLPC(reader, header, data, bitsPerSample, order);
            }
            else
            {
                Debug.WriteLine(String.Format("Invalid Flac-SubframeType. SubframeType: 0x{0:x}.", subframeType));
                return null;
            }

            if (hasWastedBits)
            {
                int* destination = data.DestinationBuffer;
                for (int i = 0; i < header.BlockSize; i++)
                {
                    *(destination++) <<= wastedBits;
                }
            }

            #if FLAC_DEBUG
            subFrame.WastedBits = wastedBits;
            #endif
            return subFrame;
        }
Example #27
0
        public static unsafe FlacSubFrameBase GetSubFrame(FlacBitReader reader, FlacSubFrameData data, FlacFrameHeader header, int bps)
        {
            uint x;
            int wastedBits = 0, totalBits = 0, order = 0;

            x = reader.ReadBits(8);
            bool haswastedBits = (x & 1) != 0;
            x &= 0xFE; //1111 1110

            if (haswastedBits)
            {
                int u = (int)reader.ReadUnary();
                wastedBits = u + 1;
                bps -= wastedBits;
                totalBits = bps;
            }

            if ((x & 0x80) != 0)
            {
                Debug.WriteLine("Flacdecoder lost sync while reading FlacSubFrameHeader. [x & 0x80].");
                return null;
            }

            FlacSubFrameBase subFrame = null;

            if ((x > 2 && x < 16) ||
                 (x > 24 && x < 64))
            {
                Debug.WriteLine("Invalid FlacSubFrameHeader. [" + x.ToString("x") + "]");
                return null;
            }
            else if (x == 0)
            {
                subFrame = new FlacSubFrameConstant(reader, header, data, bps);
            }
            else if (x == 2)
            {
                //verbatim
                subFrame = new FlacSubFrameVerbatim(reader, header, data, bps);
            }
            else if (x >= 16 && x <= 24)
            {
                //fixed
                order = (int)((x >> 1) & 7);
                subFrame = new FlacSubFrameFixed(reader, header, data, bps, order);
            }
            else if (x >= 64)
            {
                //lpc
                order = (int)(((x >> 1) & 31) + 1);
                subFrame = new FlacSubFrameLPC(reader, header, data, bps, order);
            }
            else
            {
                Debug.WriteLine("Invalid Flac-SubframeType: x = " + x + ".");
                return null;
            }

            if (haswastedBits)
            {
                int* ptrDest = data.destBuffer;
                for (int i = 0; i < header.BlockSize; i++)
                {
                    *(ptrDest++) <<= wastedBits;
                }
            }

            //System.Diagnostics.Debug.WriteLine(subFrame.GetType().Name);

            if (subFrame != null)
                subFrame.WastedBits = wastedBits;
            else
                Debug.WriteLine("Unknown error while reading FlacSubFrameHeader");

            return subFrame;
        }
Example #28
0
        protected unsafe virtual bool ParseHeader(ref byte *headerBuffer, FlacMetadataStreamInfo streamInfo)
        {
            const string loggerLocation = "FlacFrameHeader.ParseHeader(byte*, FlacMetadataStreamInfo)";
            int          x = -1;                                         //tmp value to store in

            if (headerBuffer[0] == 0xFF && headerBuffer[1] >> 1 == 0x7C) //sync bits
            {
                if ((headerBuffer[1] & 0x02) != 0)                       // ...10 2. letzes bits muss 0 sein
                {
                    Error("Invalid FlacFrame. Reservedbit_0 is 1", loggerLocation);
                    return(false);
                }

                byte *        __headerbufferPtr = headerBuffer;
                FlacBitReader reader            = new FlacBitReader(__headerbufferPtr, 0);

                #region blocksize

                //blocksize
                x = headerBuffer[2] >> 4;
                int blocksize = -1;

                if (x == 0)
                {
                    Error("Invalid Blocksize value: 0", loggerLocation);
                    return(false);
                }
                else if (x == 1)
                {
                    blocksize = 192;
                }
                else if (x >= 2 && x <= 5)
                {
                    blocksize = 576 << (x - 2);
                }
                else if (x == 6 || x == 7)
                {
                    blocksize_hint = x;
                }
                else if (x >= 8 && x <= 15)
                {
                    blocksize = 256 << (x - 8);
                }
                else
                {
                    Error("Invalid Blocksize value: " + x, loggerLocation);
                    return(false);
                }
                BlockSize = blocksize;

                #endregion blocksize

                #region samplerate

                //samplerate
                x = headerBuffer[2] & 0x0F;
                int sampleRate = -1;

                if (x == 0)
                {
                    if (streamInfo != null)
                    {
                        sampleRate = streamInfo.SampleRate;
                    }
                    else
                    {
                        Error("Missing Samplerate. Samplerate Index = 0 && streamInfoMetaData == null.", loggerLocation);
                        return(false);
                    }
                }
                else if (x >= 1 && x <= 11)
                {
                    sampleRate = FlacConstant.SampleRateTable[x];
                }
                else if (x >= 12 && x <= 14)
                {
                    sampleRate_hint = x;
                }
                else
                {
                    Error("Invalid SampleRate value: " + x, loggerLocation);
                    return(false);
                }
                SampleRate = sampleRate;

                #endregion samplerate

                #region channels

                x = headerBuffer[3] >> 4; //cc: unsigned
                int channels = -1;
                if ((x & 8) != 0)
                {
                    channels = 2;
                    if ((x & 7) > 2 || (x & 7) < 0)
                    {
                        Error("Invalid ChannelAssignment", loggerLocation);
                        return(false);
                    }
                    else
                    {
                        ChannelAssignment = (ChannelAssignment)((x & 7) + 1);
                    }
                }
                else
                {
                    channels          = x + 1;
                    ChannelAssignment = ChannelAssignment.Independent;
                }
                Channels = channels;

                #endregion channels

                #region bitspersample

                x = (headerBuffer[3] & 0x0E) >> 1;
                int bitsPerSample = -1;
                if (x == 0)
                {
                    if (streamInfo != null)
                    {
                        bitsPerSample = streamInfo.BitsPerSample;
                    }
                    else
                    {
                        Error("Missing BitsPerSample. Index = 0 && streamInfoMetaData == null.", loggerLocation);
                        return(false);
                    }
                }
                else if (x == 3 || x >= 7 || x < 0)
                {
                    Error("Invalid BitsPerSampleIndex", loggerLocation);
                    return(false);
                }
                else
                {
                    bitsPerSample = FlacConstant.BitPerSampleTable[x];
                }

                BitsPerSample = bitsPerSample;

                #endregion bitspersample

                if ((headerBuffer[3] & 0x01) != 0) // reserved bit -> 0
                {
                    Error("Invalid FlacFrame. Reservedbit_1 is 1", loggerLocation);
                    return(false);
                }

                //reader.SkipBits(4 * 8); //erste 3 bytes headerbytes überspringen, da diese schon ohne reader verarbeitet
                reader.ReadBits(32);

                //BYTE 4

                #region utf8

                //variable blocksize
                if ((headerBuffer[1] & 0x01) != 0 ||
                    (streamInfo != null && streamInfo.MinBlockSize != streamInfo.MaxBlockSize))
                {
                    ulong samplenumber;
                    if (reader.ReadUTF8_64(out samplenumber) && samplenumber != ulong.MaxValue)
                    {
                        NumberType   = FlacNumberType.SampleNumber;
                        SampleNumber = samplenumber;
                    }
                    else
                    {
                        Error("Invalid UTF8 Samplenumber coding.", loggerLocation);
                        return(false);
                    }
                }
                else //fixed blocksize
                {
                    uint framenumber;// = reader.ReadUTF8();

                    if (reader.ReadUTF8_32(out framenumber) && framenumber != uint.MaxValue)
                    {
                        NumberType  = FlacNumberType.FrameNumber;
                        FrameNumber = framenumber;
                    }
                    else
                    {
                        Error("Invalid UTF8 Framenumber coding.", loggerLocation);
                        return(false);
                    }
                }

                #endregion utf8

                #region read hints

                //blocksize am ende des frameheaders
                if (blocksize_hint != 0)
                {
                    x = (int)reader.ReadBits(8);
                    if (blocksize_hint == 7)
                    {
                        x = (x << 8) | (int)reader.ReadBits(8);
                    }
                    BlockSize = x + 1;
                }

                //samplerate am ende des frameheaders
                if (sampleRate_hint != 0)
                {
                    x = (int)reader.ReadBits(8);
                    if (sampleRate_hint != 12)
                    {
                        x = (x << 8) | (int)reader.ReadBits(8);
                    }
                    if (sampleRate_hint == 12)
                    {
                        SampleRate = x * 1000;
                    }
                    else if (sampleRate_hint == 13)
                    {
                        SampleRate = x;
                    }
                    else
                    {
                        SampleRate = x * 10;
                    }
                }

                #endregion read hints

                //if (Channels == 1 && BitsPerSample == 24 && SampleRate == 44100)
                //    System.Diagnostics.Debugger.Break();

                if (DoCRC)
                {
                    var crc8 = CSMath.CRC8.Instance.CalcCheckSum(reader.Buffer, 0, reader.Position);
                    CRC8 = (byte)reader.ReadBits(8);
                    if (CRC8 != crc8)
                    {
                        Error("CRC8 missmatch", loggerLocation);
                        return(false);
                    }
                }

                headerBuffer += reader.Position;
                return(true);
            }

            Error("Invalid Syncbits", loggerLocation);
            return(false);
        }
Example #29
0
        public unsafe FlacSubFrameLPC(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bps, int order)
            : base(header)
        {
            //warmup
            _warmup = new int[FlacConstant.MAX_LPC_ORDER];
            for (int i = 0; i < order; i++)
            {
                _warmup[i] = data.residualBuffer[i] = reader.ReadBitsSigned(bps);
            }

            //header
            int u32 = (int)reader.ReadBits(FlacConstant.SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN);

            if (u32 == (1 << FlacConstant.SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1)
            {
                Debug.WriteLine("Invalid FlacLPC qlp coeff precision.");
                return; //return false;
            }
            _qlpCoeffPrecision = u32 + 1;

            int level = reader.ReadBitsSigned(FlacConstant.SUBFRAME_LPC_QLP_SHIFT_LEN);

            if (level < 0)
            {
                throw new Exception("negative shift");
            }
            _lpcShiftNeeded = level;

            _qlpCoeffs = new int[FlacConstant.MAX_LPC_ORDER];

            //qlp coeffs
            for (int i = 0; i < order; i++)
            {
                _qlpCoeffs[i] = reader.ReadBitsSigned(_qlpCoeffPrecision);
            }

            //QLPCoeffs = coeffs;

            Residual = new FlacResidual(reader, header, data, order);

            for (int i = 0; i < order; i++)
            {
                data.destBuffer[i] = data.residualBuffer[i];
            }

            if (bps + _qlpCoeffPrecision + CSMath.ILog(order) <= 32)
            {
                if (bps <= 16 && _qlpCoeffPrecision <= 16)
                {
                    RestoreLPCSignal(data.residualBuffer + order, data.destBuffer + order, header.BlockSize - order, order); //Restore(data.residualBuffer + order, data.destBuffer, Header.BlockSize - order, order, order);
                }
                else
                {
                    RestoreLPCSignal(data.residualBuffer + order, data.destBuffer + order, header.BlockSize - order, order);
                }
            }
            else
            {
                RestoreLPCSignalWide(data.residualBuffer + order, data.destBuffer + order, header.BlockSize - order, order);//RestoreWide(data.residualBuffer + order, data.destBuffer, Header.BlockSize - order, order, order);
            }

            //Warmup = warmup;
        }
Example #30
0
        public unsafe static FlacSubFrameBase GetSubFrame(FlacBitReader reader, FlacSubFrameData data, FlacFrameHeader header, int bitsPerSample)
        {
            int wastedBits = 0, order;

            uint firstByte = reader.ReadBits(8);

            if ((firstByte & 0x80) != 0) //Zero bit padding, to prevent sync-fooling string of 1s
            {
                Debug.WriteLine("Flacdecoder subframe-header got no zero-bit padding.");
                return(null);
            }

            bool hasWastedBits = (firstByte & 1) != 0; //Wasted bits-per-sample' flag

            if (hasWastedBits)
            {
                int k = (int)reader.ReadUnary();
                wastedBits     = k + 1; //"k-1" follows -> add 1
                bitsPerSample -= wastedBits;
            }

            FlacSubFrameBase subFrame;
            var subframeType = (firstByte & 0x7E) >> 1; //0111 1110

            if (subframeType == 0)                      //000000
            {
                subFrame = new FlacSubFrameConstant(reader, header, data, bitsPerSample);
            }
            else if (subframeType == 1) //000001
            {
                subFrame = new FlacSubFrameVerbatim(reader, header, data, bitsPerSample);
            }
            else if ((subframeType & 0x08) != 0) //001000 = 0x08
            {
                order    = (int)(subframeType & 0x07);
                subFrame = new FlacSubFrameFixed(reader, header, data, bitsPerSample, order);
            }
            else if ((subframeType & 0x20) != 0) //100000 = 0x20
            {
                order    = (int)(subframeType & 0x1F) + 1;
                subFrame = new FlacSubFrameLPC(reader, header, data, bitsPerSample, order);
            }
            else
            {
                Debug.WriteLine(String.Format("Invalid Flac-SubframeType. SubframeType: 0x{0:x}.", subframeType));
                return(null);
            }

            if (hasWastedBits)
            {
                int *destination = data.DestinationBuffer;
                for (int i = 0; i < header.BlockSize; i++)
                {
                    *(destination++) <<= wastedBits;
                }
            }

#if FLAC_DEBUG
            subFrame.WastedBits = wastedBits;
#endif
            return(subFrame);
        }
Example #31
0
        private unsafe bool ParseHeader(ref byte *headerBuffer, FlacMetadataStreamInfo streamInfo)
        {
            const string loggerLocation = "FlacFrameHeader.ParseHeader(byte*, FlacMetadataStreamInfo)";
            int          val;

            if (headerBuffer[0] == 0xFF && headerBuffer[1] >> 1 == 0x7C) //sync bits
            {
                if ((headerBuffer[1] & 0x02) != 0)
                {
                    Error("Invalid FlacFrame. Reservedbit_0 is 1", loggerLocation);
                    return(false);
                }

                byte *        __headerbufferPtr = headerBuffer;
                FlacBitReader reader            = new FlacBitReader(__headerbufferPtr, 0);

                #region blocksize

                //blocksize
                val = headerBuffer[2] >> 4;
                int blocksize = -1;

                if (val == 0)
                {
                    Error("Invalid Blocksize value: 0", loggerLocation);
                    return(false);
                }
                if (val == 1)
                {
                    blocksize = 192;
                }
                else if (val >= 2 && val <= 5)
                {
                    blocksize = 576 << (val - 2);
                }
                else if (val == 6 || val == 7)
                {
                    _blocksizeHint = val;
                }
                else if (val >= 8 && val <= 15)
                {
                    blocksize = 256 << (val - 8);
                }
                else
                {
                    Error("Invalid Blocksize value: " + val, loggerLocation);
                    return(false);
                }
                BlockSize = blocksize;

                #endregion blocksize

                #region samplerate

                //samplerate
                val = headerBuffer[2] & 0x0F;
                int sampleRate = -1;

                if (val == 0)
                {
                    if (streamInfo != null)
                    {
                        sampleRate = streamInfo.SampleRate;
                    }
                    else
                    {
                        Error("Missing Samplerate. Samplerate Index = 0 && streamInfoMetaData == null.", loggerLocation);
                        return(false);
                    }
                }
                else if (val >= 1 && val <= 11)
                {
                    sampleRate = FlacConstant.SampleRateTable[val];
                }
                else if (val >= 12 && val <= 14)
                {
                    _sampleRateHint = val;
                }
                else
                {
                    Error("Invalid SampleRate value: " + val, loggerLocation);
                    return(false);
                }
                SampleRate = sampleRate;

                #endregion samplerate

                #region channels

                val = headerBuffer[3] >> 4; //cc: unsigned
                int channels;
                if ((val & 8) != 0)
                {
                    channels = 2;
                    if ((val & 7) > 2 || (val & 7) < 0)
                    {
                        Error("Invalid ChannelAssignment", loggerLocation);
                        return(false);
                    }
                    ChannelAssignment = (ChannelAssignment)((val & 7) + 1);
                }
                else
                {
                    channels          = val + 1;
                    ChannelAssignment = ChannelAssignment.Independent;
                }
                Channels = channels;

                #endregion channels

                #region bitspersample

                val = (headerBuffer[3] & 0x0E) >> 1;
                int bitsPerSample;
                if (val == 0)
                {
                    if (streamInfo != null)
                    {
                        bitsPerSample = streamInfo.BitsPerSample;
                    }
                    else
                    {
                        Error("Missing BitsPerSample. Index = 0 && streamInfoMetaData == null.", loggerLocation);
                        return(false);
                    }
                }
                else if (val == 3 || val >= 7 || val < 0)
                {
                    Error("Invalid BitsPerSampleIndex", loggerLocation);
                    return(false);
                }
                else
                {
                    bitsPerSample = FlacConstant.BitPerSampleTable[val];
                }

                BitsPerSample = bitsPerSample;

                #endregion bitspersample

                if ((headerBuffer[3] & 0x01) != 0) // reserved bit -> 0
                {
                    Error("Invalid FlacFrame. Reservedbit_1 is 1", loggerLocation);
                    return(false);
                }

                reader.ReadBits(32); //skip the first 4 bytes since they got already processed

                //BYTE 4

                #region utf8

                //variable blocksize
                if ((headerBuffer[1] & 0x01) != 0 ||
                    (streamInfo != null && streamInfo.MinBlockSize != streamInfo.MaxBlockSize))
                {
                    ulong samplenumber;
                    if (reader.ReadUTF8_64(out samplenumber) && samplenumber != ulong.MaxValue)
                    {
                        BlockingStrategy = BlockingStrategy.VariableBlockSize;
                        SampleNumber     = (long)samplenumber;
                    }
                    else
                    {
                        Error("Invalid UTF8 Samplenumber coding.", loggerLocation);
                        return(false);
                    }
                }
                else //fixed blocksize
                {
                    uint framenumber;

                    if (reader.ReadUTF8_32(out framenumber) && framenumber != uint.MaxValue)
                    {
                        BlockingStrategy = BlockingStrategy.FixedBlockSize;
                        FrameNumber      = (int)framenumber;
                    }
                    else
                    {
                        Error("Invalid UTF8 Framenumber coding.", loggerLocation);
                        return(false);
                    }
                }

                #endregion utf8

                #region read hints

                //blocksize am ende des frameheaders
                if (_blocksizeHint != 0)
                {
                    val = (int)reader.ReadBits(8);
                    if (_blocksizeHint == 7)
                    {
                        val = (val << 8) | (int)reader.ReadBits(8);
                    }
                    BlockSize = val + 1;
                }

                //samplerate
                if (_sampleRateHint != 0)
                {
                    val = (int)reader.ReadBits(8);
                    if (_sampleRateHint != 12)
                    {
                        val = (val << 8) | (int)reader.ReadBits(8);
                    }
                    if (_sampleRateHint == 12)
                    {
                        SampleRate = val * 1000;
                    }
                    else if (_sampleRateHint == 13)
                    {
                        SampleRate = val;
                    }
                    else
                    {
                        SampleRate = val * 10;
                    }
                }

                #endregion read hints

                if (DoCrc)
                {
                    var crc8 = Utils.CRC8.Instance.CalcCheckSum(reader.Buffer, 0, reader.Position);
                    Crc8 = (byte)reader.ReadBits(8);
                    if (Crc8 != crc8)
                    {
                        Error("CRC8 missmatch", loggerLocation);
                        return(false);
                    }
                }
                else
                {
                    Crc8 = (byte)reader.ReadBits(8);
                }

                headerBuffer += reader.Position;
                return(true);
            }

            Error("Invalid Syncbits", loggerLocation);
            return(false);
        }
Example #32
0
        private unsafe bool ParseHeader(ref byte* headerBuffer, FlacMetadataStreamInfo streamInfo)
        {
            const string loggerLocation = "FlacFrameHeader.ParseHeader(byte*, FlacMetadataStreamInfo)";
            int val;
            if (headerBuffer[0] == 0xFF && headerBuffer[1] >> 1 == 0x7C) //sync bits
            {
                if ((headerBuffer[1] & 0x02) != 0)
                {
                    Error("Invalid FlacFrame. Reservedbit_0 is 1", loggerLocation);
                    return false;
                }

                byte* __headerbufferPtr = headerBuffer;
                FlacBitReader reader = new FlacBitReader(__headerbufferPtr, 0);

                #region blocksize

                //blocksize
                val = headerBuffer[2] >> 4;
                int blocksize = -1;

                if (val == 0)
                {
                    Error("Invalid Blocksize value: 0", loggerLocation);
                    return false;
                }
                if (val == 1)
                    blocksize = 192;
                else if (val >= 2 && val <= 5)
                    blocksize = 576 << (val - 2);
                else if (val == 6 || val == 7)
                    _blocksizeHint = val;
                else if (val >= 8 && val <= 15)
                    blocksize = 256 << (val - 8);
                else
                {
                    Error("Invalid Blocksize value: " + val, loggerLocation);
                    return false;
                }
                BlockSize = blocksize;

                #endregion blocksize

                #region samplerate

                //samplerate
                val = headerBuffer[2] & 0x0F;
                int sampleRate = -1;

                if (val == 0)
                {
                    if (streamInfo != null)
                        sampleRate = streamInfo.SampleRate;
                    else
                    {
                        Error("Missing Samplerate. Samplerate Index = 0 && streamInfoMetaData == null.", loggerLocation);
                        return false;
                    }
                }
                else if (val >= 1 && val <= 11)
                    sampleRate = FlacConstant.SampleRateTable[val];
                else if (val >= 12 && val <= 14)
                    _sampleRateHint = val;
                else
                {
                    Error("Invalid SampleRate value: " + val, loggerLocation);
                    return false;
                }
                SampleRate = sampleRate;

                #endregion samplerate

                #region channels

                val = headerBuffer[3] >> 4; //cc: unsigned
                int channels;
                if ((val & 8) != 0)
                {
                    channels = 2;
                    if ((val & 7) > 2 || (val & 7) < 0)
                    {
                        Error("Invalid ChannelAssignment", loggerLocation);
                        return false;
                    }
                    ChannelAssignment = (ChannelAssignment)((val & 7) + 1);
                }
                else
                {
                    channels = val + 1;
                    ChannelAssignment = ChannelAssignment.Independent;
                }
                Channels = channels;

                #endregion channels

                #region bitspersample

                val = (headerBuffer[3] & 0x0E) >> 1;
                int bitsPerSample;
                if (val == 0)
                {
                    if (streamInfo != null)
                        bitsPerSample = streamInfo.BitsPerSample;
                    else
                    {
                        Error("Missing BitsPerSample. Index = 0 && streamInfoMetaData == null.", loggerLocation);
                        return false;
                    }
                }
                else if (val == 3 || val >= 7 || val < 0)
                {
                    Error("Invalid BitsPerSampleIndex", loggerLocation);
                    return false;
                }
                else
                    bitsPerSample = FlacConstant.BitPerSampleTable[val];

                BitsPerSample = bitsPerSample;

                #endregion bitspersample

                if ((headerBuffer[3] & 0x01) != 0) // reserved bit -> 0
                {
                    Error("Invalid FlacFrame. Reservedbit_1 is 1", loggerLocation);
                    return false;
                }

                reader.ReadBits(32); //skip the first 4 bytes since they got already processed

                //BYTE 4

                #region utf8

                //variable blocksize
                if ((headerBuffer[1] & 0x01) != 0 ||
                    (streamInfo != null && streamInfo.MinBlockSize != streamInfo.MaxBlockSize))
                {
                    ulong samplenumber;
                    if (reader.ReadUTF8_64(out samplenumber) && samplenumber != ulong.MaxValue)
                    {
                        BlockingStrategy = BlockingStrategy.VariableBlockSize;
                        SampleNumber = (long) samplenumber;
                    }
                    else
                    {
                        Error("Invalid UTF8 Samplenumber coding.", loggerLocation);
                        return false;
                    }
                }
                else //fixed blocksize
                {
                    uint framenumber;

                    if (reader.ReadUTF8_32(out framenumber) && framenumber != uint.MaxValue)
                    {
                        BlockingStrategy = BlockingStrategy.FixedBlockSize;
                        FrameNumber = (int) framenumber;
                    }
                    else
                    {
                        Error("Invalid UTF8 Framenumber coding.", loggerLocation);
                        return false;
                    }
                }

                #endregion utf8

                #region read hints

                //blocksize am ende des frameheaders
                if (_blocksizeHint != 0)
                {
                    val = (int)reader.ReadBits(8);
                    if (_blocksizeHint == 7)
                    {
                        val = (val << 8) | (int)reader.ReadBits(8);
                    }
                    BlockSize = val + 1;
                }

                //samplerate
                if (_sampleRateHint != 0)
                {
                    val = (int)reader.ReadBits(8);
                    if (_sampleRateHint != 12)
                    {
                        val = (val << 8) | (int)reader.ReadBits(8);
                    }
                    if (_sampleRateHint == 12)
                        SampleRate = val * 1000;
                    else if (_sampleRateHint == 13)
                        SampleRate = val;
                    else
                        SampleRate = val * 10;
                }

                #endregion read hints

                if (DoCrc)
                {
                    var crc8 = Utils.CRC8.Instance.CalcCheckSum(reader.Buffer, 0, reader.Position);
                    Crc8 = (byte) reader.ReadBits(8);
                    if (Crc8 != crc8)
                    {
                        Error("CRC8 missmatch", loggerLocation);
                        return false;
                    }
                }
                else
                {
                    Crc8 = (byte) reader.ReadBits(8);
                }

                headerBuffer += reader.Position;
                return true;
            }

            Error("Invalid Syncbits", loggerLocation);
            return false;
        }
Example #33
0
        private unsafe void ReadSubFrames()
        {
            List<FlacSubFrameBase> subFrames = new List<FlacSubFrameBase>();

            //alocateOutput
            var data = AllocOuputMemory();
            _subFrames = data;

            byte[] buffer = new byte[0x20000];
            if ((_streamInfo.MaxFrameSize * Header.Channels * Header.BitsPerSample * 2 >> 3) > buffer.Length)
            {
                buffer = new byte[(_streamInfo.MaxFrameSize * Header.Channels * Header.BitsPerSample * 2 >> 3) - FlacConstant.FrameHeaderSize];
            }

            int read = _stream.Read(buffer, 0, (int)Math.Min(buffer.Length, _stream.Length - _stream.Position));

            fixed (byte* ptrBuffer = buffer)
            {
                FlacBitReader reader = new FlacBitReader(ptrBuffer, 0);
                for (int c = 0; c < Header.Channels; c++)
                {
                    int bitsPerSample = Header.BitsPerSample;
                    if (Header.ChannelAssignment == ChannelAssignment.MidSide || Header.ChannelAssignment == ChannelAssignment.LeftSide)
                        bitsPerSample += c;
                    else if (Header.ChannelAssignment == ChannelAssignment.RightSide)
                        bitsPerSample += 1 - c;

                    var subframe = FlacSubFrameBase.GetSubFrame(reader, data[c], Header, bitsPerSample);
                    subFrames.Add(subframe);
                }

                reader.Flush();
                Crc16 = (short) reader.ReadBits(16);

                _stream.Position -= read - reader.Position;

                MapToChannels(_subFrames);
            }
        }
Example #34
0
        public static FlacSubFrameBase GetSubFrame(FlacBitReader reader, FlacSubFrameData data, FlacFrameHeader header,
                                                   int bitsPerSample)
        {
            unchecked
            {
                int wastedBits = 0, order;

                var firstByte = reader.ReadBits(8);

                if ((firstByte & 0x80) != 0) //Zero bit padding, to prevent sync-fooling string of 1s
                {
                    Debug.WriteLine("Flacdecoder subframe-header got no zero-bit padding.");
                    return(null);
                }

                var hasWastedBits = (firstByte & 1) != 0; //Wasted bits-per-sample' flag
                if (hasWastedBits)
                {
                    var k = (int)reader.ReadUnary();
                    wastedBits     = k + 1; //"k-1" follows -> add 1
                    bitsPerSample -= wastedBits;
                }

                FlacSubFrameBase subFrame;
                var subframeType = (firstByte & 0x7E) >> 1; //0111 1110

                if (subframeType == 0)                      //000000
                {
                    subFrame = new FlacSubFrameConstant(reader, header, data, bitsPerSample);
                }
                else if (subframeType == 1) //000001
                {
                    subFrame = new FlacSubFrameVerbatim(reader, header, data, bitsPerSample);
                }
                else if ((subframeType & 0x20) != 0) //100000 = 0x20
                {
                    order    = (int)(subframeType & 0x1F) + 1;
                    subFrame = new FlacSubFrameLPC(reader, header, data, bitsPerSample, order);
                }
                else if ((subframeType & 0x08) != 0) //001000 = 0x08
                {
                    order = (int)(subframeType & 0x07);
                    if (order > 4)
                    {
                        return(null);
                    }
                    subFrame = new FlacSubFrameFixed(reader, header, data, bitsPerSample, order);
                }
                else
                {
                    Debug.WriteLine($"Invalid Flac-SubframeType. SubframeType: 0x{subframeType:x}.");
                    return(null);
                }

                if (hasWastedBits)
                {
                    var destination = data.DestinationBuffer.Span;
                    for (var i = 0; i < header.BlockSize; i++)
                    {
                        destination[i] <<= wastedBits;
                    }
                }

                return(subFrame);
            }
        }
Example #35
0
        protected unsafe virtual bool ParseHeader(ref byte* headerBuffer, FlacMetadataStreamInfo streamInfo)
        {
            const string loggerLocation = "FlacFrameHeader.ParseHeader(byte*, FlacMetadataStreamInfo)";
            int x = -1; //tmp value to store in
            if (headerBuffer[0] == 0xFF && headerBuffer[1] >> 1 == 0x7C) //sync bits
            {
                if ((headerBuffer[1] & 0x02) != 0) // ...10 2. letzes bits muss 0 sein
                {
                    Error("Invalid FlacFrame. Reservedbit_0 is 1", loggerLocation);
                    return false;
                }

                byte* __headerbufferPtr = headerBuffer;
                FlacBitReader reader = new FlacBitReader(__headerbufferPtr, 0);

                #region blocksize

                //blocksize
                x = headerBuffer[2] >> 4;
                int blocksize = -1;

                if (x == 0)
                {
                    Error("Invalid Blocksize value: 0", loggerLocation);
                    return false;
                }
                else if (x == 1)
                    blocksize = 192;
                else if (x >= 2 && x <= 5)
                    blocksize = 576 << (x - 2);
                else if (x == 6 || x == 7)
                    blocksize_hint = x;
                else if (x >= 8 && x <= 15)
                    blocksize = 256 << (x - 8);
                else
                {
                    Error("Invalid Blocksize value: " + x, loggerLocation);
                    return false;
                }
                BlockSize = blocksize;

                #endregion blocksize

                #region samplerate

                //samplerate
                x = headerBuffer[2] & 0x0F;
                int sampleRate = -1;

                if (x == 0)
                {
                    if (streamInfo != null)
                        sampleRate = streamInfo.SampleRate;
                    else
                    {
                        Error("Missing Samplerate. Samplerate Index = 0 && streamInfoMetaData == null.", loggerLocation);
                        return false;
                    }
                }
                else if (x >= 1 && x <= 11)
                    sampleRate = FlacConstant.SampleRateTable[x];
                else if (x >= 12 && x <= 14)
                    sampleRate_hint = x;
                else
                {
                    Error("Invalid SampleRate value: " + x, loggerLocation);
                    return false;
                }
                SampleRate = sampleRate;

                #endregion samplerate

                #region channels

                x = headerBuffer[3] >> 4; //cc: unsigned
                int channels = -1;
                if ((x & 8) != 0)
                {
                    channels = 2;
                    if ((x & 7) > 2 || (x & 7) < 0)
                    {
                        Error("Invalid ChannelAssignment", loggerLocation);
                        return false;
                    }
                    else
                        ChannelAssignment = (ChannelAssignment)((x & 7) + 1);
                }
                else
                {
                    channels = x + 1;
                    ChannelAssignment = ChannelAssignment.Independent;
                }
                Channels = channels;

                #endregion channels

                #region bitspersample

                x = (headerBuffer[3] & 0x0E) >> 1;
                int bitsPerSample = -1;
                if (x == 0)
                {
                    if (streamInfo != null)
                        bitsPerSample = streamInfo.BitsPerSample;
                    else
                    {
                        Error("Missing BitsPerSample. Index = 0 && streamInfoMetaData == null.", loggerLocation);
                        return false;
                    }
                }
                else if (x == 3 || x >= 7 || x < 0)
                {
                    Error("Invalid BitsPerSampleIndex", loggerLocation);
                    return false;
                }
                else
                    bitsPerSample = FlacConstant.BitPerSampleTable[x];

                BitsPerSample = bitsPerSample;

                #endregion bitspersample

                if ((headerBuffer[3] & 0x01) != 0) // reserved bit -> 0
                {
                    Error("Invalid FlacFrame. Reservedbit_1 is 1", loggerLocation);
                    return false;
                }

                //reader.SkipBits(4 * 8); //erste 3 bytes headerbytes überspringen, da diese schon ohne reader verarbeitet
                reader.ReadBits(32);

                //BYTE 4

                #region utf8

                //variable blocksize
                if ((headerBuffer[1] & 0x01) != 0 ||
                    (streamInfo != null && streamInfo.MinBlockSize != streamInfo.MaxBlockSize))
                {
                    ulong samplenumber;
                    if (reader.ReadUTF8_64(out samplenumber) && samplenumber != ulong.MaxValue)
                    {
                        NumberType = FlacNumberType.SampleNumber;
                        SampleNumber = samplenumber;
                    }
                    else
                    {
                        Error("Invalid UTF8 Samplenumber coding.", loggerLocation);
                        return false;
                    }
                }
                else //fixed blocksize
                {
                    uint framenumber;// = reader.ReadUTF8();

                    if (reader.ReadUTF8_32(out framenumber) && framenumber != uint.MaxValue)
                    {
                        NumberType = FlacNumberType.FrameNumber;
                        FrameNumber = framenumber;
                    }
                    else
                    {
                        Error("Invalid UTF8 Framenumber coding.", loggerLocation);
                        return false;
                    }
                }

                #endregion utf8

                #region read hints

                //blocksize am ende des frameheaders
                if (blocksize_hint != 0)
                {
                    x = (int)reader.ReadBits(8);
                    if (blocksize_hint == 7)
                    {
                        x = (x << 8) | (int)reader.ReadBits(8);
                    }
                    BlockSize = x + 1;
                }

                //samplerate am ende des frameheaders
                if (sampleRate_hint != 0)
                {
                    x = (int)reader.ReadBits(8);
                    if (sampleRate_hint != 12)
                    {
                        x = (x << 8) | (int)reader.ReadBits(8);
                    }
                    if (sampleRate_hint == 12)
                        SampleRate = x * 1000;
                    else if (sampleRate_hint == 13)
                        SampleRate = x;
                    else
                        SampleRate = x * 10;
                }

                #endregion read hints

                //if (Channels == 1 && BitsPerSample == 24 && SampleRate == 44100)
                //    System.Diagnostics.Debugger.Break();

                if (DoCRC)
                {
                    var crc8 = CSMath.CRC8.Instance.CalcCheckSum(reader.Buffer, 0, reader.Position);
                    CRC8 = (byte)reader.ReadBits(8);
                    if (CRC8 != crc8)
                    {
                        Error("CRC8 missmatch", loggerLocation);
                        return false;
                    }
                }

                headerBuffer += reader.Position;
                return true;
            }

            Error("Invalid Syncbits", loggerLocation);
            return false;
        }