Files
AsminVoicechat/source/decompiled/de/maxhenkel/voicechat/concentus/OpusMSDecoder.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

236 lines
9.4 KiB
Java

/*
* Decompiled with CFR 0.152.
*/
package de.maxhenkel.voicechat.concentus;
import de.maxhenkel.voicechat.concentus.BoxedValueByte;
import de.maxhenkel.voicechat.concentus.BoxedValueInt;
import de.maxhenkel.voicechat.concentus.ChannelLayout;
import de.maxhenkel.voicechat.concentus.Inlines;
import de.maxhenkel.voicechat.concentus.OpusBandwidth;
import de.maxhenkel.voicechat.concentus.OpusDecoder;
import de.maxhenkel.voicechat.concentus.OpusError;
import de.maxhenkel.voicechat.concentus.OpusException;
import de.maxhenkel.voicechat.concentus.OpusMultistream;
import de.maxhenkel.voicechat.concentus.OpusPacketInfo;
public class OpusMSDecoder {
ChannelLayout layout = new ChannelLayout();
OpusDecoder[] decoders = null;
private OpusMSDecoder(int nb_streams, int nb_coupled_streams) {
this.decoders = new OpusDecoder[nb_streams];
for (int c = 0; c < nb_streams; ++c) {
this.decoders[c] = new OpusDecoder();
}
}
int opus_multistream_decoder_init(int Fs, int channels, int streams, int coupled_streams, short[] mapping) {
int ret;
int i;
int decoder_ptr = 0;
if (channels > 255 || channels < 1 || coupled_streams > streams || streams < 1 || coupled_streams < 0 || streams > 255 - coupled_streams) {
throw new IllegalArgumentException("Invalid channel or coupled stream count");
}
this.layout.nb_channels = channels;
this.layout.nb_streams = streams;
this.layout.nb_coupled_streams = coupled_streams;
for (i = 0; i < this.layout.nb_channels; ++i) {
this.layout.mapping[i] = mapping[i];
}
if (OpusMultistream.validate_layout(this.layout) == 0) {
throw new IllegalArgumentException("Invalid surround channel layout");
}
for (i = 0; i < this.layout.nb_coupled_streams; ++i) {
ret = this.decoders[decoder_ptr].opus_decoder_init(Fs, 2);
if (ret != OpusError.OPUS_OK) {
return ret;
}
++decoder_ptr;
}
while (i < this.layout.nb_streams) {
ret = this.decoders[decoder_ptr].opus_decoder_init(Fs, 1);
if (ret != OpusError.OPUS_OK) {
return ret;
}
++decoder_ptr;
++i;
}
return OpusError.OPUS_OK;
}
public static OpusMSDecoder create(int Fs, int channels, int streams, int coupled_streams, short[] mapping) 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");
}
OpusMSDecoder st = new OpusMSDecoder(streams, coupled_streams);
int ret = st.opus_multistream_decoder_init(Fs, channels, streams, coupled_streams, mapping);
if (ret != OpusError.OPUS_OK) {
if (ret == OpusError.OPUS_BAD_ARG) {
throw new IllegalArgumentException("Bad argument while creating MS decoder");
}
throw new OpusException("Could not create MS decoder", ret);
}
return st;
}
static int opus_multistream_packet_validate(byte[] data, int data_ptr, int len, int nb_streams, int Fs) {
BoxedValueByte toc = new BoxedValueByte(0);
short[] size = new short[48];
int samples = 0;
BoxedValueInt packet_offset = new BoxedValueInt(0);
BoxedValueInt dummy = new BoxedValueInt(0);
for (int s = 0; s < nb_streams; ++s) {
if (len <= 0) {
return OpusError.OPUS_INVALID_PACKET;
}
int count = OpusPacketInfo.opus_packet_parse_impl(data, data_ptr, len, s != nb_streams - 1 ? 1 : 0, toc, null, 0, size, 0, dummy, packet_offset);
if (count < 0) {
return count;
}
int tmp_samples = OpusPacketInfo.getNumSamples(data, data_ptr, packet_offset.Val, Fs);
if (s != 0 && samples != tmp_samples) {
return OpusError.OPUS_INVALID_PACKET;
}
samples = tmp_samples;
data_ptr += packet_offset.Val;
len -= packet_offset.Val;
}
return samples;
}
int opus_multistream_decode_native(byte[] data, int data_ptr, int len, short[] pcm, int pcm_ptr, int frame_size, int decode_fec, int soft_clip) {
boolean do_plc = false;
int Fs = this.getSampleRate();
frame_size = Inlines.IMIN(frame_size, Fs / 25 * 3);
short[] buf = new short[2 * frame_size];
int decoder_ptr = 0;
if (len == 0) {
do_plc = true;
}
if (len < 0) {
return OpusError.OPUS_BAD_ARG;
}
if (!do_plc && len < 2 * this.layout.nb_streams - 1) {
return OpusError.OPUS_INVALID_PACKET;
}
if (!do_plc) {
int ret = OpusMSDecoder.opus_multistream_packet_validate(data, data_ptr, len, this.layout.nb_streams, Fs);
if (ret < 0) {
return ret;
}
if (ret > frame_size) {
return OpusError.OPUS_BUFFER_TOO_SMALL;
}
}
for (int s = 0; s < this.layout.nb_streams; ++s) {
int chan;
int prev;
OpusDecoder dec = this.decoders[decoder_ptr++];
if (!do_plc && len <= 0) {
return OpusError.OPUS_INTERNAL_ERROR;
}
BoxedValueInt packet_offset = new BoxedValueInt(0);
int ret = dec.opus_decode_native(data, data_ptr, len, buf, 0, frame_size, decode_fec, s != this.layout.nb_streams - 1 ? 1 : 0, packet_offset, soft_clip);
data_ptr += packet_offset.Val;
len -= packet_offset.Val;
if (ret <= 0) {
return ret;
}
frame_size = ret;
if (s < this.layout.nb_coupled_streams) {
prev = -1;
while ((chan = OpusMultistream.get_left_channel(this.layout, s, prev)) != -1) {
OpusMSDecoder.opus_copy_channel_out_short(pcm, pcm_ptr, this.layout.nb_channels, chan, buf, 0, 2, frame_size);
prev = chan;
}
prev = -1;
while ((chan = OpusMultistream.get_right_channel(this.layout, s, prev)) != -1) {
OpusMSDecoder.opus_copy_channel_out_short(pcm, pcm_ptr, this.layout.nb_channels, chan, buf, 1, 2, frame_size);
prev = chan;
}
continue;
}
prev = -1;
while ((chan = OpusMultistream.get_mono_channel(this.layout, s, prev)) != -1) {
OpusMSDecoder.opus_copy_channel_out_short(pcm, pcm_ptr, this.layout.nb_channels, chan, buf, 0, 1, frame_size);
prev = chan;
}
}
for (int c = 0; c < this.layout.nb_channels; ++c) {
if (this.layout.mapping[c] != 255) continue;
OpusMSDecoder.opus_copy_channel_out_short(pcm, pcm_ptr, this.layout.nb_channels, c, null, 0, 0, frame_size);
}
return frame_size;
}
static void opus_copy_channel_out_short(short[] dst, int dst_ptr, int dst_stride, int dst_channel, short[] src, int src_ptr, int src_stride, int frame_size) {
if (src != null) {
for (int i = 0; i < frame_size; ++i) {
dst[i * dst_stride + dst_channel + dst_ptr] = src[i * src_stride + src_ptr];
}
} else {
for (int i = 0; i < frame_size; ++i) {
dst[i * dst_stride + dst_channel + dst_ptr] = 0;
}
}
}
public int decodeMultistream(byte[] data, int data_offset, int len, short[] out_pcm, int out_pcm_offset, int frame_size, int decode_fec) {
return this.opus_multistream_decode_native(data, data_offset, len, out_pcm, out_pcm_offset, frame_size, decode_fec, 0);
}
public OpusBandwidth getBandwidth() {
if (this.decoders == null || this.decoders.length == 0) {
throw new IllegalStateException("Decoder not initialized");
}
return this.decoders[0].getBandwidth();
}
public int getSampleRate() {
if (this.decoders == null || this.decoders.length == 0) {
throw new IllegalStateException("Decoder not initialized");
}
return this.decoders[0].getSampleRate();
}
public int getGain() {
if (this.decoders == null || this.decoders.length == 0) {
throw new IllegalStateException("Decoder not initialized");
}
return this.decoders[0].getGain();
}
public void setGain(int value) {
for (int s = 0; s < this.layout.nb_streams; ++s) {
this.decoders[s].setGain(value);
}
}
public int getLastPacketDuration() {
if (this.decoders == null || this.decoders.length == 0) {
return OpusError.OPUS_INVALID_STATE;
}
return this.decoders[0].getLastPacketDuration();
}
public int getFinalRange() {
int value = 0;
for (int s = 0; s < this.layout.nb_streams; ++s) {
value ^= this.decoders[s].getFinalRange();
}
return value;
}
public void ResetState() {
for (int s = 0; s < this.layout.nb_streams; ++s) {
this.decoders[s].resetState();
}
}
public OpusDecoder GetMultistreamDecoderState(int streamId) {
return this.decoders[streamId];
}
}