Ejemplo n.º 1
0
        internal static int quant_coarse_energy_impl(CeltMode m, int start, int end,
                                                     int[][] eBands, int[][] oldEBands,
                                                     int budget, int tell,
                                                     byte[] prob_model, int[][] error, EntropyCoder enc,
                                                     int C, int LM, int intra, int max_decay, int lfe)
        {
            int i, c;
            int badness = 0;

            int[] prev = { 0, 0 };
            int   coef;
            int   beta;

            if (tell + 3 <= budget)
            {
                enc.enc_bit_logp(intra, 3);
            }

            if (intra != 0)
            {
                coef = 0;
                beta = beta_intra;
            }
            else
            {
                beta = beta_coef[LM];
                coef = pred_coef[LM];
            }

            /* Encode at a fixed coarse resolution */
            for (i = start; i < end; i++)
            {
                c = 0;
                do
                {
                    int bits_left;
                    int qi, qi0;
                    int q;
                    int x;
                    int f, tmp;
                    int oldE;
                    int decay_bound;
                    x    = eBands[c][i];
                    oldE = Inlines.MAX16(-((short)(0.5 + (9.0f) * (((int)1) << (CeltConstants.DB_SHIFT)))) /*Inlines.QCONST16(9.0f, CeltConstants.DB_SHIFT)*/, oldEBands[c][i]);
                    f    = Inlines.SHL32(Inlines.EXTEND32(x), 7) - Inlines.PSHR32(Inlines.MULT16_16(coef, oldE), 8) - prev[c];
                    /* Rounding to nearest integer here is really important! */
                    qi          = (f + ((int)(0.5 + (.5f) * (((int)1) << (CeltConstants.DB_SHIFT + 7)))) /*Inlines.QCONST32(.5f, CeltConstants.DB_SHIFT + 7)*/) >> (CeltConstants.DB_SHIFT + 7);
                    decay_bound = Inlines.EXTRACT16(Inlines.MAX32(-((short)(0.5 + (28.0f) * (((int)1) << (CeltConstants.DB_SHIFT)))) /*Inlines.QCONST16(28.0f, CeltConstants.DB_SHIFT)*/,
                                                                  Inlines.SUB32((int)oldEBands[c][i], max_decay)));

                    /* Prevent the energy from going down too quickly (e.g. for bands
                     * that have just one bin) */
                    if (qi < 0 && x < decay_bound)
                    {
                        qi += (int)Inlines.SHR16(Inlines.SUB16(decay_bound, x), CeltConstants.DB_SHIFT);
                        if (qi > 0)
                        {
                            qi = 0;
                        }
                    }
                    qi0 = qi;

                    /* If we don't have enough bits to encode all the energy, just assume
                     *  something safe. */
                    tell      = enc.tell();
                    bits_left = budget - tell - 3 * C * (end - i);
                    if (i != start && bits_left < 30)
                    {
                        if (bits_left < 24)
                        {
                            qi = Inlines.IMIN(1, qi);
                        }
                        if (bits_left < 16)
                        {
                            qi = Inlines.IMAX(-1, qi);
                        }
                    }
                    if (lfe != 0 && i >= 2)
                    {
                        qi = Inlines.IMIN(qi, 0);
                    }
                    if (budget - tell >= 15)
                    {
                        int pi;
                        pi = 2 * Inlines.IMIN(i, 20);
                        Laplace.ec_laplace_encode(enc, ref qi, (((uint)prob_model[pi]) << 7), ((int)prob_model[pi + 1]) << 6);
                    }
                    else if (budget - tell >= 2)
                    {
                        qi = Inlines.IMAX(-1, Inlines.IMIN(qi, 1));
                        enc.enc_icdf(2 * qi ^ (0 - (qi < 0 ? 1 : 0)), small_energy_icdf, 2);
                    }
                    else if (budget - tell >= 1)
                    {
                        qi = Inlines.IMIN(0, qi);
                        enc.enc_bit_logp(-qi, 1);
                    }
                    else
                    {
                        qi = -1;
                    }
                    error[c][i] = (Inlines.PSHR32(f, 7) - Inlines.SHL16((qi), CeltConstants.DB_SHIFT));
                    badness    += Inlines.abs(qi0 - qi);
                    q           = (int)Inlines.SHL32(qi, CeltConstants.DB_SHIFT); // opus bug: useless extend32

                    tmp             = Inlines.PSHR32(Inlines.MULT16_16(coef, oldE), 8) + prev[c] + Inlines.SHL32(q, 7);
                    tmp             = Inlines.MAX32(-((int)(0.5 + (28.0f) * (((int)1) << (CeltConstants.DB_SHIFT + 7)))) /*Inlines.QCONST32(28.0f, CeltConstants.DB_SHIFT + 7)*/, tmp);
                    oldEBands[c][i] = (Inlines.PSHR32(tmp, 7));
                    prev[c]         = prev[c] + Inlines.SHL32(q, 7) - Inlines.MULT16_16(beta, Inlines.PSHR32(q, 8));
                } while (++c < C);
            }
            return(lfe != 0 ? 0 : badness);
        }
Ejemplo n.º 2
0
        internal static void unquant_coarse_energy(CeltMode m, int start, int end, int[] oldEBands, int intra, EntropyCoder dec, int C, int LM)
        {
            byte[] prob_model = Tables.e_prob_model[LM][intra];
            int    i, c;

            int[] prev = { 0, 0 };
            int   coef;
            int   beta;
            int   budget;
            int   tell;

            if (intra != 0)
            {
                coef = 0;
                beta = beta_intra;
            }
            else
            {
                beta = beta_coef[LM];
                coef = pred_coef[LM];
            }

            budget = (int)dec.storage * 8;

            /* Decode at a fixed coarse resolution */
            for (i = start; i < end; i++)
            {
                c = 0;
                do
                {
                    int qi;
                    int q;
                    int tmp;

                    /* It would be better to express this invariant as a
                     * test on C at function entry, but that isn't enough
                     * to make the static analyzer happy. */
                    Inlines.OpusAssert(c < 2);
                    tell = dec.tell();
                    if (budget - tell >= 15)
                    {
                        int pi;
                        pi = 2 * Inlines.IMIN(i, 20);
                        qi = Laplace.ec_laplace_decode(dec,
                                                       (uint)prob_model[pi] << 7, prob_model[pi + 1] << 6);
                    }
                    else if (budget - tell >= 2)
                    {
                        qi = dec.dec_icdf(small_energy_icdf, 2);
                        qi = (qi >> 1) ^ -(qi & 1);
                    }
                    else if (budget - tell >= 1)
                    {
                        qi = 0 - dec.dec_bit_logp(1);
                    }
                    else
                    {
                        qi = -1;
                    }
                    q = (int)Inlines.SHL32(qi, CeltConstants.DB_SHIFT); // opus bug: useless extend32

                    oldEBands[i + c * m.nbEBands] = Inlines.MAX16((0 - ((short)(0.5 + (9.0f) * (((int)1) << (CeltConstants.DB_SHIFT)))) /*Inlines.QCONST16(9.0f, CeltConstants.DB_SHIFT)*/), oldEBands[i + c * m.nbEBands]);
                    tmp = Inlines.PSHR32(Inlines.MULT16_16(coef, oldEBands[i + c * m.nbEBands]), 8) + prev[c] + Inlines.SHL32(q, 7);
                    tmp = Inlines.MAX32(-((int)(0.5 + (28.0f) * (((int)1) << (CeltConstants.DB_SHIFT + 7)))) /*Inlines.QCONST32(28.0f, CeltConstants.DB_SHIFT + 7)*/, tmp);
                    oldEBands[i + c * m.nbEBands] = (Inlines.PSHR32(tmp, 7));
                    prev[c] = prev[c] + Inlines.SHL32(q, 7) - Inlines.MULT16_16(beta, Inlines.PSHR32(q, 8));
                } while (++c < C);
            }
        }