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); }
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); } }