Send every ready live-capture frame per tick and cap the timer's catch-up burst
A mic running faster than the 20 ms timer filled the queue until frames were dropped; live sources now drain each tick. The catch-up clamp was inverted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,15 @@ public interface Microphone {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether {@link #provide} hands out frames captured on a clock of their own, such as a sound
|
||||
* card's. That clock drifts against the send timer, so each tick then sends every frame that is
|
||||
* ready instead of one, keeping the drift from piling up as latency or overflowing a queue.
|
||||
*/
|
||||
default boolean isLiveCapture() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** How many copies follow each voice packet, {@link #getRedundancyDelay} apart. */
|
||||
default int getRedundancyCopies() {
|
||||
return 1;
|
||||
|
||||
+8
-3
@@ -596,6 +596,7 @@ public class LocalTeamspeakClientSocket
|
||||
new MicrophoneTask()
|
||||
);
|
||||
microphoneThread.setDaemon(true);
|
||||
microphoneThread.setPriority(Thread.MAX_PRIORITY);
|
||||
|
||||
if (getState() != ClientConnectionState.DISCONNECTED)
|
||||
microphoneThread.start();
|
||||
@@ -693,9 +694,11 @@ public class LocalTeamspeakClientSocket
|
||||
// TODO
|
||||
// Set a state and send a muted event
|
||||
} else if (microphone.isReady()) {
|
||||
byte[] data = microphone.provide();
|
||||
if (data.length <= 0)
|
||||
return;
|
||||
boolean live = microphone.isLiveCapture();
|
||||
byte[] data;
|
||||
do {
|
||||
data = microphone.provide();
|
||||
if (data.length <= 0) break;
|
||||
|
||||
PacketBody0Voice voice = new PacketBody0Voice(getRole().getOut());
|
||||
|
||||
@@ -712,7 +715,9 @@ public class LocalTeamspeakClientSocket
|
||||
// All we are really concerned about here is a disconnection event, in which case the loop
|
||||
// will exit.
|
||||
getExceptionHandler().accept(e);
|
||||
return;
|
||||
}
|
||||
} while (live && microphone.isReady());
|
||||
} else if (wasSendingAudio) {
|
||||
PacketBody0Voice voice = new PacketBody0Voice(getRole().getOut());
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ public class HighPrecisionTimer extends Thread {
|
||||
|
||||
now = System.nanoTime();
|
||||
|
||||
// Clamp the next target to the maximum "drift" allowed
|
||||
if (nextTarget - now > maximumDriftInNanos)
|
||||
// After a stall, catch up at most the allowed number of ticks rather than all of them
|
||||
if (now - nextTarget > maximumDriftInNanos)
|
||||
nextTarget = now - maximumDriftInNanos;
|
||||
|
||||
if (sleepFor(nextTarget - now)) {
|
||||
|
||||
Reference in New Issue
Block a user