Beispiel #1
0
        private void decodeSpectralData(BitStream inStream)
        {
            Array.Clear(data, 0, data.Length);
            int maxSFB       = info.getMaxSFB();
            int windowGroups = info.getWindowGroupCount();

            int[] offsets = info.getSWBOffsets();
            int[] buf     = new int[4];

            int sfb, j, k, w, hcb, off, width, num;
            int groupOff = 0, idx = 0;

            for (int g = 0; g < windowGroups; g++)
            {
                int groupLen = info.getWindowGroupLength(g);

                for (sfb = 0; sfb < maxSFB; sfb++, idx++)
                {
                    hcb   = sfbCB[idx];
                    off   = groupOff + offsets[sfb];
                    width = offsets[sfb + 1] - offsets[sfb];
                    if (hcb == ZERO_HCB || hcb == INTENSITY_HCB || hcb == INTENSITY_HCB2)
                    {
                        for (w = 0; w < groupLen; w++, off += 128)
                        {
                            Array.Clear(data, off, width);
                        }
                    }
                    else if (hcb == NOISE_HCB)
                    {
                        //apply PNS: fill with random values
                        for (w = 0; w < groupLen; w++, off += 128)
                        {
                            float energy = 0;

                            for (k = 0; k < width; k++)
                            {
                                randomState  *= 1664525 + 1013904223;
                                data[off + k] = randomState;
                                energy       += data[off + k] * data[off + k];
                            }

                            float scale = (float)(scaleFactors[idx] / Math.Sqrt(energy));
                            for (k = 0; k < width; k++)
                            {
                                data[off + k] *= scale;
                            }
                        }
                    }
                    else
                    {
                        for (w = 0; w < groupLen; w++, off += 128)
                        {
                            num = (hcb >= FIRST_PAIR_HCB) ? 2 : 4;
                            for (k = 0; k < width; k += num)
                            {
                                Huffman.decodeSpectralData(inStream, hcb, buf, 0);

                                //inverse quantization & scaling
                                for (j = 0; j < num; j++)
                                {
                                    data[off + k + j]  = (buf[j] > 0) ? IQ_TABLE[buf[j]] : -IQ_TABLE[-buf[j]];
                                    data[off + k + j] *= scaleFactors[idx];
                                }
                            }
                        }
                    }
                }
                groupOff += groupLen << 7;
            }
        }
Beispiel #2
0
        void decode(BitStream inStream, DecoderConfig conf)
        {
            couplingPoint = 2 * inStream.readBit();
            coupledCount  = inStream.readBits(3);
            int gainCount = 0;

            for (int i = 0; i <= coupledCount; i++)
            {
                gainCount++;
                channelPair[i] = inStream.readBool();
                idSelect[i]    = inStream.readBits(4);
                if (channelPair[i])
                {
                    chSelect[i] = inStream.readBits(2);
                    if (chSelect[i] == 3)
                    {
                        gainCount++;
                    }
                }
                else
                {
                    chSelect[i] = 2;
                }
            }
            couplingPoint += inStream.readBit();
            couplingPoint |= (couplingPoint >> 1);

            bool   sign  = inStream.readBool();
            double scale = CCE_SCALE[inStream.readBits(2)];

            ics.decode(inStream, false, conf);
            ICSInfo info             = ics.getInfo();
            int     windowGroupCount = info.getWindowGroupCount();
            int     maxSFB           = info.getMaxSFB();

            //TODO:
            int[,] sfbCB = null;//ics.getSectionData().getSfbCB();

            for (int i = 0; i < gainCount; i++)
            {
                int   idx       = 0;
                int   cge       = 1;
                int   xg        = 0;
                float gainCache = 1.0f;
                if (i > 0)
                {
                    cge       = couplingPoint == 2 ? 1 : inStream.readBit();
                    xg        = cge == 0 ? 0 : Huffman.decodeScaleFactor(inStream) - 60;
                    gainCache = (float)Math.Pow(scale, -xg);
                }
                if (couplingPoint == 2)
                {
                    gain[i, 0] = gainCache;
                }
                else
                {
                    for (int g = 0; g < windowGroupCount; g++)
                    {
                        for (int sfb = 0; sfb < maxSFB; sfb++, idx++)
                        {
                            if (sfbCB[g, sfb] != ZERO_HCB)
                            {
                                if (cge == 0)
                                {
                                    int t = Huffman.decodeScaleFactor(inStream) - 60;
                                    if (t != 0)
                                    {
                                        int s = 1;
                                        t = xg += t;
                                        if (!sign)
                                        {
                                            s  -= 2 * (t & 0x1);
                                            t >>= 1;
                                        }
                                        gainCache = (float)(Math.Pow(scale, -t) * s);
                                    }
                                }
                                gain[i, idx] = gainCache;
                            }
                        }
                    }
                }
            }
        }
Beispiel #3
0
        //  private void decodePulseData(BitStream in) throws AACException {
        //    pulseCount = in.readBits(2)+1;
        //    pulseStartSWB = in.readBits(6);
        //    if(pulseStartSWB>=info.getSWBCount()) throw new AACException("pulse SWB out of range: "+pulseStartSWB+" > "+info.getSWBCount());

        //    if(pulseOffset==null||pulseCount!=pulseOffset.Length) {
        //      //only reallocate if needed
        //      pulseOffset = new int[pulseCount];
        //      pulseAmp = new int[pulseCount];
        //    }

        //    pulseOffset[0] = info.getSWBOffsets()[pulseStartSWB];
        //    pulseOffset[0] += in.readBits(5);
        //    pulseAmp[0] = in.readBits(4);
        //    for(int i = 1; i<pulseCount; i++) {
        //      pulseOffset[i] = in.readBits(5)+pulseOffset[i-1];
        //      if(pulseOffset[i]>1023) throw new AACException("pulse offset out of range: "+pulseOffset[0]);
        //      pulseAmp[i] = in.readBits(4);
        //    }
        //  }

        public void decodeScaleFactors(BitStream inStream)
        {
            int windowGroups = info.getWindowGroupCount();
            int maxSFB       = info.getMaxSFB();

            //0: spectrum, 1: noise, 2: intensity
            int[] offset = { globalGain, globalGain - 90, 0 };

            int  tmp;
            bool noiseFlag = true;

            int sfb, idx = 0;

            for (int g = 0; g < windowGroups; g++)
            {
                for (sfb = 0; sfb < maxSFB;)
                {
                    int end = sectEnd[idx];
                    switch (sfbCB[idx])
                    {
                    case ZERO_HCB:
                    {
                        for (; sfb < end; sfb++, idx++)
                        {
                            scaleFactors[idx] = 0;
                        }
                    } break;

                    case INTENSITY_HCB:
                    case INTENSITY_HCB2:
                    {
                        for (; sfb < end; sfb++, idx++)
                        {
                            offset[2]        += Huffman.decodeScaleFactor(inStream) - SF_DELTA;
                            tmp               = Math.Min(Math.Max(offset[2], -155), 100);
                            scaleFactors[idx] = SCALEFACTOR_TABLE[-tmp + SF_OFFSET];
                        }
                    } break;

                    case NOISE_HCB:
                    {
                        throw new NotImplementedException();
                        //for (; sfb < end; sfb++, idx++)
                        //{
                        //  if (noiseFlag)
                        //  {
                        //    offset[1] += inStream.readBits(9) - 256;
                        //    noiseFlag = false;
                        //  }
                        //  else offset[1] += Huffman.decodeScaleFactor(inStream) - SF_DELTA;
                        //  tmp = Math.min(Math.max(offset[1], -100), 155);
                        //  scaleFactors[idx] = -SCALEFACTOR_TABLE[tmp + SF_OFFSET];
                        //}
                    } break;

                    default:
                    {
                        for (; sfb < end; sfb++, idx++)
                        {
                            offset[0] += Huffman.decodeScaleFactor(inStream) - SF_DELTA;
                            if (offset[0] > 255)
                            {
                                throw new AACException("scalefactor out of range: " + offset[0]);
                            }
                            scaleFactors[idx] = SCALEFACTOR_TABLE[offset[0] - 100 + SF_OFFSET];
                        }
                    } break;
                    }
                }
            }
        }