Ejemplo n.º 1
0
        private IEnumerable <int> GetPredictorSamples(int blockSize, int[] warmupSamples, IPredictor predictor, IEnumerator <int> residualData)
        {
            int lastSample = 0;

            if (warmupSamples.Length > 0)
            {
                for (int i = 0; i < warmupSamples.Length; i++)
                {
                    yield return(warmupSamples[i]);
                }
                lastSample = warmupSamples[warmupSamples.Length - 1];
            }

            for (int i = warmupSamples.Length; i < blockSize; i++)
            {
                if (!residualData.MoveNext())
                {
                    throw new FlacException("Not enough residual data");
                }
                int x          = predictor.Next(lastSample);
                int e          = residualData.Current;
                int nextSample = x + e;
                yield return(nextSample);

                lastSample = nextSample;
            }

            if (residualData.MoveNext())
            {
                throw new FlacException("Not all residual data is decoded");
            }
        }
Ejemplo n.º 2
0
 private IEnumerator<int> GetResidual(int[] samples, int predictorOrder, IPredictor predictor)
 {
     int lastSample = predictorOrder > 0 ? samples[predictorOrder - 1] : 0;
     for (int i = predictorOrder; i < samples.Length; i++)
     {
         int nextSample = samples[i];
         yield return nextSample - predictor.Next(lastSample);
         lastSample = nextSample;
     }
 }
Ejemplo n.º 3
0
        private IEnumerator <int> GetResidual(int[] samples, int predictorOrder, IPredictor predictor)
        {
            int lastSample = predictorOrder > 0 ? samples[predictorOrder - 1] : 0;

            for (int i = predictorOrder; i < samples.Length; i++)
            {
                int nextSample = samples[i];
                yield return(nextSample - predictor.Next(lastSample));

                lastSample = nextSample;
            }
        }
Ejemplo n.º 4
0
        private IEnumerable<int> GetPredictorSamples(int blockSize, int[] warmupSamples, IPredictor predictor, IEnumerator<int> residualData)
        {
            int lastSample = 0;
            if (warmupSamples.Length > 0)
            {
                for (int i = 0; i < warmupSamples.Length; i++)
                {
                    yield return warmupSamples[i];
                }
                lastSample = warmupSamples[warmupSamples.Length - 1];
            }

            for (int i = warmupSamples.Length; i < blockSize; i++)
            {
                if (!residualData.MoveNext())
                    throw new FlacException("Not enough residual data");
                int x = predictor.Next(lastSample);
                int e = residualData.Current;
                int nextSample = x + e;
                yield return nextSample;

                lastSample = nextSample;
            }

            if (residualData.MoveNext())
                throw new FlacException("Not all residual data is decoded");
        }
Ejemplo n.º 5
0
 public int Next(int x)
 {
     return(basePredictor.Next(x) << shift);
 }
Ejemplo n.º 6
0
        private FlacResidualCoefficeints FindBestResidual(int[] channelSamples, int order, IPredictor predictor, FlacEncodingPolicy policy)
        {
            int[] residual;
            if (order > 0)
            {
                residual = new int[channelSamples.Length];
                int lastSample = channelSamples[order - 1];
                for (int i = order; i < residual.Length; i++)
                {
                    int nextSample = channelSamples[i];
                    residual[i] = nextSample - predictor.Next(lastSample);
                    lastSample  = nextSample;
                }
            }
            else
            {
                residual = channelSamples;
            }

            int minRiceOrder = policy.RicePartionOrder.MinValue;
            int maxRiceOrder = policy.RicePartionOrder.MaxValue;
            List <FlacResidualCoefficeints> rices = new List <FlacResidualCoefficeints>();
            int samplesPerPartition = channelSamples.Length >> minRiceOrder;

            if (samplesPerPartition << minRiceOrder != channelSamples.Length)
            {
                minRiceOrder = maxRiceOrder = 0; // reset minRiceOrder to zero;
            }

            for (int riceOrder = minRiceOrder; riceOrder <= maxRiceOrder; riceOrder++)
            {
                if (samplesPerPartition <= order)
                {
                    break;
                }

                int partitionCount = 1 << riceOrder;

                int[] parameters             = new int[partitionCount];
                int   totalPartitionDataSize = 0;
                int   j = order;
                for (int i = 0; i < partitionCount; i++)
                {
                    int skipAmount = i == 0 ? order : 0;
                    int estimatedPartitionSize;
                    int riceParameter;
                    FindBestResidual(residual, samplesPerPartition * i + skipAmount, samplesPerPartition - skipAmount,
                                     out estimatedPartitionSize, out riceParameter);
                    totalPartitionDataSize += estimatedPartitionSize;
                    parameters[i]           = riceParameter;
                }

                const int NormalPrecision               = 4;
                const int ExtendedPrecision             = 5;
                const int MinValueForExtendedParameters = 15;

                bool isExtended = false;
                for (int i = 0; i < parameters.Length && !isExtended; ++i)
                {
                    isExtended = parameters[i] >= MinValueForExtendedParameters;
                }

                int totalSize = 4 + totalPartitionDataSize +
                                partitionCount * (isExtended ? ExtendedPrecision : NormalPrecision);

                FlacResidualCoefficeints rice = new FlacResidualCoefficeints();
                rice.EstimatedSize  = totalSize;
                rice.IsExtended     = isExtended;
                rice.RiceParameters = parameters;
                rice.Order          = riceOrder;

                rices.Add(rice);

                if ((samplesPerPartition & 1) != 0)
                {
                    break;
                }
                samplesPerPartition >>= 1;
            }

            int bestRicePartition = 0;

            for (int i = 1; i < rices.Count; i++)
            {
                if (rices[bestRicePartition].EstimatedSize > rices[i].EstimatedSize)
                {
                    bestRicePartition = i;
                }
            }
            return(rices[bestRicePartition]);
        }
Ejemplo n.º 7
0
        private FlacResidualCoefficeints FindBestResidual(int[] channelSamples, int order, IPredictor predictor, FlacEncodingPolicy policy)
        {
            int[] residual;
            if (order > 0)
            {
                residual = new int[channelSamples.Length];
                int lastSample = channelSamples[order - 1];
                for (int i = order; i < residual.Length; i++)
                {
                    int nextSample = channelSamples[i];
                    residual[i] = nextSample - predictor.Next(lastSample);
                    lastSample = nextSample;
                }
            }
            else
                residual = channelSamples;

            int minRiceOrder = policy.RicePartionOrder.MinValue;
            int maxRiceOrder = policy.RicePartionOrder.MaxValue;
            List<FlacResidualCoefficeints> rices = new List<FlacResidualCoefficeints>();
            int samplesPerPartition = channelSamples.Length >> minRiceOrder;

            if (samplesPerPartition << minRiceOrder != channelSamples.Length)
            {
                minRiceOrder = maxRiceOrder = 0; // reset minRiceOrder to zero;
            }

            for (int riceOrder = minRiceOrder; riceOrder <= maxRiceOrder; riceOrder++)
            {
                if (samplesPerPartition <= order) break;

                int partitionCount = 1 << riceOrder;

                int[] parameters = new int[partitionCount];
                int totalPartitionDataSize = 0;
                int j = order;
                for (int i = 0; i < partitionCount; i++)
                {
                    int skipAmount = i == 0 ? order : 0;
                    int estimatedPartitionSize;
                    int riceParameter;
                    FindBestResidual(residual, samplesPerPartition * i + skipAmount, samplesPerPartition - skipAmount,
                        out estimatedPartitionSize, out riceParameter);
                    totalPartitionDataSize += estimatedPartitionSize;
                    parameters[i] = riceParameter;
                }

                const int NormalPrecision = 4;
                const int ExtendedPrecision = 5;
                const int MinValueForExtendedParameters = 15;

                bool isExtended = Array.Exists(parameters, delegate(int x) {
                    return x >= MinValueForExtendedParameters;
                });

                int totalSize = 4 + totalPartitionDataSize +
                    partitionCount * (isExtended ? ExtendedPrecision : NormalPrecision);

                FlacResidualCoefficeints rice = new FlacResidualCoefficeints();
                rice.EstimatedSize = totalSize;
                rice.IsExtended = isExtended;
                rice.RiceParameters = parameters;
                rice.Order = riceOrder;

                rices.Add(rice);

                if ((samplesPerPartition & 1) != 0) break;
                samplesPerPartition >>= 1;
            }

            int bestRicePartition = 0;
            for (int i = 1; i < rices.Count; i++)
            {
                if (rices[bestRicePartition].EstimatedSize > rices[i].EstimatedSize)
                    bestRicePartition = i;
            }
            return rices[bestRicePartition];
        }