internal static void quant_coarse_energy(CeltMode m, int start, int end, int effEnd, int[][] eBands, int[][] oldEBands, uint budget, int[][] error, EntropyCoder enc, int C, int LM, int nbAvailableBytes, int force_intra, ref int delayedIntra, int two_pass, int loss_rate, int lfe) { int intra; int max_decay; int[][] oldEBands_intra; int[][] error_intra; EntropyCoder enc_start_state = new EntropyCoder(); // [porting note] stack variable uint tell; int badness1 = 0; int intra_bias; int new_distortion; intra = (force_intra != 0 || (two_pass == 0 && delayedIntra > 2 * C * (end - start) && nbAvailableBytes > (end - start) * C)) ? 1 : 0; intra_bias = (int)((budget * delayedIntra * loss_rate) / (C * 512)); new_distortion = loss_distortion(eBands, oldEBands, start, effEnd, m.nbEBands, C); tell = (uint)enc.tell(); if (tell + 3 > budget) { two_pass = intra = 0; } max_decay = ((short)(0.5 + (16.0f) * (((int)1) << (CeltConstants.DB_SHIFT)))) /*Inlines.QCONST16(16.0f, CeltConstants.DB_SHIFT)*/; if (end - start > 10) { max_decay = (Inlines.MIN32(max_decay, Inlines.SHL32(nbAvailableBytes, CeltConstants.DB_SHIFT - 3))); // opus bug: useless extend32 } if (lfe != 0) { max_decay = ((short)(0.5 + (3.0f) * (((int)1) << (CeltConstants.DB_SHIFT)))) /*Inlines.QCONST16(3.0f, CeltConstants.DB_SHIFT)*/; } enc_start_state.Assign(enc); oldEBands_intra = Arrays.InitTwoDimensionalArray <int>(C, m.nbEBands); error_intra = Arrays.InitTwoDimensionalArray <int>(C, m.nbEBands); Array.Copy(oldEBands[0], 0, oldEBands_intra[0], 0, m.nbEBands); if (C == 2) { Array.Copy(oldEBands[1], 0, oldEBands_intra[1], 0, m.nbEBands); } if (two_pass != 0 || intra != 0) { badness1 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands_intra, (int)budget, (int)tell, Tables.e_prob_model[LM][1], error_intra, enc, C, LM, 1, max_decay, lfe); } if (intra == 0) { int intra_buf; EntropyCoder enc_intra_state = new EntropyCoder(); // [porting note] stack variable int tell_intra; uint nstart_bytes; uint nintra_bytes; uint save_bytes; int badness2; byte[] intra_bits = null; tell_intra = (int)enc.tell_frac(); enc_intra_state.Assign(enc); nstart_bytes = enc_start_state.range_bytes(); nintra_bytes = enc_intra_state.range_bytes(); intra_buf = enc_intra_state.buf_ptr + (int)nstart_bytes; save_bytes = nintra_bytes - nstart_bytes; if (save_bytes != 0) { intra_bits = new byte[(int)save_bytes]; /* Copy bits from intra bit-stream */ Array.Copy(enc_intra_state.buf, intra_buf, intra_bits, 0, (int)save_bytes); } enc.Assign(enc_start_state); badness2 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, (int)budget, (int)tell, Tables.e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay, lfe); if (two_pass != 0 && (badness1 < badness2 || (badness1 == badness2 && ((int)enc.tell_frac()) + intra_bias > tell_intra))) { enc.Assign(enc_intra_state); /* Copy intra bits to bit-stream */ if (intra_bits != null) { Array.Copy(intra_bits, 0, enc_intra_state.buf, intra_buf, (int)(nintra_bytes - nstart_bytes)); } Array.Copy(oldEBands_intra[0], 0, oldEBands[0], 0, m.nbEBands); Array.Copy(error_intra[0], 0, error[0], 0, m.nbEBands); if (C == 2) { Array.Copy(oldEBands_intra[1], 0, oldEBands[1], 0, m.nbEBands); Array.Copy(error_intra[1], 0, error[1], 0, m.nbEBands); } intra = 1; } } else { Array.Copy(oldEBands_intra[0], 0, oldEBands[0], 0, m.nbEBands); Array.Copy(error_intra[0], 0, error[0], 0, m.nbEBands); if (C == 2) { Array.Copy(oldEBands_intra[1], 0, oldEBands[1], 0, m.nbEBands); Array.Copy(error_intra[1], 0, error[1], 0, m.nbEBands); } } if (intra != 0) { delayedIntra = new_distortion; } else { delayedIntra = Inlines.ADD32(Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15(pred_coef[LM], pred_coef[LM]), delayedIntra), new_distortion); } }