first commit
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
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
This commit is contained in:
commit
bbccd4a815
454 files changed
+45050
No files matched your search
@@ -0,0 +1,735 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package de.maxhenkel.voicechat.concentus;
|
||||
|
||||
import de.maxhenkel.voicechat.concentus.Arrays;
|
||||
import de.maxhenkel.voicechat.concentus.Bands;
|
||||
import de.maxhenkel.voicechat.concentus.BoxedValueInt;
|
||||
import de.maxhenkel.voicechat.concentus.CeltCommon;
|
||||
import de.maxhenkel.voicechat.concentus.CeltMode;
|
||||
import de.maxhenkel.voicechat.concentus.ChannelLayout;
|
||||
import de.maxhenkel.voicechat.concentus.CodecHelpers;
|
||||
import de.maxhenkel.voicechat.concentus.Inlines;
|
||||
import de.maxhenkel.voicechat.concentus.MDCT;
|
||||
import de.maxhenkel.voicechat.concentus.OpusApplication;
|
||||
import de.maxhenkel.voicechat.concentus.OpusBandwidth;
|
||||
import de.maxhenkel.voicechat.concentus.OpusEncoder;
|
||||
import de.maxhenkel.voicechat.concentus.OpusError;
|
||||
import de.maxhenkel.voicechat.concentus.OpusException;
|
||||
import de.maxhenkel.voicechat.concentus.OpusFramesize;
|
||||
import de.maxhenkel.voicechat.concentus.OpusMode;
|
||||
import de.maxhenkel.voicechat.concentus.OpusMultistream;
|
||||
import de.maxhenkel.voicechat.concentus.OpusRepacketizer;
|
||||
import de.maxhenkel.voicechat.concentus.OpusSignal;
|
||||
import de.maxhenkel.voicechat.concentus.QuantizeBands;
|
||||
import de.maxhenkel.voicechat.concentus.VorbisLayout;
|
||||
|
||||
public class OpusMSEncoder {
|
||||
final ChannelLayout layout = new ChannelLayout();
|
||||
int lfe_stream = 0;
|
||||
OpusApplication application = OpusApplication.OPUS_APPLICATION_AUDIO;
|
||||
OpusFramesize variable_duration = OpusFramesize.OPUS_FRAMESIZE_UNKNOWN;
|
||||
int surround = 0;
|
||||
int bitrate_bps = 0;
|
||||
final float[] subframe_mem = new float[3];
|
||||
OpusEncoder[] encoders = null;
|
||||
int[] window_mem = null;
|
||||
int[] preemph_mem = null;
|
||||
private static final int[] diff_table = new int[]{512, 300, 165, 87, 45, 23, 11, 6, 3, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
private final int MS_FRAME_TMP = 3832;
|
||||
|
||||
private OpusMSEncoder(int nb_streams, int nb_coupled_streams) {
|
||||
if (nb_streams < 1 || nb_coupled_streams > nb_streams || nb_coupled_streams < 0) {
|
||||
throw new IllegalArgumentException("Invalid channel count in MS encoder");
|
||||
}
|
||||
this.encoders = new OpusEncoder[nb_streams];
|
||||
for (int c = 0; c < nb_streams; ++c) {
|
||||
this.encoders[c] = new OpusEncoder();
|
||||
}
|
||||
int nb_channels = nb_coupled_streams * 2 + (nb_streams - nb_coupled_streams);
|
||||
this.window_mem = new int[nb_channels * 120];
|
||||
this.preemph_mem = new int[nb_channels];
|
||||
}
|
||||
|
||||
public void resetState() {
|
||||
this.subframe_mem[2] = 0.0f;
|
||||
this.subframe_mem[1] = 0.0f;
|
||||
this.subframe_mem[0] = 0.0f;
|
||||
if (this.surround != 0) {
|
||||
Arrays.MemSet(this.preemph_mem, 0, this.layout.nb_channels);
|
||||
Arrays.MemSet(this.window_mem, 0, this.layout.nb_channels * 120);
|
||||
}
|
||||
int encoder_ptr = 0;
|
||||
for (int s = 0; s < this.layout.nb_streams; ++s) {
|
||||
OpusEncoder enc = this.encoders[encoder_ptr++];
|
||||
enc.resetState();
|
||||
}
|
||||
}
|
||||
|
||||
static int validate_encoder_layout(ChannelLayout layout) {
|
||||
for (int s = 0; s < layout.nb_streams; ++s) {
|
||||
if (s < layout.nb_coupled_streams) {
|
||||
if (OpusMultistream.get_left_channel(layout, s, -1) == -1) {
|
||||
return 0;
|
||||
}
|
||||
if (OpusMultistream.get_right_channel(layout, s, -1) != -1) continue;
|
||||
return 0;
|
||||
}
|
||||
if (OpusMultistream.get_mono_channel(layout, s, -1) != -1) continue;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void channel_pos(int channels, int[] pos) {
|
||||
if (channels == 4) {
|
||||
pos[0] = 1;
|
||||
pos[1] = 3;
|
||||
pos[2] = 1;
|
||||
pos[3] = 3;
|
||||
} else if (channels == 3 || channels == 5 || channels == 6) {
|
||||
pos[0] = 1;
|
||||
pos[1] = 2;
|
||||
pos[2] = 3;
|
||||
pos[3] = 1;
|
||||
pos[4] = 3;
|
||||
pos[5] = 0;
|
||||
} else if (channels == 7) {
|
||||
pos[0] = 1;
|
||||
pos[1] = 2;
|
||||
pos[2] = 3;
|
||||
pos[3] = 1;
|
||||
pos[4] = 3;
|
||||
pos[5] = 2;
|
||||
pos[6] = 0;
|
||||
} else if (channels == 8) {
|
||||
pos[0] = 1;
|
||||
pos[1] = 2;
|
||||
pos[2] = 3;
|
||||
pos[3] = 1;
|
||||
pos[4] = 3;
|
||||
pos[5] = 1;
|
||||
pos[6] = 3;
|
||||
pos[7] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int logSum(int a, int b) {
|
||||
int diff;
|
||||
int max;
|
||||
if (a > b) {
|
||||
max = a;
|
||||
diff = Inlines.SUB32(Inlines.EXTEND32(a), Inlines.EXTEND32(b));
|
||||
} else {
|
||||
max = b;
|
||||
diff = Inlines.SUB32(Inlines.EXTEND32(b), Inlines.EXTEND32(a));
|
||||
}
|
||||
if (diff >= 8192) {
|
||||
return max;
|
||||
}
|
||||
int low = Inlines.SHR32(diff, 9);
|
||||
int frac = Inlines.SHL16(diff - Inlines.SHL16(low, 9), 6);
|
||||
return max + diff_table[low] + Inlines.MULT16_16_Q15(frac, Inlines.SUB16(diff_table[low + 1], diff_table[low]));
|
||||
}
|
||||
|
||||
static void surround_analysis(CeltMode celt_mode, short[] pcm, int pcm_ptr, int[] bandLogE, int[] mem, int[] preemph_mem, int len, int overlap, int channels, int rate) {
|
||||
int i;
|
||||
int c;
|
||||
int LM;
|
||||
int[] pos = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int[][] bandE = Arrays.InitTwoDimensionalArrayInt(1, 21);
|
||||
int[][] maskLogE = Arrays.InitTwoDimensionalArrayInt(3, 21);
|
||||
int upsample = CeltCommon.resampling_factor(rate);
|
||||
int frame_size = len * upsample;
|
||||
for (LM = 0; LM < celt_mode.maxLM && celt_mode.shortMdctSize << LM != frame_size; ++LM) {
|
||||
}
|
||||
int[] input = new int[frame_size + overlap];
|
||||
short[] x = new short[len];
|
||||
int[][] freq = Arrays.InitTwoDimensionalArrayInt(1, frame_size);
|
||||
OpusMSEncoder.channel_pos(channels, pos);
|
||||
for (c = 0; c < 3; ++c) {
|
||||
for (i = 0; i < 21; ++i) {
|
||||
maskLogE[c][i] = -28672;
|
||||
}
|
||||
}
|
||||
for (c = 0; c < channels; ++c) {
|
||||
System.arraycopy(mem, c * overlap, input, 0, overlap);
|
||||
OpusMSEncoder.opus_copy_channel_in_short(x, 0, 1, pcm, pcm_ptr, channels, c, len);
|
||||
BoxedValueInt boxed_preemph = new BoxedValueInt(preemph_mem[c]);
|
||||
CeltCommon.celt_preemphasis(x, input, overlap, frame_size, 1, upsample, celt_mode.preemph, boxed_preemph, 0);
|
||||
preemph_mem[c] = boxed_preemph.Val;
|
||||
MDCT.clt_mdct_forward(celt_mode.mdct, input, 0, freq[0], 0, celt_mode.window, overlap, celt_mode.maxLM - LM, 1);
|
||||
if (upsample != 1) {
|
||||
int bound = len;
|
||||
i = 0;
|
||||
while (i < bound) {
|
||||
int[] nArray = freq[0];
|
||||
int n = i++;
|
||||
nArray[n] = nArray[n] * upsample;
|
||||
}
|
||||
while (i < frame_size) {
|
||||
freq[0][i] = 0;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
Bands.compute_band_energies(celt_mode, freq, bandE, 21, 1, LM);
|
||||
QuantizeBands.amp2Log2(celt_mode, 21, 21, bandE[0], bandLogE, 21 * c, 1);
|
||||
for (i = 1; i < 21; ++i) {
|
||||
bandLogE[21 * c + i] = Inlines.MAX16(bandLogE[21 * c + i], bandLogE[21 * c + i - 1] - 1024);
|
||||
}
|
||||
for (i = 19; i >= 0; --i) {
|
||||
bandLogE[21 * c + i] = Inlines.MAX16(bandLogE[21 * c + i], bandLogE[21 * c + i + 1] - 2048);
|
||||
}
|
||||
if (pos[c] == 1) {
|
||||
for (i = 0; i < 21; ++i) {
|
||||
maskLogE[0][i] = OpusMSEncoder.logSum(maskLogE[0][i], bandLogE[21 * c + i]);
|
||||
}
|
||||
} else if (pos[c] == 3) {
|
||||
for (i = 0; i < 21; ++i) {
|
||||
maskLogE[2][i] = OpusMSEncoder.logSum(maskLogE[2][i], bandLogE[21 * c + i]);
|
||||
}
|
||||
} else if (pos[c] == 2) {
|
||||
for (i = 0; i < 21; ++i) {
|
||||
maskLogE[0][i] = OpusMSEncoder.logSum(maskLogE[0][i], bandLogE[21 * c + i] - 512);
|
||||
maskLogE[2][i] = OpusMSEncoder.logSum(maskLogE[2][i], bandLogE[21 * c + i] - 512);
|
||||
}
|
||||
}
|
||||
System.arraycopy(input, frame_size, mem, c * overlap, overlap);
|
||||
}
|
||||
for (i = 0; i < 21; ++i) {
|
||||
maskLogE[1][i] = Inlines.MIN32(maskLogE[0][i], maskLogE[2][i]);
|
||||
}
|
||||
int channel_offset = Inlines.HALF16(Inlines.celt_log2(32768 / (channels - 1)));
|
||||
for (c = 0; c < 3; ++c) {
|
||||
i = 0;
|
||||
while (i < 21) {
|
||||
int[] nArray = maskLogE[c];
|
||||
int n = i++;
|
||||
nArray[n] = nArray[n] + channel_offset;
|
||||
}
|
||||
}
|
||||
for (c = 0; c < channels; ++c) {
|
||||
if (pos[c] != 0) {
|
||||
int[] mask = maskLogE[pos[c] - 1];
|
||||
for (i = 0; i < 21; ++i) {
|
||||
bandLogE[21 * c + i] = bandLogE[21 * c + i] - mask[i];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < 21; ++i) {
|
||||
bandLogE[21 * c + i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int opus_multistream_encoder_init(int Fs, int channels, int streams, int coupled_streams, short[] mapping, OpusApplication application, int surround) {
|
||||
int ret;
|
||||
int i;
|
||||
if (channels > 255 || channels < 1 || coupled_streams > streams || streams < 1 || coupled_streams < 0 || streams > 255 - coupled_streams) {
|
||||
return OpusError.OPUS_BAD_ARG;
|
||||
}
|
||||
this.layout.nb_channels = channels;
|
||||
this.layout.nb_streams = streams;
|
||||
this.layout.nb_coupled_streams = coupled_streams;
|
||||
this.subframe_mem[2] = 0.0f;
|
||||
this.subframe_mem[1] = 0.0f;
|
||||
this.subframe_mem[0] = 0.0f;
|
||||
if (surround == 0) {
|
||||
this.lfe_stream = -1;
|
||||
}
|
||||
this.bitrate_bps = -1000;
|
||||
this.application = application;
|
||||
this.variable_duration = OpusFramesize.OPUS_FRAMESIZE_ARG;
|
||||
for (i = 0; i < this.layout.nb_channels; ++i) {
|
||||
this.layout.mapping[i] = mapping[i];
|
||||
}
|
||||
if (OpusMultistream.validate_layout(this.layout) == 0 || OpusMSEncoder.validate_encoder_layout(this.layout) == 0) {
|
||||
return OpusError.OPUS_BAD_ARG;
|
||||
}
|
||||
int encoder_ptr = 0;
|
||||
for (i = 0; i < this.layout.nb_coupled_streams; ++i) {
|
||||
ret = this.encoders[encoder_ptr].opus_init_encoder(Fs, 2, application);
|
||||
if (ret != OpusError.OPUS_OK) {
|
||||
return ret;
|
||||
}
|
||||
if (i == this.lfe_stream) {
|
||||
this.encoders[encoder_ptr].setIsLFE(true);
|
||||
}
|
||||
++encoder_ptr;
|
||||
}
|
||||
while (i < this.layout.nb_streams) {
|
||||
ret = this.encoders[encoder_ptr].opus_init_encoder(Fs, 1, application);
|
||||
if (i == this.lfe_stream) {
|
||||
this.encoders[encoder_ptr].setIsLFE(true);
|
||||
}
|
||||
if (ret != OpusError.OPUS_OK) {
|
||||
return ret;
|
||||
}
|
||||
++encoder_ptr;
|
||||
++i;
|
||||
}
|
||||
if (surround != 0) {
|
||||
Arrays.MemSet(this.preemph_mem, 0, channels);
|
||||
Arrays.MemSet(this.window_mem, 0, channels * 120);
|
||||
}
|
||||
this.surround = surround;
|
||||
return OpusError.OPUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enabled force condition propagation
|
||||
* Lifted jumps to return sites
|
||||
*/
|
||||
int opus_multistream_surround_encoder_init(int Fs, int channels, int mapping_family, BoxedValueInt streams, BoxedValueInt coupled_streams, short[] mapping, OpusApplication application) {
|
||||
streams.Val = 0;
|
||||
coupled_streams.Val = 0;
|
||||
if (channels > 255 || channels < 1) {
|
||||
return OpusError.OPUS_BAD_ARG;
|
||||
}
|
||||
this.lfe_stream = -1;
|
||||
if (mapping_family == 0) {
|
||||
if (channels == 1) {
|
||||
streams.Val = 1;
|
||||
coupled_streams.Val = 0;
|
||||
mapping[0] = 0;
|
||||
return this.opus_multistream_encoder_init(Fs, channels, streams.Val, coupled_streams.Val, mapping, application, channels > 2 && mapping_family == 1 ? 1 : 0);
|
||||
} else {
|
||||
if (channels != 2) return OpusError.OPUS_UNIMPLEMENTED;
|
||||
streams.Val = 1;
|
||||
coupled_streams.Val = 1;
|
||||
mapping[0] = 0;
|
||||
mapping[1] = 1;
|
||||
}
|
||||
return this.opus_multistream_encoder_init(Fs, channels, streams.Val, coupled_streams.Val, mapping, application, channels > 2 && mapping_family == 1 ? 1 : 0);
|
||||
} else if (mapping_family == 1 && channels <= 8 && channels >= 1) {
|
||||
streams.Val = VorbisLayout.vorbis_mappings[channels - 1].nb_streams;
|
||||
coupled_streams.Val = VorbisLayout.vorbis_mappings[channels - 1].nb_coupled_streams;
|
||||
for (int i = 0; i < channels; ++i) {
|
||||
mapping[i] = VorbisLayout.vorbis_mappings[channels - 1].mapping[i];
|
||||
}
|
||||
if (channels < 6) return this.opus_multistream_encoder_init(Fs, channels, streams.Val, coupled_streams.Val, mapping, application, channels > 2 && mapping_family == 1 ? 1 : 0);
|
||||
this.lfe_stream = streams.Val - 1;
|
||||
return this.opus_multistream_encoder_init(Fs, channels, streams.Val, coupled_streams.Val, mapping, application, channels > 2 && mapping_family == 1 ? 1 : 0);
|
||||
} else {
|
||||
if (mapping_family != 255) return OpusError.OPUS_UNIMPLEMENTED;
|
||||
streams.Val = channels;
|
||||
coupled_streams.Val = 0;
|
||||
for (int i = 0; i < channels; i = (int)((byte)(i + 1))) {
|
||||
mapping[i] = (short)i;
|
||||
}
|
||||
}
|
||||
return this.opus_multistream_encoder_init(Fs, channels, streams.Val, coupled_streams.Val, mapping, application, channels > 2 && mapping_family == 1 ? 1 : 0);
|
||||
}
|
||||
|
||||
public static OpusMSEncoder Create(int Fs, int channels, int streams, int coupled_streams, short[] mapping, OpusApplication application) throws OpusException {
|
||||
if (channels > 255 || channels < 1 || coupled_streams > streams || streams < 1 || coupled_streams < 0 || streams > 255 - coupled_streams) {
|
||||
throw new IllegalArgumentException("Invalid channel / stream configuration");
|
||||
}
|
||||
OpusMSEncoder st = new OpusMSEncoder(streams, coupled_streams);
|
||||
int ret = st.opus_multistream_encoder_init(Fs, channels, streams, coupled_streams, mapping, application, 0);
|
||||
if (ret != OpusError.OPUS_OK) {
|
||||
if (ret == OpusError.OPUS_BAD_ARG) {
|
||||
throw new IllegalArgumentException("OPUS_BAD_ARG when creating MS encoder");
|
||||
}
|
||||
throw new OpusException("Could not create MS encoder", ret);
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enabled force condition propagation
|
||||
* Lifted jumps to return sites
|
||||
*/
|
||||
static void GetStreamCount(int channels, int mapping_family, BoxedValueInt nb_streams, BoxedValueInt nb_coupled_streams) {
|
||||
if (mapping_family == 0) {
|
||||
if (channels == 1) {
|
||||
nb_streams.Val = 1;
|
||||
nb_coupled_streams.Val = 0;
|
||||
return;
|
||||
} else {
|
||||
if (channels != 2) throw new IllegalArgumentException("More than 2 channels requires custom mappings");
|
||||
nb_streams.Val = 1;
|
||||
nb_coupled_streams.Val = 1;
|
||||
}
|
||||
return;
|
||||
} else if (mapping_family == 1 && channels <= 8 && channels >= 1) {
|
||||
nb_streams.Val = VorbisLayout.vorbis_mappings[channels - 1].nb_streams;
|
||||
nb_coupled_streams.Val = VorbisLayout.vorbis_mappings[channels - 1].nb_coupled_streams;
|
||||
return;
|
||||
} else {
|
||||
if (mapping_family != 255) throw new IllegalArgumentException("Invalid mapping family");
|
||||
nb_streams.Val = channels;
|
||||
nb_coupled_streams.Val = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static OpusMSEncoder CreateSurround(int Fs, int channels, int mapping_family, BoxedValueInt streams, BoxedValueInt coupled_streams, short[] mapping, OpusApplication application) throws OpusException {
|
||||
if (channels > 255 || channels < 1 || application == OpusApplication.OPUS_APPLICATION_UNIMPLEMENTED) {
|
||||
throw new IllegalArgumentException("Invalid channel count or application");
|
||||
}
|
||||
BoxedValueInt nb_streams = new BoxedValueInt(0);
|
||||
BoxedValueInt nb_coupled_streams = new BoxedValueInt(0);
|
||||
OpusMSEncoder.GetStreamCount(channels, mapping_family, nb_streams, nb_coupled_streams);
|
||||
OpusMSEncoder st = new OpusMSEncoder(nb_streams.Val, nb_coupled_streams.Val);
|
||||
int ret = st.opus_multistream_surround_encoder_init(Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
|
||||
if (ret != OpusError.OPUS_OK) {
|
||||
if (ret == OpusError.OPUS_BAD_ARG) {
|
||||
throw new IllegalArgumentException("Bad argument passed to CreateSurround");
|
||||
}
|
||||
throw new OpusException("Could not create multistream encoder", ret);
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
int surround_rate_allocation(int[] out_rates, int frame_size) {
|
||||
int channel_rate;
|
||||
int rate_sum = 0;
|
||||
OpusEncoder ptr = this.encoders[0];
|
||||
int Fs = ptr.getSampleRate();
|
||||
int stream_offset = this.bitrate_bps > this.layout.nb_channels * 40000 ? 20000 : this.bitrate_bps / this.layout.nb_channels / 2;
|
||||
stream_offset += 60 * (Fs / frame_size - 50);
|
||||
int lfe_offset = 3500 + 60 * (Fs / frame_size - 50);
|
||||
int coupled_ratio = 512;
|
||||
int lfe_ratio = 32;
|
||||
if (this.bitrate_bps == -1000) {
|
||||
channel_rate = Fs + 60 * Fs / frame_size;
|
||||
} else if (this.bitrate_bps == -1) {
|
||||
channel_rate = 300000;
|
||||
} else {
|
||||
int nb_lfe = this.lfe_stream != -1 ? 1 : 0;
|
||||
int nb_coupled = this.layout.nb_coupled_streams;
|
||||
int nb_uncoupled = this.layout.nb_streams - nb_coupled - nb_lfe;
|
||||
int total = (nb_uncoupled << 8) + coupled_ratio * nb_coupled + nb_lfe * lfe_ratio;
|
||||
channel_rate = 256 * (this.bitrate_bps - lfe_offset * nb_lfe - stream_offset * (nb_coupled + nb_uncoupled)) / total;
|
||||
}
|
||||
for (int i = 0; i < this.layout.nb_streams; ++i) {
|
||||
out_rates[i] = i < this.layout.nb_coupled_streams ? stream_offset + (channel_rate * coupled_ratio >> 8) : (i != this.lfe_stream ? stream_offset + channel_rate : lfe_offset + (channel_rate * lfe_ratio >> 8));
|
||||
out_rates[i] = Inlines.IMAX(out_rates[i], 500);
|
||||
rate_sum += out_rates[i];
|
||||
}
|
||||
return rate_sum;
|
||||
}
|
||||
|
||||
int opus_multistream_encode_native(short[] pcm, int pcm_ptr, int analysis_frame_size, byte[] data, int data_ptr, int max_data_bytes, int lsb_depth, int float_api) {
|
||||
int s;
|
||||
byte[] tmp_data = new byte[3832];
|
||||
OpusRepacketizer rp = new OpusRepacketizer();
|
||||
int[] bitrates = new int[256];
|
||||
int[] bandLogE = new int[42];
|
||||
int[] mem = null;
|
||||
int[] preemph_mem = null;
|
||||
if (this.surround != 0) {
|
||||
preemph_mem = this.preemph_mem;
|
||||
mem = this.window_mem;
|
||||
}
|
||||
int encoder_ptr = 0;
|
||||
int Fs = this.encoders[encoder_ptr].getSampleRate();
|
||||
boolean vbr = this.encoders[encoder_ptr].getUseVBR();
|
||||
CeltMode celt_mode = this.encoders[encoder_ptr].GetCeltMode();
|
||||
int channels = this.layout.nb_streams + this.layout.nb_coupled_streams;
|
||||
int delay_compensation = this.encoders[encoder_ptr].getLookahead();
|
||||
int frame_size = CodecHelpers.compute_frame_size(pcm, pcm_ptr, analysis_frame_size, this.variable_duration, channels, Fs, this.bitrate_bps, delay_compensation -= Fs / 400, this.subframe_mem, this.encoders[encoder_ptr].analysis.enabled);
|
||||
if (400 * frame_size < Fs) {
|
||||
return OpusError.OPUS_BAD_ARG;
|
||||
}
|
||||
if (400 * frame_size != Fs && 200 * frame_size != Fs && 100 * frame_size != Fs && 50 * frame_size != Fs && 25 * frame_size != Fs && 50 * frame_size != 3 * Fs) {
|
||||
return OpusError.OPUS_BAD_ARG;
|
||||
}
|
||||
int smallest_packet = this.layout.nb_streams * 2 - 1;
|
||||
if (max_data_bytes < smallest_packet) {
|
||||
return OpusError.OPUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
short[] buf = new short[2 * frame_size];
|
||||
int[] bandSMR = new int[21 * this.layout.nb_channels];
|
||||
if (this.surround != 0) {
|
||||
OpusMSEncoder.surround_analysis(celt_mode, pcm, pcm_ptr, bandSMR, mem, preemph_mem, frame_size, 120, this.layout.nb_channels, Fs);
|
||||
}
|
||||
int rate_sum = this.surround_rate_allocation(bitrates, frame_size);
|
||||
if (!vbr) {
|
||||
if (this.bitrate_bps == -1000) {
|
||||
max_data_bytes = Inlines.IMIN(max_data_bytes, 3 * rate_sum / (24 * Fs / frame_size));
|
||||
} else if (this.bitrate_bps != -1) {
|
||||
max_data_bytes = Inlines.IMIN(max_data_bytes, Inlines.IMAX(smallest_packet, 3 * this.bitrate_bps / (24 * Fs / frame_size)));
|
||||
}
|
||||
}
|
||||
for (s = 0; s < this.layout.nb_streams; ++s) {
|
||||
OpusEncoder enc = this.encoders[encoder_ptr];
|
||||
++encoder_ptr;
|
||||
enc.setBitrate(bitrates[s]);
|
||||
if (this.surround == 0) continue;
|
||||
int equiv_rate = this.bitrate_bps;
|
||||
if (frame_size * 50 < Fs) {
|
||||
equiv_rate -= 60 * (Fs / frame_size - 50) * this.layout.nb_channels;
|
||||
}
|
||||
if (equiv_rate > 10000 * this.layout.nb_channels) {
|
||||
enc.setBandwidth(OpusBandwidth.OPUS_BANDWIDTH_FULLBAND);
|
||||
} else if (equiv_rate > 7000 * this.layout.nb_channels) {
|
||||
enc.setBandwidth(OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND);
|
||||
} else if (equiv_rate > 5000 * this.layout.nb_channels) {
|
||||
enc.setBandwidth(OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND);
|
||||
} else {
|
||||
enc.setBandwidth(OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND);
|
||||
}
|
||||
if (s >= this.layout.nb_coupled_streams) continue;
|
||||
enc.setForceMode(OpusMode.MODE_CELT_ONLY);
|
||||
enc.setForceChannels(2);
|
||||
}
|
||||
encoder_ptr = 0;
|
||||
int tot_size = 0;
|
||||
for (s = 0; s < this.layout.nb_streams; ++s) {
|
||||
int len;
|
||||
int c2;
|
||||
int c1;
|
||||
int i;
|
||||
rp.Reset();
|
||||
OpusEncoder enc = this.encoders[encoder_ptr];
|
||||
if (s < this.layout.nb_coupled_streams) {
|
||||
int left = OpusMultistream.get_left_channel(this.layout, s, -1);
|
||||
int right = OpusMultistream.get_right_channel(this.layout, s, -1);
|
||||
OpusMSEncoder.opus_copy_channel_in_short(buf, 0, 2, pcm, pcm_ptr, this.layout.nb_channels, left, frame_size);
|
||||
OpusMSEncoder.opus_copy_channel_in_short(buf, 1, 2, pcm, pcm_ptr, this.layout.nb_channels, right, frame_size);
|
||||
++encoder_ptr;
|
||||
if (this.surround != 0) {
|
||||
for (i = 0; i < 21; ++i) {
|
||||
bandLogE[i] = bandSMR[21 * left + i];
|
||||
bandLogE[21 + i] = bandSMR[21 * right + i];
|
||||
}
|
||||
}
|
||||
c1 = left;
|
||||
c2 = right;
|
||||
} else {
|
||||
int chan = OpusMultistream.get_mono_channel(this.layout, s, -1);
|
||||
OpusMSEncoder.opus_copy_channel_in_short(buf, 0, 1, pcm, pcm_ptr, this.layout.nb_channels, chan, frame_size);
|
||||
++encoder_ptr;
|
||||
if (this.surround != 0) {
|
||||
for (i = 0; i < 21; ++i) {
|
||||
bandLogE[i] = bandSMR[21 * chan + i];
|
||||
}
|
||||
}
|
||||
c1 = chan;
|
||||
c2 = -1;
|
||||
}
|
||||
if (this.surround != 0) {
|
||||
enc.SetEnergyMask(bandLogE);
|
||||
}
|
||||
int curr_max = max_data_bytes - tot_size;
|
||||
curr_max -= Inlines.IMAX(0, 2 * (this.layout.nb_streams - s - 1) - 1);
|
||||
curr_max = Inlines.IMIN(curr_max, 3832);
|
||||
if (s != this.layout.nb_streams - 1) {
|
||||
curr_max -= curr_max > 253 ? 2 : 1;
|
||||
}
|
||||
if (!vbr && s == this.layout.nb_streams - 1) {
|
||||
enc.setBitrate(curr_max * (8 * Fs / frame_size));
|
||||
}
|
||||
if ((len = enc.opus_encode_native(buf, 0, frame_size, tmp_data, 0, curr_max, lsb_depth, pcm, pcm_ptr, analysis_frame_size, c1, c2, this.layout.nb_channels, float_api)) < 0) {
|
||||
return len;
|
||||
}
|
||||
rp.addPacket(tmp_data, 0, len);
|
||||
len = rp.opus_repacketizer_out_range_impl(0, rp.getNumFrames(), data, data_ptr, max_data_bytes - tot_size, s != this.layout.nb_streams - 1 ? 1 : 0, !vbr && s == this.layout.nb_streams - 1 ? 1 : 0);
|
||||
data_ptr += len;
|
||||
tot_size += len;
|
||||
}
|
||||
return tot_size;
|
||||
}
|
||||
|
||||
static void opus_copy_channel_in_short(short[] dst, int dst_ptr, int dst_stride, short[] src, int src_ptr, int src_stride, int src_channel, int frame_size) {
|
||||
for (int i = 0; i < frame_size; ++i) {
|
||||
dst[dst_ptr + i * dst_stride] = src[i * src_stride + src_channel + src_ptr];
|
||||
}
|
||||
}
|
||||
|
||||
public int encodeMultistream(short[] pcm, int pcm_offset, int frame_size, byte[] outputBuffer, int outputBuffer_offset, int max_data_bytes) {
|
||||
return this.opus_multistream_encode_native(pcm, pcm_offset, frame_size, outputBuffer, outputBuffer_offset, max_data_bytes, 16, 0);
|
||||
}
|
||||
|
||||
public int getBitrate() {
|
||||
int value = 0;
|
||||
int encoder_ptr = 0;
|
||||
for (int s = 0; s < this.layout.nb_streams; ++s) {
|
||||
OpusEncoder enc = this.encoders[encoder_ptr++];
|
||||
value += enc.getBitrate();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setBitrate(int value) {
|
||||
if (value < 0 && value != -1000 && value != -1) {
|
||||
throw new IllegalArgumentException("Invalid bitrate");
|
||||
}
|
||||
this.bitrate_bps = value;
|
||||
}
|
||||
|
||||
public OpusApplication getApplication() {
|
||||
return this.encoders[0].getApplication();
|
||||
}
|
||||
|
||||
public void setApplication(OpusApplication value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setApplication(value);
|
||||
}
|
||||
}
|
||||
|
||||
public int getForceChannels() {
|
||||
return this.encoders[0].getForceChannels();
|
||||
}
|
||||
|
||||
public void setForceChannels(int value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setForceChannels(value);
|
||||
}
|
||||
}
|
||||
|
||||
public OpusBandwidth getMaxBandwidth() {
|
||||
return this.encoders[0].getMaxBandwidth();
|
||||
}
|
||||
|
||||
public void setMaxBandwidth(OpusBandwidth value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setMaxBandwidth(value);
|
||||
}
|
||||
}
|
||||
|
||||
public OpusBandwidth getBandwidth() {
|
||||
return this.encoders[0].getBandwidth();
|
||||
}
|
||||
|
||||
public void setBandwidth(OpusBandwidth value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setBandwidth(value);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getUseDTX() {
|
||||
return this.encoders[0].getUseDTX();
|
||||
}
|
||||
|
||||
public void setUseDTX(boolean value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setUseDTX(value);
|
||||
}
|
||||
}
|
||||
|
||||
public int getComplexity() {
|
||||
return this.encoders[0].getComplexity();
|
||||
}
|
||||
|
||||
public void setComplexity(int value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setComplexity(value);
|
||||
}
|
||||
}
|
||||
|
||||
public OpusMode getForceMode() {
|
||||
return this.encoders[0].getForceMode();
|
||||
}
|
||||
|
||||
public void setForceMode(OpusMode value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setForceMode(value);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getUseInbandFEC() {
|
||||
return this.encoders[0].getUseInbandFEC();
|
||||
}
|
||||
|
||||
public void setUseInbandFEC(boolean value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setUseInbandFEC(value);
|
||||
}
|
||||
}
|
||||
|
||||
public int getPacketLossPercent() {
|
||||
return this.encoders[0].getPacketLossPercent();
|
||||
}
|
||||
|
||||
public void setPacketLossPercent(int value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setPacketLossPercent(value);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getUseVBR() {
|
||||
return this.encoders[0].getUseVBR();
|
||||
}
|
||||
|
||||
public void setUseVBR(boolean value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setUseVBR(value);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getUseConstrainedVBR() {
|
||||
return this.encoders[0].getUseConstrainedVBR();
|
||||
}
|
||||
|
||||
public void setUseConstrainedVBR(boolean value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setUseConstrainedVBR(value);
|
||||
}
|
||||
}
|
||||
|
||||
public OpusSignal getSignalType() {
|
||||
return this.encoders[0].getSignalType();
|
||||
}
|
||||
|
||||
public void setSignalType(OpusSignal value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setSignalType(value);
|
||||
}
|
||||
}
|
||||
|
||||
public int getLookahead() {
|
||||
return this.encoders[0].getLookahead();
|
||||
}
|
||||
|
||||
public int getSampleRate() {
|
||||
return this.encoders[0].getSampleRate();
|
||||
}
|
||||
|
||||
public int getFinalRange() {
|
||||
int value = 0;
|
||||
int encoder_ptr = 0;
|
||||
for (int s = 0; s < this.layout.nb_streams; ++s) {
|
||||
value ^= this.encoders[encoder_ptr++].getFinalRange();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public int getLSBDepth() {
|
||||
return this.encoders[0].getLSBDepth();
|
||||
}
|
||||
|
||||
public void setLSBDepth(int value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setLSBDepth(value);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getPredictionDisabled() {
|
||||
return this.encoders[0].getPredictionDisabled();
|
||||
}
|
||||
|
||||
public void setPredictionDisabled(boolean value) {
|
||||
for (int encoder_ptr = 0; encoder_ptr < this.layout.nb_streams; ++encoder_ptr) {
|
||||
this.encoders[encoder_ptr].setPredictionDisabled(value);
|
||||
}
|
||||
}
|
||||
|
||||
public OpusFramesize getExpertFrameDuration() {
|
||||
return this.variable_duration;
|
||||
}
|
||||
|
||||
public void setExpertFrameDuration(OpusFramesize value) {
|
||||
this.variable_duration = value;
|
||||
}
|
||||
|
||||
public OpusEncoder getMultistreamEncoderState(int streamId) {
|
||||
if (streamId >= this.layout.nb_streams) {
|
||||
throw new IllegalArgumentException("Requested stream doesn't exist");
|
||||
}
|
||||
return this.encoders[streamId];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user