Пример #1
0
        public int ScalarLookup(BitReader r)
        {
            HuffNode cur = RootNode;

            while (cur.Internal)
            {
                if (r.ReadBit())
                    cur = cur.One;
                else
                    cur = cur.Zero;

                if (cur == null)
                    throw new VorbisReadException("Bad huffman code encountered");
            }

            return cur.Code;
        }
Пример #2
0
        public float[][] Decode(BitReader r, int numVectors, int vectorLength, bool[] doNotDecodeFlags)
        {
            if (Type == 0 || Type == 1)
            {
                return Decode01(Type, r, numVectors, vectorLength, doNotDecodeFlags);
            }
            else if (Type == 2)
            {
                float[][] result = new float[numVectors][];
                for (int i = 0; i < numVectors; ++i)
                    result[i] = new float[vectorLength];

                if (doNotDecodeFlags.All((x) => (x == true)))
                {
                    // done early
                    return result;
                }
                else
                {
                    float[][] tmp = Decode01(1, r, 1, vectorLength*numVectors, doNotDecodeFlags);
                    //float[] tmp0 = tmp[0];
                    //int m = 0;
                    for (int i = 0; i < vectorLength; ++i)
                    {
                        for (int j = 0; j < numVectors; ++j)
                        {
                            result[j][i] = tmp[0][i * numVectors + j];
                        }
                    }

                    return result;
                }
            }
            else
                throw new VorbisReadException("bad residue type from setup");
        }
Пример #3
0
        private float[][] Decode01(int type, BitReader r, int numVectors, int vectorLength, bool[] doNotDecodeFlags)
        {
            int limitResidueBegin = Math.Min(Begin, vectorLength);
            int limitResidueEnd = Math.Min(End, vectorLength);

            int classWordsPerCodeWord = ClassBook.Dimensions;
            int nToRead = limitResidueEnd - limitResidueBegin;
            int partitionsToRead = nToRead / PartitionSize;

            float[][] result = new float[numVectors][];

            for (int i = 0; i < numVectors; ++i)
                result[i] = new float[vectorLength];

            if (nToRead == 0)
                return result;

            int[,] classifications = new int[numVectors, classWordsPerCodeWord + partitionsToRead];

            for (int pass = 0; pass < 8; ++pass)
            {
                int partitionCount = 0;

                while (partitionCount < partitionsToRead)
                {
                    if (pass == 0)
                    {
                        for (int j = 0; j < numVectors; ++j)
                        {
                            if (!doNotDecodeFlags[j])
                            {
                                int temp = ClassBook.ScalarLookup(r);
                                for (int i = classWordsPerCodeWord - 1; i >= 0; --i)
                                {
                                    // TODO: Isn't this indexing f*****g weird?
                                    classifications[j,i+partitionCount] = temp % ClassificationCount;

                                    temp = temp / ClassificationCount;
                                }
                            }
                        }
                    }

                    for (int i = 0; i < classWordsPerCodeWord && partitionCount < partitionsToRead; ++i )
                    {
                        for (int j = 0; j < numVectors; ++j)
                        {
                            int vqclass = classifications[j, partitionCount];
                            Codebook vqbook = Books[vqclass, pass];
                            if (vqbook != null)
                            {
                                int offset = limitResidueBegin + partitionCount * PartitionSize;

                                if (type == 0)
                                {
                                    //DecodeFormat0(r, vqbook, offset, result[j]);
                                    throw new NotImplementedException();
                                }
                                else if (type == 1)
                                {
                                    DecodeFormat1(r, vqbook, offset, result[j]);
                                }
                            }
                        }

                        ++partitionCount;
                    }
                }
            }

            return result;
        }
Пример #4
0
 private void DecodeFormat1(BitReader r, Codebook vqbook, int offset, float[] v)
 {
     int n = PartitionSize;
     int i=0;
     do
     {
         float[] entryTemp = vqbook.VectorLookup(r);
         for (int j = 0; j < vqbook.Dimensions; ++j)
         {
             v[offset + i] += entryTemp[j];
             ++i;
         }
     } while(i <n);
 }
Пример #5
0
 public override bool Decode(BitReader r, int samples, float[] data)
 {
     throw new NotImplementedException();
 }
Пример #6
0
 public abstract bool Decode(BitReader r, int samples, float[] data);
Пример #7
0
        public override bool Decode(BitReader r, int samples, float[] data)
        {
            if (!r.ReadBit())
            {
                //Console.WriteLine("    (zero)");
                //data = null;
                return false;
            }

            int[] ylist = ylistStorage;

            int range;

            if (Multiplier == 1)
                range = 256;
            else if (Multiplier == 2)
                range = 128;
            else if (Multiplier == 3)
                range = 84;
            else if (Multiplier == 4)
                range = 64;
            else
                // this is really a consistency check
                throw new VorbisReadException("Bad multiplier");

            ylist[0] = (int)r.ReadUnsigned(VorbisUtil.InverseLog(range - 1));
            ylist[1] = (int)r.ReadUnsigned(VorbisUtil.InverseLog(range - 1));
            int offset = 2;

            foreach (Floor1Class cls in ClassesByPartition)
            {
                int cdim = cls.Dimensions;
                int cbits = cls.SubclassBits;
                int csub = (1 << cbits) - 1;
                int cval = 0;

                if (cbits > 0)
                {
                    cval = cls.MasterCodebook.ScalarLookup(r);
                }

                for (int j = 0; j < cdim; ++j)
                {
                    Codebook book = cls.SubclassBooks[cval & csub];
                    cval = cval >> cbits;
                    if (book != null)
                    {
                        ylist[offset + j] = book.ScalarLookup(r);
                    }
                    else
                    {
                        ylist[offset + j] = 0;
                    }
                }

                offset += cdim;
            }

            /*Console.Write("    X vals: ");
            for (int i = 0; i < XList.Length; ++i)
                Console.Write("{0},", XList[i]);
            Console.WriteLine();
            Console.Write("    Y vals: ");
            for (int i = 0; i < XList.Length; ++i)
                Console.Write("{0},", ylist[i]);
            Console.WriteLine();*/

            /*Console.Write("    >>> ");
            for(int i=0; i<XList.Length; ++i)
                Console.Write("{0},{1},", XList[i], ylist[i]);
            Console.WriteLine();*/

            // "amplitude value synthesis" --
            // "Unwrap the always-positive-or-zero values read from the packet into +/- difference values, then apply to line prediction."

            bool[] step2Flag = step2FlagStorage;// new bool[XList.Length];
            int[] finalY = ylist;//new int[XList.Length];
            step2Flag[0] = true;
            step2Flag[1] = true;
            //finalY[0] = ylist[0];
            //finalY[1] = ylist[1];

            for (int i = 2; i<ylist.Length; ++i)
            {
                int lowNeighborOffset = LowNeighborLookup[i];// lowNeighbor(XList, i);
                int highNeighborOffset = HighNeighborLookup[i];// highNeighbor(XList, i);
                //Console.WriteLine("lo={0},hi={1}", lowNeighborOffset, highNeighborOffset);
                int predicted = renderPoint(XList[lowNeighborOffset], finalY[lowNeighborOffset],
                                            XList[highNeighborOffset], finalY[highNeighborOffset],
                                            XList[i]);

                int val = ylist[i];
                int highroom = range - predicted;
                int lowroom = predicted;

                int room = (highroom < lowroom) ? (highroom * 2) : (lowroom * 2);

                /*Console.WriteLine("lo={0}, hi={1}, loroom={2}, hiroom={3}, room={4}, val={5}, predicted={6}",
                    lowNeighborOffset, highNeighborOffset,
                    lowroom, highroom, room, val, predicted);

                Console.WriteLine("finalY[{0}]={1}, finalY[{2}]={3}",
                   lowNeighborOffset, finalY[lowNeighborOffset], highNeighborOffset, finalY[highNeighborOffset]);
                */

                if (val != 0)
                {
                    step2Flag[lowNeighborOffset] = true;
                    step2Flag[highNeighborOffset] = true;
                    step2Flag[i] = true;

                    if (val >= room)
                    {
                        if (highroom > lowroom)
                        {
                            finalY[i] = val - lowroom + predicted;
                        }
                        else // highroom <= lowroom
                        {
                            finalY[i] = predicted - val + highroom - 1;
                        }
                    }
                    else // val < room
                    {
                        // val is odd
                        if ((val % 2) != 0)
                        {
                            finalY[i] = predicted - ((val + 1) / 2);
                        }
                        // val is even
                        else
                        {
                            finalY[i] = predicted + (val / 2);
                        }
                    }
                }
                else
                {
                    step2Flag[i] = false;
                    finalY[i] = predicted;
                }

                //Console.WriteLine("Wrote finalY[{0}] = {1}", i, finalY[i]);
            }

            /*
            Console.Write("    reconstituted y vals: ");
            for (int i = 0; i < XList.Length; ++i)
                Console.Write("{0},", finalY[i]);
            Console.WriteLine();

            Console.Write("    Flags: ");
            for (int i = 0; i < XList.Length; ++i)
                Console.Write("{0},", step2Flag[i]?1:0);
            Console.WriteLine();
            */

            /*Console.Write("    >>> ");
            for(int i=0; i<XList.Length; ++i)
                if(step2Flag[i])
                    Console.Write("{0},{1},", XList[i], finalY[i]);
            Console.WriteLine();*/

            /*int[] indices = new int[XList.Length];
            for (int i = 0; i < indices.Length; ++i)
                indices[i] = i;*/

            /*int[] xlistSorted = new int[XList.Length];
            int[] finalYSorted = new int[XList.Length];
            bool[] step2FlagSorted = new bool[XList.Length];

            int n = 0;
            foreach(int i in SortTable)//indices.OrderBy((i) => XList[i]))
            {
                xlistSorted[n] = XList[i];
                finalYSorted[n] = finalY[i];
                step2FlagSorted[n] = step2Flag[i];
                ++n;
            }*/

               /* Console.Write("    $$$ ");
            for(int i=0; i<XList.Length; ++i)
                if(step2FlagSorted[i])
                    Console.Write("{0},{1},", xlistSorted[i], finalYSorted[i]);
            Console.WriteLine();*/

            //int maxX = XList.Max();

            int hx = 0;
            int hy = 0;
            int lx = 0;
            int ly = finalY[SortTable[0]] * Multiplier;
            for (int i = 1; i < XList.Length; ++i)
            {
                int j = SortTable[i];

                if (step2Flag[j])
                {
                    hy = finalY[j] * Multiplier;
                    hx = XList[j];
                    renderLine(samples, lx, ly, hx, hy, data);
                    lx = hx;
                    ly = hy;
                }
            }

            // TODO: Not 100% certain what we ought to do here.
            // Check spec/libvorbis.
            if (hx < samples)
            {
                renderLine(samples, hx, hy, samples, hy, data);
            }

            /*Console.Write("    ### ");
            for (int i = 0; i < floor.Length; ++i)
                Console.Write("{0},", floor[i]);
            Console.WriteLine();*/

            /*float[] clippedFloor = new float[samples];
            for (int i = 0; i <= maxX && i < samples; ++i)
                clippedFloor[i] = inverseDecibelTable[floor[i]];*/

            /*Console.Write("FLOOR INVERSE: ");
            for (int i = 0; i < samples; ++i)
                Console.Write("{0}{1}", (i != 0) ? "," : "", data[i]);
            Console.WriteLine();*/

            return true;
        }
Пример #8
0
 public float[] VectorLookup(BitReader r)
 {
     return Lookup[ScalarLookup(r)];
 }