Пример #1
0
        private IEnumerator <int> ReadResidualData(FlacBitStreamReader bitReader, int blockSize, int predictorOrder)
        {
            const byte RiceCodingWith4BitParameter = 0;
            const byte RiceCodingWith5BitParameter = 1;

            uint residualRiceParamSizeType = bitReader.ReadBits(2);

            int residualRiceParamSize;

            if (residualRiceParamSizeType == RiceCodingWith4BitParameter)
            {
                residualRiceParamSize = 4;
            }
            else if (residualRiceParamSizeType == RiceCodingWith5BitParameter)
            {
                residualRiceParamSize = 5;
            }
            else
            {
                throw new FlacException("Reserved residual coding method");
            }

            // rice and rice2 almost the same
            // read rice partitined method
            int partitionOrder = (int)bitReader.ReadBits(4);
            int partitionCount = 1 << partitionOrder;
            int sampleCount    = blockSize >> partitionOrder;

            if (sampleCount < predictorOrder || sampleCount < 1 ||
                (sampleCount << partitionOrder) != blockSize)
            {
                throw new FlacException("Invalid partition order");
            }

            for (int i = 0; i < partitionCount; i++)
            {
                int skipSamples = i == 0 ? predictorOrder : 0;

                int riceParameter = (int)bitReader.ReadBits(residualRiceParamSize);
                if (riceParameter + 1 == 1 << residualRiceParamSize)
                {
                    // escape mode
                    int bitsPerSample = (int)bitReader.ReadBits(5);

                    for (int j = skipSamples; j < sampleCount; j++)
                    {
                        yield return(bitReader.ReadSignedBits(bitsPerSample));
                    }
                }
                else
                {
                    int maxRiceK = int.MaxValue >> riceParameter;
                    for (int j = skipSamples; j < sampleCount; j++)
                    {
                        yield return(bitReader.ReadRice(riceParameter));
                    }
                }
            }
        }
Пример #2
0
        private IEnumerator<int> ReadResidualData(FlacBitStreamReader bitReader, int blockSize, int predictorOrder)
        {
            const byte RiceCodingWith4BitParameter = 0;
            const byte RiceCodingWith5BitParameter = 1;

            uint residualRiceParamSizeType = bitReader.ReadBits(2);

            int residualRiceParamSize;
            if (residualRiceParamSizeType == RiceCodingWith4BitParameter)
                residualRiceParamSize = 4;
            else if (residualRiceParamSizeType == RiceCodingWith5BitParameter)
                residualRiceParamSize = 5;
            else
                throw new FlacException("Reserved residual coding method");

            // rice and rice2 almost the same
            // read rice partitined method
            int partitionOrder = (int)bitReader.ReadBits(4);
            int partitionCount = 1 << partitionOrder;
            int sampleCount = blockSize >> partitionOrder;

            if (sampleCount < predictorOrder || sampleCount < 1 ||
                (sampleCount << partitionOrder) != blockSize )
                throw new FlacException("Invalid partition order");

            for (int i = 0; i < partitionCount; i++)
            {
                int skipSamples = i == 0 ? predictorOrder : 0;

                int riceParameter = (int)bitReader.ReadBits(residualRiceParamSize);
                if (riceParameter + 1 == 1 << residualRiceParamSize)
                {
                    // escape mode
                    int bitsPerSample = (int)bitReader.ReadBits(5);

                    for (int j = skipSamples; j < sampleCount; j++)
                    {
                        yield return bitReader.ReadSignedBits(bitsPerSample);
                    }
                }
                else
                {
                    int maxRiceK = int.MaxValue >> riceParameter;
                    for (int j = skipSamples; j < sampleCount; j++)
                    {
                        yield return bitReader.ReadRice(riceParameter);
                    }
                }
            }
        }
Пример #3
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;
        }