Пример #1
0
        void Allocate(int channel, ExpStrat expstr)
        {
            if (csnroffst == 0 && fsnroffst[channel] == 0)
            {
                Array.Clear(allocation[channel].bap, 0, allocation[channel].bap.Length);
                return;
            }
            int snroffset = (((csnroffst - 15) << 4) + fsnroffst[channel]) << 2;

            Allocate(0, endmant[channel], fastgain[fgaincod[channel]], snroffset, exps[channel], nchgrps[channel],
                     exps[channel][0], expstr, allocation[channel], deltba[channel]);
        }
Пример #2
0
        void AllocateCoupling(ExpStrat expstr)
        {
            if (csnroffst == 0 && cplfsnroffst == 0)
            {
                Array.Clear(couplingAllocation.bap, 0, couplingAllocation.bap.Length);
                return;
            }
            int snroffset = (((csnroffst - 15) << 4) + cplfsnroffst) << 2;

            Allocate(cplstrtmant, cplendmant, fastgain[cplfgaincod], snroffset, cplexps, ncplgrps, cplexps[0] << 1,
                     expstr, couplingAllocation, cpldeltba, (cplfleak << 8) + 768, (cplsleak << 8) + 768, true);
        }
Пример #3
0
        void Allocate(int start, int end, int fgain, int snroffset, int[] gexp, int ngrps, int absexp,
                      ExpStrat expstr, Allocation allocation, DeltaBitAllocation dba, int fastleak = 0, int slowleak = 0,
                      bool coupling = false)
        {
            // Unpack the mapped values
            int[] dexp = allocation.dexp;
            for (int grp = 0; grp < ngrps; ++grp)
            {
                int expacc = gexp[grp + 1];
                dexp[grp * 3]     = expacc / 25;
                expacc           -= 25 * dexp[grp * 3];
                dexp[grp * 3 + 1] = expacc / 5;
                expacc           -= (5 * dexp[grp * 3 + 1]);
                dexp[grp * 3 + 2] = expacc;
            }

            // Expand to full absolute exponent array
            int i, j;
            int grpsize = expstr != ExpStrat.D45 ? (int)expstr : 4;

            int[] exp = allocation.exp;
            exp[0] = absexp;
            int expOffset = coupling ? start : (start + 1);

            for (i = 0; i < (ngrps * 3); ++i)
            {
                absexp += dexp[i] - 2; // Convert from differentials to absolutes using unbiased mapped values
                for (j = 0; j < grpsize; ++j)
                {
                    exp[expOffset++] = absexp;
                }
            }

            // Initialization
            int sdecay = slowdec[sdcycod];
            int fdecay = fastdec[fdcycod];
            int sgain  = slowgain[sgaincod];
            int dbknee = dbpbtab[dbpbcod];
            int floor  = floortab[floorcod];

            // Exponent mapping into psd
            int[] psd = allocation.psd;
            for (int bin = start; bin < end; ++bin)
            {
                psd[bin] = 3072 - (exp[bin] << 7);
            }

            // psd integration
            int[] bndpsd = allocation.bndpsd;
            j = start;
            int k = masktab[start];
            int lastbin;

            do
            {
                lastbin   = Math.Min(bndtab[k], end);
                bndpsd[k] = psd[j++];
                for (i = j; i < lastbin; ++i, ++j)
                {
                    bndpsd[k] = LogAdd(bndpsd[k], psd[j]);
                }
                ++k;
            } while (end > lastbin);

            // Compute excitation function
            int[] excite  = allocation.excite;
            int   bndstrt = masktab[start];
            int   bndend  = masktab[end - 1] + 1;
            int   begin;

            if (bndstrt == 0)   // Full bandwidth and LFE channels
            {
                int lowcomp = CalcLowcomp(0, bndpsd[0], bndpsd[1], 0);
                excite[0] = bndpsd[0] - fgain - lowcomp;
                lowcomp   = CalcLowcomp(lowcomp, bndpsd[1], bndpsd[2], 1);
                excite[1] = bndpsd[1] - fgain - lowcomp;
                begin     = 7;
                for (int bin = 2; bin < 7; ++bin)
                {
                    if (bndend != 7 || bin != 6)
                    {
                        lowcomp = CalcLowcomp(lowcomp, bndpsd[bin], bndpsd[bin + 1], bin);
                    }
                    fastleak    = bndpsd[bin] - fgain;
                    slowleak    = bndpsd[bin] - sgain;
                    excite[bin] = fastleak - lowcomp;
                    if ((bndend != 7 || bin != 6) && bndpsd[bin] <= bndpsd[bin + 1])
                    {
                        begin = bin + 1;
                        break;
                    }
                }
                for (int bin = begin, bins = Math.Min(bndend, 22); bin < bins; ++bin)
                {
                    if (bndend != 7 || bin != 6)
                    {
                        lowcomp = CalcLowcomp(lowcomp, bndpsd[bin], bndpsd[bin + 1], bin);
                    }
                    fastleak    = Math.Max(fastleak - fdecay, bndpsd[bin] - fgain);
                    slowleak    = Math.Max(slowleak - sdecay, bndpsd[bin] - sgain);
                    excite[bin] = Math.Max(fastleak - lowcomp, slowleak);
                }
                begin = 22;
            }
            else   // Coupling channel
            {
                begin = bndstrt;
            }
            for (int bin = begin; bin < bndend; ++bin)
            {
                fastleak    = Math.Max(fastleak - fdecay, bndpsd[bin] - fgain);
                slowleak    = Math.Max(slowleak - sdecay, bndpsd[bin] - sgain);
                excite[bin] = Math.Max(fastleak, slowleak);
            }

            // Compute masking curve
            int[] mask = allocation.mask;
            for (int bin = bndstrt; bin < bndend; ++bin)
            {
                if (bndpsd[bin] < dbknee)
                {
                    excite[bin] += (dbknee - bndpsd[bin]) >> 2;
                }
                mask[bin] = Math.Max(excite[bin], hth[header.SampleRateCode][bin]);
            }

            // Apply delta bit allocation
            if (dba.enabled == DeltaBitAllocationMode.Reuse || dba.enabled == DeltaBitAllocationMode.NewInfoFollows)
            {
                int[] offset        = dba.Offset;
                int[] length        = dba.Length;
                int[] bitAllocation = dba.BitAllocation;
                for (int band = bndstrt, seg = 0; seg < offset.Length; ++seg)
                {
                    band += offset[seg];
                    int delta = bitAllocation[seg] >= 4 ? (bitAllocation[seg] - 3) << 7 : ((bitAllocation[seg] - 4) << 7);
                    for (k = 0; k < length[seg]; ++k)
                    {
                        mask[band++] += delta;
                    }
                }
            }

            // Compute bit allocation
            byte[] bap = allocation.bap;
            i = start;
            j = masktab[start];
            do
            {
                lastbin = Math.Min(bndtab[j], end);
                int masked = mask[j] - snroffset - floor;
                if (masked < 0)
                {
                    masked = 0;
                }
                masked = (masked & 0x1fe0) + floor;
                while (i < lastbin)
                {
                    int address = (psd[i] - masked) >> 5;
                    address  = Math.Min(63, Math.Max(0, address));
                    bap[i++] = baptab[address];
                }
                j++;
            }while (end > lastbin);
            Array.Clear(bap, i, bap.Length - i);
        }
Пример #4
0
#pragma warning restore IDE0052 // Remove unread private members

        void CreateCacheTables(int blocks, int channels)
        {
            blksw         = new bool[channels];
            chahtinu      = new int[channels];
            chbwcod       = new int[channels];
            chexpstr      = new ExpStrat[blocks][];
            chincpl       = new bool[channels];
            chinspx       = new bool[channels];
            chinspxatten  = new bool[channels];
            chintransproc = new bool[channels];
            chmant        = new int[channels][];
            convexpstr    = new int[channels];
            cplcoe        = new bool[channels];
            cplcoexp      = new int[channels][];
            cplcomant     = new int[channels][];
            cplexps       = new int[maxAllocationSize];
            cplexpstr     = new ExpStrat[blocks];
            cplinu        = new bool[blocks];
            cplstre       = new bool[blocks];
            deltba        = new DeltaBitAllocation[channels];
            dithflag      = new bool[channels];
            endmant       = new int[channels];
            exps          = new int[channels][];
            fgaincod      = new int[channels];
            firstcplcos   = new bool[channels];
            firstspxcos   = new bool[channels];
            frmchexpstr   = new int[channels];
            fsnroffst     = new int[channels];
            gainrng       = new int[channels];
            lfeexps       = new int[nlfegrps + 1];
            lfeexpstr     = new bool[blocks];
            lfemant       = new int[nlfemant];
            mstrcplco     = new int[channels];
            mstrspxco     = new int[channels];
            nchgrps       = new int[channels];
            spxattencod   = new int[channels];
            spxblnd       = new int[channels];
            spxcoe        = new bool[channels];
            spxcoexp      = new int[channels][];
            spxcomant     = new int[channels][];
            transproclen  = new int[channels];
            transprocloc  = new int[channels];

            for (int block = 0; block < blocks; ++block)
            {
                chexpstr[block] = new ExpStrat[channels];
            }

            allocation         = new Allocation[channels];
            couplingAllocation = new Allocation(maxAllocationSize);
            lfeAllocation      = new Allocation(maxAllocationSize);
            cpldeltba.Reset();
            lfedeltba.Reset();
            for (int channel = 0; channel < channels; ++channel)
            {
                allocation[channel] = new Allocation(maxAllocationSize);
                chmant[channel]     = new int[maxAllocationSize];
                cplcoexp[channel]   = new int[cplbndstrc.Length];
                cplcomant[channel]  = new int[cplbndstrc.Length];
                deltba[channel].Reset();
                exps[channel] = new int[maxAllocationSize];
            }
        }