diff --git a/ts3-client/core/src/main/java/com/ts3client/audio/CaptureVoiceInput.java b/ts3-client/core/src/main/java/com/ts3client/audio/CaptureVoiceInput.java index df08660..584b981 100644 --- a/ts3-client/core/src/main/java/com/ts3client/audio/CaptureVoiceInput.java +++ b/ts3-client/core/src/main/java/com/ts3client/audio/CaptureVoiceInput.java @@ -76,7 +76,7 @@ public final class CaptureVoiceInput implements VoiceInput { private final AudioIo io; private final OpusCodec opus; - private final String deviceName; + private volatile String deviceName; private final Object encoderLock = new Object(); private volatile OpusParameters params; @@ -117,6 +117,17 @@ public final class CaptureVoiceInput implements VoiceInput { // ---- live configuration (safe to call from the UI thread) ---- + @Override + public synchronized void setInputDevice(String deviceId) { + String device = deviceId == null ? "" : deviceId; + if (device.equals(deviceName)) return; + deviceName = device; + if (running.get()) { + stop(); + start(); + } + } + public void setMode(Settings.InputMode mode) { this.mode = mode; } diff --git a/ts3-client/core/src/main/java/com/ts3client/audio/MixedPlayout.java b/ts3-client/core/src/main/java/com/ts3client/audio/MixedPlayout.java index fa2ebdb..81ef5c2 100644 --- a/ts3-client/core/src/main/java/com/ts3client/audio/MixedPlayout.java +++ b/ts3-client/core/src/main/java/com/ts3client/audio/MixedPlayout.java @@ -66,9 +66,15 @@ final class MixedPlayout implements Playout { float[] mix = null; float[] scratch = null; byte[] out = null; + String device = null; while (awaitSpeech()) { + if (line != null && !device.equals(outputDevice.get())) { + line.close(); + line = null; + } if (line == null) { - line = io.openPlayback(outputDevice.get(), VoiceFormat.MAX_CHANNELS); + device = outputDevice.get(); + line = io.openPlayback(device, VoiceFormat.MAX_CHANNELS); line.start(); channels = line.channels(); mix = new float[FRAME * channels]; diff --git a/ts3-client/core/src/main/java/com/ts3client/audio/StreamingVoiceOutput.java b/ts3-client/core/src/main/java/com/ts3client/audio/StreamingVoiceOutput.java index bf69fe9..ff97e80 100644 --- a/ts3-client/core/src/main/java/com/ts3client/audio/StreamingVoiceOutput.java +++ b/ts3-client/core/src/main/java/com/ts3client/audio/StreamingVoiceOutput.java @@ -60,7 +60,7 @@ public final class StreamingVoiceOutput implements VoiceOutput { public StreamingVoiceOutput(AudioIo io, OpusCodec opus, String outputDevice, Lines lines) { this.opus = opus; - this.outputDevice = outputDevice; + this.outputDevice = outputDevice == null ? "" : outputDevice; this.playout = switch (lines) { case PER_SPEAKER -> new PerSpeakerPlayout(io, () -> this.outputDevice, this::gainFor, clock); case SHARED -> new MixedPlayout(io, () -> this.outputDevice, this::gainFor, streams.values()); @@ -137,7 +137,7 @@ public final class StreamingVoiceOutput implements VoiceOutput { @Override public void setOutputDevice(String device) { - this.outputDevice = device; + this.outputDevice = device == null ? "" : device; } /** Entry point wired into {@code client.setVoiceHandler(...)}. */ diff --git a/ts3-client/core/src/main/java/com/ts3client/audio/VoiceInput.java b/ts3-client/core/src/main/java/com/ts3client/audio/VoiceInput.java index 48b3fcd..83c963f 100644 --- a/ts3-client/core/src/main/java/com/ts3client/audio/VoiceInput.java +++ b/ts3-client/core/src/main/java/com/ts3client/audio/VoiceInput.java @@ -27,6 +27,9 @@ public interface VoiceInput extends Microphone { boolean isLocalMuted(); + /** Moves capture to another device, reopening at once if capturing; empty is the default. */ + void setInputDevice(String deviceId); + void setMode(Settings.InputMode mode); void setVadMode(Settings.VadMode mode); @@ -80,6 +83,7 @@ public interface VoiceInput extends Microphone { /** Takes on the voice settings, as they stand now, while capturing. */ default void apply(Settings settings) { + setInputDevice(settings.inputDevice); setMode(settings.inputMode); setVadMode(settings.vadMode); setThresholdDb(settings.vadThresholdDb);