/* * Decompiled with CFR 0.152. */ package de.maxhenkel.voicechat.concentus; import de.maxhenkel.voicechat.concentus.AnalysisInfo; import de.maxhenkel.voicechat.concentus.Arrays; import de.maxhenkel.voicechat.concentus.Bands; import de.maxhenkel.voicechat.concentus.BoxedValueInt; import de.maxhenkel.voicechat.concentus.CeltMode; import de.maxhenkel.voicechat.concentus.CeltTables; import de.maxhenkel.voicechat.concentus.EntropyCoder; import de.maxhenkel.voicechat.concentus.Inlines; import de.maxhenkel.voicechat.concentus.Kernels; import de.maxhenkel.voicechat.concentus.MDCT; import de.maxhenkel.voicechat.concentus.OpusFramesize; import de.maxhenkel.voicechat.concentus.Pitch; class CeltCommon { private static final short[] inv_table = new short[]{255, 255, 156, 110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25, 23, 22, 21, 20, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2}; private static final short[][] gains = new short[][]{{10048, 7112, 4248}, {15200, 8784, 0}, {26208, 3280, 0}}; private static final byte[][] tf_select_table = new byte[][]{{0, -1, 0, -1, 0, -1, 0, -1}, {0, -1, 0, -2, 1, 0, 1, -1}, {0, -2, 0, -3, 2, 0, 1, -1}, {0, -2, 0, -3, 3, 0, 1, -1}}; CeltCommon() { } static int compute_vbr(CeltMode mode, AnalysisInfo analysis, int base_target, int LM, int bitrate, int lastCodedBands, int C, int intensity, int constrained_vbr, int stereo_saving, int tot_boost, int tf_estimate, int pitch_change, int maxDepth, OpusFramesize variable_duration, int lfe, int has_surround_mask, int surround_masking, int temporal_vbr) { int nbEBands = mode.nbEBands; short[] eBands = mode.eBands; int coded_bands = lastCodedBands != 0 ? lastCodedBands : nbEBands; int coded_bins = eBands[coded_bands] << LM; if (C == 2) { coded_bins += eBands[Inlines.IMIN(intensity, coded_bands)] << LM; } int target = base_target; if (analysis.enabled && analysis.valid != 0 && (double)analysis.activity < 0.4) { target -= (int)((float)(coded_bins << 3) * (0.4f - analysis.activity)); } if (C == 2) { int coded_stereo_bands = Inlines.IMIN(intensity, coded_bands); int coded_stereo_dof = (eBands[coded_stereo_bands] << LM) - coded_stereo_bands; int max_frac = Inlines.DIV32_16(Inlines.MULT16_16(26214, coded_stereo_dof), coded_bins); stereo_saving = Inlines.MIN16(stereo_saving, 256); target -= Inlines.MIN32(Inlines.MULT16_32_Q15(max_frac, target), Inlines.SHR32(Inlines.MULT16_16(stereo_saving - 26, coded_stereo_dof << 3), 8)); } target += tot_boost - (16 << LM); int tf_calibration = variable_duration == OpusFramesize.OPUS_FRAMESIZE_VARIABLE ? 328 : 655; target += Inlines.SHL32(Inlines.MULT16_32_Q15(tf_estimate - tf_calibration, target), 1); if (analysis.enabled && analysis.valid != 0 && lfe == 0) { float tonal = Inlines.MAX16(0.0f, analysis.tonality - 0.15f) - 0.09f; int tonal_target = target + (int)((float)(coded_bins << 3) * 1.2f * tonal); if (pitch_change != 0) { tonal_target += (int)((float)(coded_bins << 3) * 0.8f); } target = tonal_target; } if (has_surround_mask != 0 && lfe == 0) { int surround_target = target + Inlines.SHR32(Inlines.MULT16_16(surround_masking, coded_bins << 3), 10); target = Inlines.IMAX(target / 4, surround_target); } int bins = eBands[nbEBands - 2] << LM; int floor_depth = Inlines.SHR32(Inlines.MULT16_16(C * bins << 3, maxDepth), 10); floor_depth = Inlines.IMAX(floor_depth, target >> 2); target = Inlines.IMIN(target, floor_depth); if (!(has_surround_mask != 0 && lfe == 0 || constrained_vbr == 0 && bitrate >= 64000)) { int rate_factor = Inlines.MAX16(0, bitrate - 32000); if (constrained_vbr != 0) { rate_factor = Inlines.MIN16(rate_factor, 21955); } target = base_target + Inlines.MULT16_32_Q15(rate_factor, target - base_target); } if (has_surround_mask == 0 && tf_estimate < 3277) { int amount = Inlines.MULT16_16_Q15(3329, Inlines.IMAX(0, Inlines.IMIN(32000, 96000 - bitrate))); int tvbr_factor = Inlines.SHR32(Inlines.MULT16_16(temporal_vbr, amount), 10); target += Inlines.MULT16_32_Q15(tvbr_factor, target); } target = Inlines.IMIN(2 * base_target, target); return target; } static int transient_analysis(int[][] input, int len, int C, BoxedValueInt tf_estimate, BoxedValueInt tf_chan) { int is_transient = 0; int mask_metric = 0; tf_chan.Val = 0; int[] tmp = new int[len]; int len2 = len / 2; for (int c = 0; c < C; ++c) { int i; int unmask = 0; int mem0 = 0; int mem1 = 0; for (i = 0; i < len; ++i) { int x = Inlines.SHR32(input[c][i], 12); int y = Inlines.ADD32(mem0, x); mem0 = mem1 + y - Inlines.SHL32(x, 1); mem1 = x - Inlines.SHR32(y, 1); tmp[i] = Inlines.EXTRACT16(Inlines.SHR32(y, 2)); } Arrays.MemSet(tmp, 0, 12); int shift = 0; shift = 14 - Inlines.celt_ilog2(1 + Inlines.celt_maxabs32(tmp, 0, len)); if (shift != 0) { for (i = 0; i < len; ++i) { tmp[i] = Inlines.SHL16(tmp[i], shift); } } int mean = 0; mem0 = 0; for (i = 0; i < len2; ++i) { int x2 = Inlines.PSHR32(Inlines.MULT16_16(tmp[2 * i], tmp[2 * i]) + Inlines.MULT16_16(tmp[2 * i + 1], tmp[2 * i + 1]), 16); mean += x2; tmp[i] = mem0 + Inlines.PSHR32(x2 - mem0, 4); mem0 = tmp[i]; } mem0 = 0; int maxE = 0; for (i = len2 - 1; i >= 0; --i) { tmp[i] = mem0 + Inlines.PSHR32(tmp[i] - mem0, 3); mem0 = tmp[i]; maxE = Inlines.MAX16(maxE, mem0); } mean = Inlines.MULT16_16(Inlines.celt_sqrt(mean), Inlines.celt_sqrt(Inlines.MULT16_16(maxE, len2 >> 1))); int norm = Inlines.SHL32(len2, 20) / Inlines.ADD32(1, Inlines.SHR32(mean, 1)); unmask = 0; for (i = 12; i < len2 - 5; i += 4) { int id = Inlines.MAX32(0, Inlines.MIN32(127, Inlines.MULT16_32_Q15(tmp[i] + 1, norm))); unmask += inv_table[id]; } if ((unmask = 64 * unmask * 4 / (6 * (len2 - 17))) <= mask_metric) continue; tf_chan.Val = c; mask_metric = unmask; } is_transient = mask_metric > 200 ? 1 : 0; int tf_max = Inlines.MAX16(0, Inlines.celt_sqrt(27 * mask_metric) - 42); tf_estimate.Val = Inlines.celt_sqrt(Inlines.MAX32(0, Inlines.SHL32(Inlines.MULT16_16(113, Inlines.MIN16(163, tf_max)), 14) - 37312528)); return is_transient; } static int patch_transient_decision(int[][] newE, int[][] oldE, int nbEBands, int start, int end, int C) { int i; int mean_diff = 0; int[] spread_old = new int[26]; if (C == 1) { spread_old[start] = oldE[0][start]; for (i = start + 1; i < end; ++i) { spread_old[i] = Inlines.MAX16(spread_old[i - 1] - 1024, oldE[0][i]); } } else { spread_old[start] = Inlines.MAX16(oldE[0][start], oldE[1][start]); for (i = start + 1; i < end; ++i) { spread_old[i] = Inlines.MAX16(spread_old[i - 1] - 1024, Inlines.MAX16(oldE[0][i], oldE[1][i])); } } for (i = end - 2; i >= start; --i) { spread_old[i] = Inlines.MAX16(spread_old[i], spread_old[i + 1] - 1024); } int c = 0; do { for (i = Inlines.IMAX(2, start); i < end - 1; ++i) { int x1 = Inlines.MAX16(0, newE[c][i]); int x2 = Inlines.MAX16(0, spread_old[i]); mean_diff = Inlines.ADD32(mean_diff, Inlines.MAX16(0, Inlines.SUB16(x1, x2))); } } while (++c < C); return (mean_diff = Inlines.DIV32(mean_diff, C * (end - 1 - Inlines.IMAX(2, start)))) > 1024 ? 1 : 0; } static void compute_mdcts(CeltMode mode, int shortBlocks, int[][] input, int[][] output, int C, int CC, int LM, int upsample) { int i; int shift; int N; int B; int overlap = mode.overlap; if (shortBlocks != 0) { B = shortBlocks; N = mode.shortMdctSize; shift = mode.maxLM; } else { B = 1; N = mode.shortMdctSize << LM; shift = mode.maxLM - LM; } int c = 0; do { for (int b = 0; b < B; ++b) { MDCT.clt_mdct_forward(mode.mdct, input[c], b * N, output[c], b, mode.window, overlap, shift, B); } } while (++c < CC); if (CC == 2 && C == 1) { for (i = 0; i < B * N; ++i) { output[0][i] = Inlines.ADD32(Inlines.HALF32(output[0][i]), Inlines.HALF32(output[1][i])); } } if (upsample != 1) { c = 0; do { int bound = B * N / upsample; i = 0; while (i < bound) { int[] nArray = output[c]; int n = i++; nArray[n] = nArray[n] * upsample; } Arrays.MemSetWithOffset(output[c], 0, bound, B * N - bound); } while (++c < C); } } static void celt_preemphasis(short[] pcmp, int pcmp_ptr, int[] inp, int inp_ptr, int N, int CC, int upsample, int[] coef, BoxedValueInt mem, int clip) { int i; int coef0 = coef[0]; int m = mem.Val; if (coef[1] == 0 && upsample == 1 && clip == 0) { for (int i2 = 0; i2 < N; ++i2) { short x = pcmp[pcmp_ptr + CC * i2]; inp[inp_ptr + i2] = Inlines.SHL32(x, 12) - m; m = Inlines.SHR32(Inlines.MULT16_16(coef0, (int)x), 3); } mem.Val = m; return; } int Nu = N / upsample; if (upsample != 1) { Arrays.MemSetWithOffset(inp, 0, inp_ptr, N); } for (i = 0; i < Nu; ++i) { inp[inp_ptr + i * upsample] = pcmp[pcmp_ptr + CC * i]; } for (i = 0; i < N; ++i) { int x = inp[inp_ptr + i]; inp[inp_ptr + i] = Inlines.SHL32(x, 12) - m; m = Inlines.SHR32(Inlines.MULT16_16(coef0, x), 3); } mem.Val = m; } static void celt_preemphasis(short[] pcmp, int[] inp, int inp_ptr, int N, int CC, int upsample, int[] coef, BoxedValueInt mem, int clip) { int i; int coef0 = coef[0]; int m = mem.Val; if (coef[1] == 0 && upsample == 1 && clip == 0) { for (int i2 = 0; i2 < N; ++i2) { short x = pcmp[CC * i2]; inp[inp_ptr + i2] = Inlines.SHL32(x, 12) - m; m = Inlines.SHR32(Inlines.MULT16_16(coef0, (int)x), 3); } mem.Val = m; return; } int Nu = N / upsample; if (upsample != 1) { Arrays.MemSetWithOffset(inp, 0, inp_ptr, N); } for (i = 0; i < Nu; ++i) { inp[inp_ptr + i * upsample] = pcmp[CC * i]; } for (i = 0; i < N; ++i) { int x = inp[inp_ptr + i]; inp[inp_ptr + i] = Inlines.SHL32(x, 12) - m; m = Inlines.SHR32(Inlines.MULT16_16(coef0, x), 3); } mem.Val = m; } static int l1_metric(int[] tmp, int N, int LM, int bias) { int L1 = 0; for (int i = 0; i < N; ++i) { L1 += Inlines.EXTEND32(Inlines.ABS32(tmp[i])); } L1 = Inlines.MAC16_32_Q15(L1, LM * bias, L1); return L1; } static int tf_analysis(CeltMode m, int len, int isTransient, int[] tf_res, int lambda, int[][] X, int N0, int LM, BoxedValueInt tf_sum, int tf_estimate, int tf_chan) { int curr1; int curr0; int cost1; int cost0; int i; int[] selcost = new int[2]; int tf_select = 0; int bias = Inlines.MULT16_16_Q14(1311, Inlines.MAX16(-4096, 8192 - tf_estimate)); int[] metric = new int[len]; int[] tmp = new int[m.eBands[len] - m.eBands[len - 1] << LM]; int[] tmp_1 = new int[m.eBands[len] - m.eBands[len - 1] << LM]; int[] path0 = new int[len]; int[] path1 = new int[len]; tf_sum.Val = 0; for (i = 0; i < len; ++i) { int L1; int best_level = 0; int N = m.eBands[i + 1] - m.eBands[i] << LM; boolean narrow = m.eBands[i + 1] - m.eBands[i] == 1; System.arraycopy(X[tf_chan], m.eBands[i] << LM, tmp, 0, N); int best_L1 = L1 = CeltCommon.l1_metric(tmp, N, isTransient != 0 ? LM : 0, bias); if (isTransient != 0 && !narrow) { System.arraycopy(tmp, 0, tmp_1, 0, N); Bands.haar1ZeroOffset(tmp_1, N >> LM, 1 << LM); L1 = CeltCommon.l1_metric(tmp_1, N, LM + 1, bias); if (L1 < best_L1) { best_L1 = L1; best_level = -1; } } for (int k = 0; k < LM + (isTransient == 0 && !narrow ? 1 : 0); ++k) { int B = isTransient != 0 ? LM - k - 1 : k + 1; Bands.haar1ZeroOffset(tmp, N >> k, 1 << k); L1 = CeltCommon.l1_metric(tmp, N, B, bias); if (L1 >= best_L1) continue; best_L1 = L1; best_level = k + 1; } metric[i] = isTransient != 0 ? 2 * best_level : -2 * best_level; tf_sum.Val = tf_sum.Val + ((isTransient != 0 ? LM : 0) - metric[i] / 2); if (!narrow || metric[i] != 0 && metric[i] != -2 * LM) continue; int n = i; metric[n] = metric[n] - 1; } tf_select = 0; for (int sel = 0; sel < 2; ++sel) { cost0 = 0; cost1 = isTransient != 0 ? 0 : lambda; for (i = 1; i < len; ++i) { curr0 = Inlines.IMIN(cost0, cost1 + lambda); curr1 = Inlines.IMIN(cost0 + lambda, cost1); cost0 = curr0 + Inlines.abs(metric[i] - 2 * CeltTables.tf_select_table[LM][4 * isTransient + 2 * sel + 0]); cost1 = curr1 + Inlines.abs(metric[i] - 2 * CeltTables.tf_select_table[LM][4 * isTransient + 2 * sel + 1]); } selcost[sel] = cost0 = Inlines.IMIN(cost0, cost1); } if (selcost[1] < selcost[0] && isTransient != 0) { tf_select = 1; } cost0 = 0; cost1 = isTransient != 0 ? 0 : lambda; for (i = 1; i < len; ++i) { int from0 = cost0; int from1 = cost1 + lambda; if (from0 < from1) { curr0 = from0; path0[i] = 0; } else { curr0 = from1; path0[i] = 1; } from0 = cost0 + lambda; from1 = cost1; if (from0 < from1) { curr1 = from0; path1[i] = 0; } else { curr1 = from1; path1[i] = 1; } cost0 = curr0 + Inlines.abs(metric[i] - 2 * CeltTables.tf_select_table[LM][4 * isTransient + 2 * tf_select + 0]); cost1 = curr1 + Inlines.abs(metric[i] - 2 * CeltTables.tf_select_table[LM][4 * isTransient + 2 * tf_select + 1]); } tf_res[len - 1] = cost0 < cost1 ? 0 : 1; for (i = len - 2; i >= 0; --i) { tf_res[i] = tf_res[i + 1] == 1 ? path1[i + 1] : path0[i + 1]; } return tf_select; } static void tf_encode(int start, int end, int isTransient, int[] tf_res, int LM, int tf_select, EntropyCoder enc) { int i; int budget = enc.storage * 8; int tell = enc.tell(); int logp = isTransient != 0 ? 2 : 4; int tf_select_rsv = LM > 0 && tell + logp + 1 <= budget ? 1 : 0; budget -= tf_select_rsv; int tf_changed = 0; int curr = 0; for (i = start; i < end; ++i) { if (tell + logp <= budget) { enc.enc_bit_logp(tf_res[i] ^ curr, logp); tell = enc.tell(); curr = tf_res[i]; tf_changed |= curr; } else { tf_res[i] = curr; } logp = isTransient != 0 ? 4 : 5; } if (tf_select_rsv != 0 && CeltTables.tf_select_table[LM][4 * isTransient + 0 + tf_changed] != CeltTables.tf_select_table[LM][4 * isTransient + 2 + tf_changed]) { enc.enc_bit_logp(tf_select, 1); } else { tf_select = 0; } for (i = start; i < end; ++i) { tf_res[i] = CeltTables.tf_select_table[LM][4 * isTransient + 2 * tf_select + tf_res[i]]; } } static int alloc_trim_analysis(CeltMode m, int[][] X, int[][] bandLogE, int end, int LM, int C, AnalysisInfo analysis, BoxedValueInt stereo_saving, int tf_estimate, int intensity, int surround_trim) { int i; int diff = 0; int trim = 1280; if (C == 2) { int partial; int sum = 0; for (i = 0; i < 8; ++i) { partial = Kernels.celt_inner_prod(X[0], m.eBands[i] << LM, X[1], m.eBands[i] << LM, m.eBands[i + 1] - m.eBands[i] << LM); sum = Inlines.ADD16(sum, (int)Inlines.EXTRACT16(Inlines.SHR32(partial, 18))); } sum = Inlines.MULT16_16_Q15(4096, sum); int minXC = sum = Inlines.MIN16(1024, Inlines.ABS32(sum)); for (i = 8; i < intensity; ++i) { partial = Kernels.celt_inner_prod(X[0], m.eBands[i] << LM, X[1], m.eBands[i] << LM, m.eBands[i + 1] - m.eBands[i] << LM); minXC = Inlines.MIN16(minXC, (int)Inlines.ABS16(Inlines.EXTRACT16(Inlines.SHR32(partial, 18)))); } minXC = Inlines.MIN16(1024, Inlines.ABS32(minXC)); int logXC = Inlines.celt_log2(1049625 - Inlines.MULT16_16(sum, sum)); int logXC2 = Inlines.MAX16(Inlines.HALF16(logXC), Inlines.celt_log2(1049625 - Inlines.MULT16_16(minXC, minXC))); logXC = Inlines.PSHR32(logXC - 6144, 2); logXC2 = Inlines.PSHR32(logXC2 - 6144, 2); trim += Inlines.MAX16(-1024, Inlines.MULT16_16_Q15(24576, logXC)); stereo_saving.Val = Inlines.MIN16(stereo_saving.Val + 64, 0 - Inlines.HALF16(logXC2)); } int c = 0; do { for (i = 0; i < end - 1; ++i) { diff += bandLogE[c][i] * (2 + 2 * i - end); } } while (++c < C); trim -= Inlines.MAX16((int)Inlines.NEG16((short)512), Inlines.MIN16(512, Inlines.SHR16((diff /= C * (end - 1)) + 1024, 2) / 6)); trim -= Inlines.SHR16(surround_trim, 2); trim -= 2 * Inlines.SHR16(tf_estimate, 6); if (analysis.enabled && analysis.valid != 0) { trim -= Inlines.MAX16(-512, Inlines.MIN16(512, (int)(512.0f * (analysis.tonality_slope + 0.05f)))); } int trim_index = Inlines.PSHR32(trim, 8); trim_index = Inlines.IMAX(0, Inlines.IMIN(10, trim_index)); return trim_index; } static int stereo_analysis(CeltMode m, int[][] X, int LM) { int sumLR = 1; int sumMS = 1; for (int i = 0; i < 13; ++i) { for (int j = m.eBands[i] << LM; j < m.eBands[i + 1] << LM; ++j) { int L = Inlines.EXTEND32(X[0][j]); int R = Inlines.EXTEND32(X[1][j]); int M = Inlines.ADD32(L, R); int S = Inlines.SUB32(L, R); sumLR = Inlines.ADD32(sumLR, Inlines.ADD32(Inlines.ABS32(L), Inlines.ABS32(R))); sumMS = Inlines.ADD32(sumMS, Inlines.ADD32(Inlines.ABS32(M), Inlines.ABS32(S))); } } sumMS = Inlines.MULT16_32_Q15((short)23170, sumMS); int thetas = 13; if (LM <= 1) { thetas -= 8; } return Inlines.MULT16_32_Q15((m.eBands[13] << LM + 1) + thetas, sumMS) > Inlines.MULT16_32_Q15(m.eBands[13] << LM + 1, sumLR) ? 1 : 0; } static int median_of_5(int[] x, int x_ptr) { int t4; int t3; int t1; int t0; int t2 = x[x_ptr + 2]; if (x[x_ptr] > x[x_ptr + 1]) { t0 = x[x_ptr + 1]; t1 = x[x_ptr]; } else { t0 = x[x_ptr]; t1 = x[x_ptr + 1]; } if (x[x_ptr + 3] > x[x_ptr + 4]) { t3 = x[x_ptr + 4]; t4 = x[x_ptr + 3]; } else { t3 = x[x_ptr + 3]; t4 = x[x_ptr + 4]; } if (t0 > t3) { int tmp = t3; t3 = t0; t0 = tmp; tmp = t4; t4 = t1; t1 = tmp; } if (t2 > t1) { if (t1 < t3) { return Inlines.MIN16(t2, t3); } return Inlines.MIN16(t4, t1); } if (t2 < t3) { return Inlines.MIN16(t1, t3); } return Inlines.MIN16(t2, t4); } static int median_of_3(int[] x, int x_ptr) { int t1; int t0; if (x[x_ptr] > x[x_ptr + 1]) { t0 = x[x_ptr + 1]; t1 = x[x_ptr]; } else { t0 = x[x_ptr]; t1 = x[x_ptr + 1]; } int t2 = x[x_ptr + 2]; if (t1 < t2) { return t1; } if (t0 < t2) { return t2; } return t0; } static int dynalloc_analysis(int[][] bandLogE, int[][] bandLogE2, int nbEBands, int start, int end, int C, int[] offsets, int lsb_depth, short[] logN, int isTransient, int vbr, int constrained_vbr, short[] eBands, int LM, int effectiveBytes, BoxedValueInt tot_boost_, int lfe, int[] surround_dynalloc) { int i; int tot_boost = 0; int[][] follower = Arrays.InitTwoDimensionalArrayInt(2, nbEBands); int[] noise_floor = new int[C * nbEBands]; Arrays.MemSet(offsets, 0, nbEBands); int maxDepth = -32666; for (i = 0; i < end; ++i) { noise_floor[i] = Inlines.MULT16_16((short)64, logN[i]) + 512 + Inlines.SHL16(9 - lsb_depth, 10) - Inlines.SHL16(CeltTables.eMeans[i], 6) + Inlines.MULT16_16(6, (i + 5) * (i + 5)); } int c = 0; do { for (i = 0; i < end; ++i) { maxDepth = Inlines.MAX16(maxDepth, bandLogE[c][i] - noise_floor[i]); } } while (++c < C); if (effectiveBytes > 50 && LM >= 1 && lfe == 0) { int last = 0; c = 0; do { int[] f = follower[c]; f[0] = bandLogE2[c][0]; for (i = 1; i < end; ++i) { if (bandLogE2[c][i] > bandLogE2[c][i - 1] + 512) { last = i; } f[i] = Inlines.MIN16(f[i - 1] + 1536, bandLogE2[c][i]); } for (i = last - 1; i >= 0; --i) { f[i] = Inlines.MIN16(f[i], Inlines.MIN16(f[i + 1] + 2048, bandLogE2[c][i])); } int offset = 1024; for (i = 2; i < end - 2; ++i) { f[i] = Inlines.MAX16(f[i], CeltCommon.median_of_5(bandLogE2[c], i - 2) - offset); } int tmp = CeltCommon.median_of_3(bandLogE2[c], 0) - offset; f[0] = Inlines.MAX16(f[0], tmp); f[1] = Inlines.MAX16(f[1], tmp); tmp = CeltCommon.median_of_3(bandLogE2[c], end - 3) - offset; f[end - 2] = Inlines.MAX16(f[end - 2], tmp); f[end - 1] = Inlines.MAX16(f[end - 1], tmp); for (i = 0; i < end; ++i) { f[i] = Inlines.MAX16(f[i], noise_floor[i]); } } while (++c < C); if (C == 2) { for (i = start; i < end; ++i) { follower[1][i] = Inlines.MAX16(follower[1][i], follower[0][i] - 4096); follower[0][i] = Inlines.MAX16(follower[0][i], follower[1][i] - 4096); follower[0][i] = Inlines.HALF16(Inlines.MAX16(0, bandLogE[0][i] - follower[0][i]) + Inlines.MAX16(0, bandLogE[1][i] - follower[1][i])); } } else { for (i = start; i < end; ++i) { follower[0][i] = Inlines.MAX16(0, bandLogE[0][i] - follower[0][i]); } } for (i = start; i < end; ++i) { follower[0][i] = Inlines.MAX16(follower[0][i], surround_dynalloc[i]); } if ((vbr == 0 || constrained_vbr != 0) && isTransient == 0) { for (i = start; i < end; ++i) { follower[0][i] = Inlines.HALF16(follower[0][i]); } } for (i = start; i < end; ++i) { int boost_bits; int boost; if (i < 8) { int[] nArray = follower[0]; int n = i; nArray[n] = nArray[n] * 2; } if (i >= 12) { follower[0][i] = Inlines.HALF16(follower[0][i]); } follower[0][i] = Inlines.MIN16(follower[0][i], 4096); int width = C * (eBands[i + 1] - eBands[i]) << LM; if (width < 6) { boost = Inlines.SHR32(follower[0][i], 10); boost_bits = boost * width << 3; } else if (width > 48) { boost = Inlines.SHR32(follower[0][i] * 8, 10); boost_bits = (boost * width << 3) / 8; } else { boost = Inlines.SHR32(follower[0][i] * width / 6, 10); boost_bits = boost * 6 << 3; } if ((vbr == 0 || constrained_vbr != 0 && isTransient == 0) && tot_boost + boost_bits >> 3 >> 3 > effectiveBytes / 4) { int cap = effectiveBytes / 4 << 3 << 3; offsets[i] = cap - tot_boost; tot_boost = cap; break; } offsets[i] = boost; tot_boost += boost_bits; } } tot_boost_.Val = tot_boost; return maxDepth; } static void deemphasis(int[][] input, int[] input_ptrs, short[] pcm, int pcm_ptr, int N, int C, int downsample, int[] coef, int[] mem, int accum) { boolean apply_downsampling = false; int[] scratch = new int[N]; int coef0 = coef[0]; int Nd = N / downsample; int c = 0; do { int tmp; int j; int m = mem[c]; int[] x = input[c]; int x_ptr = input_ptrs[c]; int y = pcm_ptr + c; if (downsample > 1) { for (j = 0; j < N; ++j) { tmp = x[x_ptr + j] + m + 0; m = Inlines.MULT16_32_Q15(coef0, tmp); scratch[j] = tmp; } apply_downsampling = true; } else if (accum != 0) { for (j = 0; j < N; ++j) { tmp = x[x_ptr + j] + m + 0; m = Inlines.MULT16_32_Q15(coef0, tmp); pcm[y + j * C] = Inlines.SAT16(Inlines.ADD32(pcm[y + j * C], Inlines.SIG2WORD16(tmp))); } } else { for (j = 0; j < N; ++j) { tmp = x[x_ptr + j] + m + 0; if (x[x_ptr + j] > 0 && m > 0 && tmp < 0) { tmp = Integer.MAX_VALUE; m = Integer.MAX_VALUE; } else { m = Inlines.MULT16_32_Q15(coef0, tmp); } pcm[y + j * C] = Inlines.SIG2WORD16(tmp); } } mem[c] = m; if (!apply_downsampling) continue; for (j = 0; j < Nd; ++j) { pcm[y + j * C] = Inlines.SIG2WORD16(scratch[j * downsample]); } } while (++c < C); } static void celt_synthesis(CeltMode mode, int[][] X, int[][] out_syn, int[] out_syn_ptrs, int[] oldBandE, int start, int effEnd, int C, int CC, int isTransient, int LM, int downsample, int silence) { int shift; int NB; int B; int overlap = mode.overlap; int nbEBands = mode.nbEBands; int N = mode.shortMdctSize << LM; int[] freq = new int[N]; int M = 1 << LM; if (isTransient != 0) { B = M; NB = mode.shortMdctSize; shift = mode.maxLM; } else { B = 1; NB = mode.shortMdctSize << LM; shift = mode.maxLM - LM; } if (CC == 2 && C == 1) { int b; Bands.denormalise_bands(mode, X[0], freq, 0, oldBandE, 0, start, effEnd, M, downsample, silence); int freq2 = out_syn_ptrs[1] + overlap / 2; System.arraycopy(freq, 0, out_syn[1], freq2, N); for (b = 0; b < B; ++b) { MDCT.clt_mdct_backward(mode.mdct, out_syn[1], freq2 + b, out_syn[0], out_syn_ptrs[0] + NB * b, mode.window, overlap, shift, B); } for (b = 0; b < B; ++b) { MDCT.clt_mdct_backward(mode.mdct, freq, b, out_syn[1], out_syn_ptrs[1] + NB * b, mode.window, overlap, shift, B); } } else if (CC == 1 && C == 2) { int freq2 = out_syn_ptrs[0] + overlap / 2; Bands.denormalise_bands(mode, X[0], freq, 0, oldBandE, 0, start, effEnd, M, downsample, silence); Bands.denormalise_bands(mode, X[1], out_syn[0], freq2, oldBandE, nbEBands, start, effEnd, M, downsample, silence); for (int i = 0; i < N; ++i) { freq[i] = Inlines.HALF32(Inlines.ADD32(freq[i], out_syn[0][freq2 + i])); } for (int b = 0; b < B; ++b) { MDCT.clt_mdct_backward(mode.mdct, freq, b, out_syn[0], out_syn_ptrs[0] + NB * b, mode.window, overlap, shift, B); } } else { int c = 0; do { Bands.denormalise_bands(mode, X[c], freq, 0, oldBandE, c * nbEBands, start, effEnd, M, downsample, silence); for (int b = 0; b < B; ++b) { MDCT.clt_mdct_backward(mode.mdct, freq, b, out_syn[c], out_syn_ptrs[c] + NB * b, mode.window, overlap, shift, B); } } while (++c < CC); } } static void tf_decode(int start, int end, int isTransient, int[] tf_res, int LM, EntropyCoder dec) { int i; int budget = dec.storage * 8; int tell = dec.tell(); int logp = isTransient != 0 ? 2 : 4; int tf_select_rsv = LM > 0 && tell + logp + 1 <= budget ? 1 : 0; budget -= tf_select_rsv; int curr = 0; int tf_changed = 0; for (i = start; i < end; ++i) { if (tell + logp <= budget) { tell = dec.tell(); tf_changed |= (curr ^= dec.dec_bit_logp(logp)); } tf_res[i] = curr; logp = isTransient != 0 ? 4 : 5; } int tf_select = 0; if (tf_select_rsv != 0 && CeltTables.tf_select_table[LM][4 * isTransient + 0 + tf_changed] != CeltTables.tf_select_table[LM][4 * isTransient + 2 + tf_changed]) { tf_select = dec.dec_bit_logp(1L); } for (i = start; i < end; ++i) { tf_res[i] = CeltTables.tf_select_table[LM][4 * isTransient + 2 * tf_select + tf_res[i]]; } } static int celt_plc_pitch_search(int[][] decode_mem, int C) { BoxedValueInt pitch_index = new BoxedValueInt(0); int[] lp_pitch_buf = new int[1024]; Pitch.pitch_downsample(decode_mem, lp_pitch_buf, 2048, C); Pitch.pitch_search(lp_pitch_buf, 360, lp_pitch_buf, 1328, 620, pitch_index); pitch_index.Val = 720 - pitch_index.Val; return pitch_index.Val; } static int resampling_factor(int rate) { int ret; switch (rate) { case 48000: { ret = 1; break; } case 24000: { ret = 2; break; } case 16000: { ret = 3; break; } case 12000: { ret = 4; break; } case 8000: { ret = 6; break; } default: { Inlines.OpusAssert(false); ret = 0; } } return ret; } static void comb_filter_const(int[] y, int y_ptr, int[] x, int x_ptr, int T, int N, int g10, int g11, int g12) { int xpt = x_ptr - T; int x4 = x[xpt - 2]; int x3 = x[xpt - 1]; int x2 = x[xpt]; int x1 = x[xpt + 1]; for (int i = 0; i < N; ++i) { int x0 = x[xpt + i + 2]; y[y_ptr + i] = x[x_ptr + i] + Inlines.MULT16_32_Q15(g10, x2) + Inlines.MULT16_32_Q15(g11, Inlines.ADD32(x1, x3)) + Inlines.MULT16_32_Q15(g12, Inlines.ADD32(x0, x4)); x4 = x3; x3 = x2; x2 = x1; x1 = x0; } } static void comb_filter(int[] y, int y_ptr, int[] x, int x_ptr, int T0, int T1, int N, int g0, int g1, int tapset0, int tapset1, int[] window, int overlap) { int i; if (g0 == 0 && g1 == 0) { if (x_ptr != y_ptr) { // empty if block } return; } int g00 = Inlines.MULT16_16_P15(g0, (int)gains[tapset0][0]); int g01 = Inlines.MULT16_16_P15(g0, (int)gains[tapset0][1]); int g02 = Inlines.MULT16_16_P15(g0, (int)gains[tapset0][2]); int g10 = Inlines.MULT16_16_P15(g1, (int)gains[tapset1][0]); int g11 = Inlines.MULT16_16_P15(g1, (int)gains[tapset1][1]); int g12 = Inlines.MULT16_16_P15(g1, (int)gains[tapset1][2]); int x1 = x[x_ptr - T1 + 1]; int x2 = x[x_ptr - T1]; int x3 = x[x_ptr - T1 - 1]; int x4 = x[x_ptr - T1 - 2]; if (g0 == g1 && T0 == T1 && tapset0 == tapset1) { overlap = 0; } for (i = 0; i < overlap; ++i) { int x0 = x[x_ptr + i - T1 + 2]; int f = Inlines.MULT16_16_Q15(window[i], window[i]); y[y_ptr + i] = x[x_ptr + i] + Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15((int)((short)(Short.MAX_VALUE - f)), g00), x[x_ptr + i - T0]) + Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15((int)((short)(Short.MAX_VALUE - f)), g01), Inlines.ADD32(x[x_ptr + i - T0 + 1], x[x_ptr + i - T0 - 1])) + Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15((int)((short)(Short.MAX_VALUE - f)), g02), Inlines.ADD32(x[x_ptr + i - T0 + 2], x[x_ptr + i - T0 - 2])) + Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15(f, g10), x2) + Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15(f, g11), Inlines.ADD32(x1, x3)) + Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15(f, g12), Inlines.ADD32(x0, x4)); x4 = x3; x3 = x2; x2 = x1; x1 = x0; } if (g1 == 0) { if (x_ptr != y_ptr) { // empty if block } return; } CeltCommon.comb_filter_const(y, y_ptr + i, x, x_ptr + i, T1, N - i, g10, g11, g12); } static void init_caps(CeltMode m, int[] cap, int LM, int C) { for (int i = 0; i < m.nbEBands; ++i) { int N = m.eBands[i + 1] - m.eBands[i] << LM; cap[i] = (m.cache.caps[m.nbEBands * (2 * LM + C - 1) + i] + 64) * C * N >> 2; } } }