Files
AsminVoicechat/source/decompiled/de/maxhenkel/voicechat/concentus/CodecHelpers.java
T
asminme bbccd4a815
Build AsminVoicechat / prepare-release (push) Successful in 14s
Build AsminVoicechat / build-and-test (17) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (18) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (19) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (20) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (21) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (22) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (23) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (24) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (25) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (26) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (27-ea) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (16) (push) Canceled after 38s
first commit
2026-10-24 15:18:03 +02:00

371 lines
17 KiB
Java

/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.concentus;
import de.maxhenkel.voicechat.concentus.Arrays;
import de.maxhenkel.voicechat.concentus.Downmix;
import de.maxhenkel.voicechat.concentus.Filters;
import de.maxhenkel.voicechat.concentus.Inlines;
import de.maxhenkel.voicechat.concentus.OpusBandwidth;
import de.maxhenkel.voicechat.concentus.OpusBandwidthHelpers;
import de.maxhenkel.voicechat.concentus.OpusFramesize;
import de.maxhenkel.voicechat.concentus.OpusFramesizeHelpers;
import de.maxhenkel.voicechat.concentus.OpusMode;
import de.maxhenkel.voicechat.concentus.StereoWidthState;
public class CodecHelpers {
private static final int MAX_DYNAMIC_FRAMESIZE = 24;
static byte gen_toc(OpusMode mode, int framerate, OpusBandwidth bandwidth, int channels) {
int toc;
int period = 0;
while (framerate < 400) {
framerate <<= 1;
++period;
}
if (mode == OpusMode.MODE_SILK_ONLY) {
toc = (short)(OpusBandwidthHelpers.GetOrdinal(bandwidth) - OpusBandwidthHelpers.GetOrdinal(OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND) << 5);
toc = (short)(toc | (short)(period - 2 << 3));
} else if (mode == OpusMode.MODE_CELT_ONLY) {
int tmp = OpusBandwidthHelpers.GetOrdinal(bandwidth) - OpusBandwidthHelpers.GetOrdinal(OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND);
if (tmp < 0) {
tmp = 0;
}
toc = 128;
toc = (short)(toc | (short)(tmp << 5));
toc = (short)(toc | (short)(period << 3));
} else {
toc = 96;
toc = (short)(toc | (short)(OpusBandwidthHelpers.GetOrdinal(bandwidth) - OpusBandwidthHelpers.GetOrdinal(OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND) << 4));
toc = (short)(toc | (short)(period - 2 << 3));
}
toc = (short)(toc | (short)((channels == 2 ? 1 : 0) << 2));
return (byte)(0xFF & toc);
}
static void hp_cutoff(short[] input, int input_ptr, int cutoff_Hz, short[] output, int output_ptr, int[] hp_mem, int len, int channels, int Fs) {
int r_Q28;
int[] B_Q28 = new int[3];
int[] A_Q28 = new int[2];
Inlines.OpusAssert(cutoff_Hz <= 869074);
int Fc_Q19 = Inlines.silk_DIV32_16(Inlines.silk_SMULBB(2471, cutoff_Hz), Fs / 1000);
Inlines.OpusAssert(Fc_Q19 > 0 && Fc_Q19 < 32768);
B_Q28[0] = r_Q28 = 0x10000000 - Inlines.silk_MUL(471, Fc_Q19);
B_Q28[1] = Inlines.silk_LSHIFT(-r_Q28, 1);
B_Q28[2] = r_Q28;
int r_Q22 = Inlines.silk_RSHIFT(r_Q28, 6);
A_Q28[0] = Inlines.silk_SMULWW(r_Q22, Inlines.silk_SMULWW(Fc_Q19, Fc_Q19) - 0x800000);
A_Q28[1] = Inlines.silk_SMULWW(r_Q22, r_Q22);
Filters.silk_biquad_alt(input, input_ptr, B_Q28, A_Q28, hp_mem, 0, output, output_ptr, len, channels);
if (channels == 2) {
Filters.silk_biquad_alt(input, input_ptr + 1, B_Q28, A_Q28, hp_mem, 2, output, output_ptr + 1, len, channels);
}
}
static void dc_reject(short[] input, int input_ptr, int cutoff_Hz, short[] output, int output_ptr, int[] hp_mem, int len, int channels, int Fs) {
int shift = Inlines.celt_ilog2(Fs / (cutoff_Hz * 3));
for (int c = 0; c < channels; ++c) {
for (int i = 0; i < len; ++i) {
int x = Inlines.SHL32(Inlines.EXTEND32(input[channels * i + c + input_ptr]), 15);
int tmp = x - hp_mem[2 * c];
hp_mem[2 * c] = hp_mem[2 * c] + Inlines.PSHR32(x - hp_mem[2 * c], shift);
int y = tmp - hp_mem[2 * c + 1];
hp_mem[2 * c + 1] = hp_mem[2 * c + 1] + Inlines.PSHR32(tmp - hp_mem[2 * c + 1], shift);
output[channels * i + c + output_ptr] = Inlines.EXTRACT16(Inlines.SATURATE(Inlines.PSHR32(y, 15), Short.MAX_VALUE));
}
}
}
static void stereo_fade(short[] pcm_buf, int g1, int g2, int overlap48, int frame_size, int channels, int[] window, int Fs) {
int diff;
int i;
int inc = 48000 / Fs;
int overlap = overlap48 / inc;
g1 = Short.MAX_VALUE - g1;
g2 = Short.MAX_VALUE - g2;
for (i = 0; i < overlap; ++i) {
int w = Inlines.MULT16_16_Q15(window[i * inc], window[i * inc]);
int g = Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(w, g2), Short.MAX_VALUE - w, g1), 15);
diff = Inlines.EXTRACT16(Inlines.HALF32(pcm_buf[i * channels] - pcm_buf[i * channels + 1]));
diff = Inlines.MULT16_16_Q15(g, diff);
pcm_buf[i * channels] = (short)(pcm_buf[i * channels] - diff);
pcm_buf[i * channels + 1] = (short)(pcm_buf[i * channels + 1] + diff);
}
while (i < frame_size) {
diff = Inlines.EXTRACT16(Inlines.HALF32(pcm_buf[i * channels] - pcm_buf[i * channels + 1]));
diff = Inlines.MULT16_16_Q15(g2, diff);
pcm_buf[i * channels] = (short)(pcm_buf[i * channels] - diff);
pcm_buf[i * channels + 1] = (short)(pcm_buf[i * channels + 1] + diff);
++i;
}
}
static void gain_fade(short[] buffer, int buf_ptr, int g1, int g2, int overlap48, int frame_size, int channels, int[] window, int Fs) {
int g;
int w;
int i;
int inc = 48000 / Fs;
int overlap = overlap48 / inc;
if (channels == 1) {
for (i = 0; i < overlap; ++i) {
w = Inlines.MULT16_16_Q15(window[i * inc], window[i * inc]);
g = Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(w, g2), Short.MAX_VALUE - w, g1), 15);
buffer[buf_ptr + i] = (short)Inlines.MULT16_16_Q15(g, (int)buffer[buf_ptr + i]);
}
} else {
for (i = 0; i < overlap; ++i) {
w = Inlines.MULT16_16_Q15(window[i * inc], window[i * inc]);
g = Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(w, g2), Short.MAX_VALUE - w, g1), 15);
buffer[buf_ptr + i * 2] = (short)Inlines.MULT16_16_Q15(g, (int)buffer[buf_ptr + i * 2]);
buffer[buf_ptr + i * 2 + 1] = (short)Inlines.MULT16_16_Q15(g, (int)buffer[buf_ptr + i * 2 + 1]);
}
}
int c = 0;
do {
for (i = overlap; i < frame_size; ++i) {
buffer[buf_ptr + i * channels + c] = (short)Inlines.MULT16_16_Q15(g2, (int)buffer[buf_ptr + i * channels + c]);
}
} while (++c < channels);
}
static float transient_boost(float[] E, int E_ptr, float[] E_1, int LM, int maxM) {
float sumE = 0.0f;
float sumE_1 = 0.0f;
int M = Inlines.IMIN(maxM, (1 << LM) + 1);
for (int i = E_ptr; i < M + E_ptr; ++i) {
sumE += E[i];
sumE_1 += E_1[i];
}
float metric = sumE * sumE_1 / (float)(M * M);
return Inlines.MIN16(1.0f, (float)Math.sqrt(Inlines.MAX16(0.0f, 0.05f * (metric - 2.0f))));
}
static int transient_viterbi(float[] E, float[] E_1, int N, int frame_cost, int rate) {
int i;
float[][] cost = Arrays.InitTwoDimensionalArrayFloat(24, 16);
int[][] states = Arrays.InitTwoDimensionalArrayInt(24, 16);
float factor = rate < 80 ? 0.0f : (rate > 160 ? 1.0f : ((float)rate - 80.0f) / 80.0f);
for (i = 0; i < 16; ++i) {
states[0][i] = -1;
cost[0][i] = 1.0E10f;
}
for (i = 0; i < 4; ++i) {
cost[0][1 << i] = (float)(frame_cost + rate * (1 << i)) * (1.0f + factor * CodecHelpers.transient_boost(E, 0, E_1, i, N + 1));
states[0][1 << i] = i;
}
for (i = 1; i < N; ++i) {
int j;
for (j = 2; j < 16; ++j) {
cost[i][j] = cost[i - 1][j - 1];
states[i][j] = j - 1;
}
for (j = 0; j < 4; ++j) {
states[i][1 << j] = 1;
float min_cost = cost[i - 1][1];
for (int k = 1; k < 4; ++k) {
float tmp = cost[i - 1][(1 << k + 1) - 1];
if (!(tmp < min_cost)) continue;
states[i][1 << j] = (1 << k + 1) - 1;
min_cost = tmp;
}
float curr_cost = (float)(frame_cost + rate * (1 << j)) * (1.0f + factor * CodecHelpers.transient_boost(E, i, E_1, j, N - i + 1));
cost[i][1 << j] = min_cost;
if (N - i < 1 << j) {
float[] fArray = cost[i];
int n = 1 << j;
fArray[n] = fArray[n] + curr_cost * (float)(N - i) / (float)(1 << j);
continue;
}
float[] fArray = cost[i];
int n = 1 << j;
fArray[n] = fArray[n] + curr_cost;
}
}
int best_state = 1;
float best_cost = cost[N - 1][1];
for (i = 2; i < 16; ++i) {
if (!(cost[N - 1][i] < best_cost)) continue;
best_cost = cost[N - 1][i];
best_state = i;
}
for (i = N - 1; i >= 0; --i) {
best_state = states[i][best_state];
}
return best_state;
}
static int optimize_framesize(short[] x, int x_ptr, int len, int C, int Fs, int bitrate, int tonality, float[] mem, int buffering) {
int i;
int pos;
int offset;
float[] e = new float[28];
float[] e_1 = new float[27];
int bestLM = 0;
int subframe = Fs / 400;
int[] sub = new int[subframe];
e[0] = mem[0];
e_1[0] = 1.0f / (1.0f + mem[0]);
if (buffering != 0) {
offset = 2 * subframe - buffering;
Inlines.OpusAssert(offset >= 0 && offset <= subframe);
len -= offset;
e[1] = mem[1];
e_1[1] = 1.0f / (1.0f + mem[1]);
e[2] = mem[2];
e_1[2] = 1.0f / (1.0f + mem[2]);
pos = 3;
} else {
pos = 1;
offset = 0;
}
int N = Inlines.IMIN(len / subframe, 24);
int memx = 0;
for (i = 0; i < N; ++i) {
float tmp = 1.0f;
Downmix.downmix_int(x, x_ptr, sub, 0, subframe, i * subframe + offset, 0, -2, C);
if (i == 0) {
memx = sub[0];
}
for (int j = 0; j < subframe; ++j) {
int tmpx = sub[j];
tmp += (float)(tmpx - memx) * (float)(tmpx - memx);
memx = tmpx;
}
e[i + pos] = tmp;
e_1[i + pos] = 1.0f / tmp;
}
e[i + pos] = e[i + pos - 1];
if (buffering != 0) {
N = Inlines.IMIN(24, N + 2);
}
bestLM = CodecHelpers.transient_viterbi(e, e_1, N, (int)((1.0f + 0.5f * (float)tonality) * (float)(60 * C + 40)), bitrate / 400);
mem[0] = e[1 << bestLM];
if (buffering != 0) {
mem[1] = e[(1 << bestLM) + 1];
mem[2] = e[(1 << bestLM) + 2];
}
return bestLM;
}
static int frame_size_select(int frame_size, OpusFramesize variable_duration, int Fs) {
int new_size;
if (frame_size < Fs / 400) {
return -1;
}
if (variable_duration == OpusFramesize.OPUS_FRAMESIZE_ARG) {
new_size = frame_size;
} else if (variable_duration == OpusFramesize.OPUS_FRAMESIZE_VARIABLE) {
new_size = Fs / 50;
} else if (OpusFramesizeHelpers.GetOrdinal(variable_duration) >= OpusFramesizeHelpers.GetOrdinal(OpusFramesize.OPUS_FRAMESIZE_2_5_MS) && OpusFramesizeHelpers.GetOrdinal(variable_duration) <= OpusFramesizeHelpers.GetOrdinal(OpusFramesize.OPUS_FRAMESIZE_60_MS)) {
new_size = Inlines.IMIN(3 * Fs / 50, Fs / 400 << OpusFramesizeHelpers.GetOrdinal(variable_duration) - OpusFramesizeHelpers.GetOrdinal(OpusFramesize.OPUS_FRAMESIZE_2_5_MS));
} else {
return -1;
}
if (new_size > frame_size) {
return -1;
}
if (400 * new_size != Fs && 200 * new_size != Fs && 100 * new_size != Fs && 50 * new_size != Fs && 25 * new_size != Fs && 50 * new_size != 3 * Fs) {
return -1;
}
return new_size;
}
static int compute_frame_size(short[] analysis_pcm, int analysis_pcm_ptr, int frame_size, OpusFramesize variable_duration, int C, int Fs, int bitrate_bps, int delay_compensation, float[] subframe_mem, boolean analysis_enabled) {
if (analysis_enabled && variable_duration == OpusFramesize.OPUS_FRAMESIZE_VARIABLE && frame_size >= Fs / 200) {
int LM = 3;
LM = CodecHelpers.optimize_framesize(analysis_pcm, analysis_pcm_ptr, frame_size, C, Fs, bitrate_bps, 0, subframe_mem, delay_compensation);
while (Fs / 400 << LM > frame_size) {
--LM;
}
frame_size = Fs / 400 << LM;
} else {
frame_size = CodecHelpers.frame_size_select(frame_size, variable_duration, Fs);
}
if (frame_size < 0) {
return -1;
}
return frame_size;
}
static int compute_stereo_width(short[] pcm, int pcm_ptr, int frame_size, int Fs, StereoWidthState mem) {
int frame_rate = Fs / frame_size;
int short_alpha = Short.MAX_VALUE - 819175 / Inlines.IMAX(50, frame_rate);
int yy = 0;
int xy = 0;
int xx = 0;
for (int i = 0; i < frame_size - 3; i += 4) {
int pxx = 0;
int pxy = 0;
int pyy = 0;
int p2i = pcm_ptr + 2 * i;
short x = pcm[p2i];
short y = pcm[p2i + 1];
pxx = Inlines.SHR32(Inlines.MULT16_16((int)x, (int)x), 2);
pxy = Inlines.SHR32(Inlines.MULT16_16((int)x, (int)y), 2);
pyy = Inlines.SHR32(Inlines.MULT16_16((int)y, (int)y), 2);
x = pcm[p2i + 2];
y = pcm[p2i + 3];
pxx += Inlines.SHR32(Inlines.MULT16_16((int)x, (int)x), 2);
pxy += Inlines.SHR32(Inlines.MULT16_16((int)x, (int)y), 2);
pyy += Inlines.SHR32(Inlines.MULT16_16((int)y, (int)y), 2);
x = pcm[p2i + 4];
y = pcm[p2i + 5];
pxx += Inlines.SHR32(Inlines.MULT16_16((int)x, (int)x), 2);
pxy += Inlines.SHR32(Inlines.MULT16_16((int)x, (int)y), 2);
pyy += Inlines.SHR32(Inlines.MULT16_16((int)y, (int)y), 2);
x = pcm[p2i + 6];
y = pcm[p2i + 7];
xx += Inlines.SHR32(pxx += Inlines.SHR32(Inlines.MULT16_16((int)x, (int)x), 2), 10);
xy += Inlines.SHR32(pxy += Inlines.SHR32(Inlines.MULT16_16((int)x, (int)y), 2), 10);
yy += Inlines.SHR32(pyy += Inlines.SHR32(Inlines.MULT16_16((int)y, (int)y), 2), 10);
}
mem.XX += Inlines.MULT16_32_Q15(short_alpha, xx - mem.XX);
mem.XY += Inlines.MULT16_32_Q15(short_alpha, xy - mem.XY);
mem.YY += Inlines.MULT16_32_Q15(short_alpha, yy - mem.YY);
mem.XX = Inlines.MAX32(0, mem.XX);
mem.XY = Inlines.MAX32(0, mem.XY);
mem.YY = Inlines.MAX32(0, mem.YY);
if (Inlines.MAX32(mem.XX, mem.YY) > 210) {
int sqrt_xx = Inlines.celt_sqrt(mem.XX);
int sqrt_yy = Inlines.celt_sqrt(mem.YY);
int qrrt_xx = Inlines.celt_sqrt(sqrt_xx);
int qrrt_yy = Inlines.celt_sqrt(sqrt_yy);
mem.XY = Inlines.MIN32(mem.XY, sqrt_xx * sqrt_yy);
int corr = Inlines.SHR32(Inlines.frac_div32(mem.XY, 1 + Inlines.MULT16_16(sqrt_xx, sqrt_yy)), 16);
int ldiff = Short.MAX_VALUE * Inlines.ABS16(qrrt_xx - qrrt_yy) / (1 + qrrt_xx + qrrt_yy);
int width = Inlines.MULT16_16_Q15(Inlines.celt_sqrt(0x40000000 - Inlines.MULT16_16(corr, corr)), ldiff);
mem.smoothed_width += (width - mem.smoothed_width) / frame_rate;
mem.max_follower = Inlines.MAX16(mem.max_follower - 655 / frame_rate, mem.smoothed_width);
} else {
boolean width = false;
int corr = Short.MAX_VALUE;
boolean ldiff = false;
}
return Inlines.EXTRACT16(Inlines.MIN32(Short.MAX_VALUE, 20 * mem.max_follower));
}
static void smooth_fade(short[] in1, int in1_ptr, short[] in2, int in2_ptr, short[] output, int output_ptr, int overlap, int channels, int[] window, int Fs) {
int inc = 48000 / Fs;
for (int c = 0; c < channels; ++c) {
for (int i = 0; i < overlap; ++i) {
int w = Inlines.MULT16_16_Q15(window[i * inc], window[i * inc]);
output[output_ptr + i * channels + c] = (short)Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(w, (int)in2[in2_ptr + i * channels + c]), Short.MAX_VALUE - w, (int)in1[in1_ptr + i * channels + c]), 15);
}
}
}
public static String opus_strerror(int error) {
String[] error_strings = new String[]{"success", "invalid argument", "buffer too small", "error", "corrupted stream", "request not implemented", "invalid state", "memory allocation failed"};
if (error > 0 || error < -7) {
return "unknown error";
}
return error_strings[-error];
}
public static String GetVersionString() {
return "concentus 1.0a-java-fixed";
}
}