diff --git a/ts3-client/core/src/main/java/com/ts3client/audio/opus/CtlOpusEncoder.java b/ts3-client/core/src/main/java/com/ts3client/audio/opus/CtlOpusEncoder.java new file mode 100644 index 0000000..703f230 --- /dev/null +++ b/ts3-client/core/src/main/java/com/ts3client/audio/opus/CtlOpusEncoder.java @@ -0,0 +1,38 @@ +package com.ts3client.audio.opus; + +/** An {@link OpusEncoder} configured through libopus' own controls; a binding supplies {@link #ctl}. */ +public abstract class CtlOpusEncoder implements OpusEncoder { + + /** Calls {@code opus_encoder_ctl(encoder, request, value)}. */ + protected abstract void ctl(int request, int value); + + @Override + public void setBitrate(int bitsPerSecond) { + ctl(LibOpus.SET_BITRATE_REQUEST, bitsPerSecond); + } + + @Override + public void setComplexity(int complexity) { + ctl(LibOpus.SET_COMPLEXITY_REQUEST, Math.max(0, Math.min(10, complexity))); + } + + @Override + public void setVbr(boolean vbr) { + ctl(LibOpus.SET_VBR_REQUEST, vbr ? 1 : 0); + } + + @Override + public void setInbandFec(boolean fec) { + ctl(LibOpus.SET_INBAND_FEC_REQUEST, fec ? 1 : 0); + } + + @Override + public void setExpectedPacketLoss(int percent) { + ctl(LibOpus.SET_PACKET_LOSS_PERC_REQUEST, Math.max(0, Math.min(100, percent))); + } + + @Override + public void setSignal(Signal signal) { + ctl(LibOpus.SET_SIGNAL_REQUEST, signal == Signal.MUSIC ? LibOpus.SIGNAL_MUSIC : LibOpus.SIGNAL_VOICE); + } +} diff --git a/ts3-client/core/src/main/java/com/ts3client/audio/opus/LibOpus.java b/ts3-client/core/src/main/java/com/ts3client/audio/opus/LibOpus.java new file mode 100644 index 0000000..0cdcda0 --- /dev/null +++ b/ts3-client/core/src/main/java/com/ts3client/audio/opus/LibOpus.java @@ -0,0 +1,26 @@ +package com.ts3client.audio.opus; + +/** libopus' numeric constants (opus_defines.h), shared by every binding of it. */ +public final class LibOpus { + + public static final int APPLICATION_VOIP = 2048; + public static final int APPLICATION_AUDIO = 2049; + + public static final int SET_BITRATE_REQUEST = 4002; + public static final int SET_VBR_REQUEST = 4006; + public static final int SET_COMPLEXITY_REQUEST = 4010; + public static final int SET_INBAND_FEC_REQUEST = 4012; + public static final int SET_PACKET_LOSS_PERC_REQUEST = 4014; + public static final int SET_SIGNAL_REQUEST = 4024; + public static final int RESET_STATE = 4028; + + public static final int SIGNAL_VOICE = 3001; + public static final int SIGNAL_MUSIC = 3002; + + private LibOpus() { + } + + public static int application(OpusCodec.Application application) { + return application == OpusCodec.Application.AUDIO ? APPLICATION_AUDIO : APPLICATION_VOIP; + } +} diff --git a/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/NativeOpusCodec.java b/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/NativeOpusCodec.java index 143c851..4bf2674 100644 --- a/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/NativeOpusCodec.java +++ b/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/NativeOpusCodec.java @@ -1,5 +1,6 @@ package com.ts3client.audio.desktop; +import com.ts3client.audio.opus.LibOpus; import com.ts3client.audio.opus.OpusCodec; import com.ts3client.audio.opus.OpusDecoder; import com.ts3client.audio.opus.OpusEncoder; @@ -9,8 +10,7 @@ public final class NativeOpusCodec implements OpusCodec { @Override public OpusEncoder createEncoder(int sampleRate, int frameSize, int channels, Application application) { - int app = application == Application.AUDIO ? Opus.OPUS_APPLICATION_AUDIO : Opus.OPUS_APPLICATION_VOIP; - return new NativeOpusEncoder(sampleRate, frameSize, channels, app); + return new NativeOpusEncoder(sampleRate, frameSize, channels, LibOpus.application(application)); } @Override diff --git a/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/NativeOpusDecoder.java b/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/NativeOpusDecoder.java index de3dd5a..1954bc8 100644 --- a/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/NativeOpusDecoder.java +++ b/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/NativeOpusDecoder.java @@ -1,5 +1,6 @@ package com.ts3client.audio.desktop; +import com.ts3client.audio.opus.LibOpus; import com.ts3client.audio.opus.OpusDecoder; import java.lang.foreign.Arena; @@ -74,7 +75,7 @@ final class NativeOpusDecoder implements OpusDecoder { @Override public void reset() { if (closed) return; - Opus.decoderCtl(handle, Opus.OPUS_RESET_STATE, 0); + Opus.decoderCtl(handle, LibOpus.RESET_STATE, 0); } @Override diff --git a/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/NativeOpusEncoder.java b/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/NativeOpusEncoder.java index d0fe712..959f62a 100644 --- a/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/NativeOpusEncoder.java +++ b/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/NativeOpusEncoder.java @@ -1,6 +1,6 @@ package com.ts3client.audio.desktop; -import com.ts3client.audio.opus.OpusEncoder; +import com.ts3client.audio.opus.CtlOpusEncoder; import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; @@ -16,7 +16,7 @@ import java.lang.foreign.ValueLayout; * are freed by {@link #close()}; access is serialised by the instance lock, so the * encoder may be driven from any thread. */ -final class NativeOpusEncoder implements OpusEncoder { +final class NativeOpusEncoder extends CtlOpusEncoder { private static final int MAX_PACKET_BYTES = 4096; @@ -47,36 +47,7 @@ final class NativeOpusEncoder implements OpusEncoder { } @Override - public void setBitrate(int bitsPerSecond) { - ctl(Opus.OPUS_SET_BITRATE_REQUEST, bitsPerSecond); - } - - @Override - public void setComplexity(int complexity) { - ctl(Opus.OPUS_SET_COMPLEXITY_REQUEST, Math.max(0, Math.min(10, complexity))); - } - - @Override - public void setVbr(boolean vbr) { - ctl(Opus.OPUS_SET_VBR_REQUEST, vbr ? 1 : 0); - } - - @Override - public void setInbandFec(boolean fec) { - ctl(Opus.OPUS_SET_INBAND_FEC_REQUEST, fec ? 1 : 0); - } - - @Override - public void setExpectedPacketLoss(int percent) { - ctl(Opus.OPUS_SET_PACKET_LOSS_PERC_REQUEST, Math.max(0, Math.min(100, percent))); - } - - @Override - public void setSignal(Signal signal) { - ctl(Opus.OPUS_SET_SIGNAL_REQUEST, signal == Signal.MUSIC ? Opus.OPUS_SIGNAL_MUSIC : Opus.OPUS_SIGNAL_VOICE); - } - - private void ctl(int request, int value) { + protected void ctl(int request, int value) { synchronized (lock) { if (closed) return; int r = Opus.encoderCtl(handle, request, value); diff --git a/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/Opus.java b/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/Opus.java index 9a9f8e6..4dfb692 100644 --- a/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/Opus.java +++ b/ts3-client/desktop/src/main/java/com/ts3client/audio/desktop/Opus.java @@ -30,25 +30,6 @@ public final class Opus { private Opus() { } - // ---- application types (opus_defines.h) ---- - public static final int OPUS_APPLICATION_VOIP = 2048; - public static final int OPUS_APPLICATION_AUDIO = 2049; - public static final int OPUS_APPLICATION_RESTRICTED_LOWDELAY = 2051; - - // ---- CTL request codes ---- - public static final int OPUS_SET_BITRATE_REQUEST = 4002; - public static final int OPUS_SET_VBR_REQUEST = 4006; - public static final int OPUS_SET_COMPLEXITY_REQUEST = 4010; - public static final int OPUS_SET_INBAND_FEC_REQUEST = 4012; - public static final int OPUS_SET_PACKET_LOSS_PERC_REQUEST = 4014; - public static final int OPUS_SET_SIGNAL_REQUEST = 4024; - public static final int OPUS_RESET_STATE = 4028; - - // ---- signal hints ---- - public static final int OPUS_AUTO = -1000; - public static final int OPUS_SIGNAL_VOICE = 3001; - public static final int OPUS_SIGNAL_MUSIC = 3002; - private static final ValueLayout.OfInt INT = ValueLayout.JAVA_INT; private static final java.lang.foreign.AddressLayout PTR = ValueLayout.ADDRESS;