Clamp high precision timer to specific tick drift
This commit is contained in:
+3
-3
@@ -24,7 +24,7 @@ import com.github.manevolent.ts3j.protocol.packet.handler.client.LocalClientHand
|
||||
import com.github.manevolent.ts3j.protocol.packet.handler.client.LocalClientHandlerRetrievingData;
|
||||
import com.github.manevolent.ts3j.protocol.packet.statistics.PacketStatistics;
|
||||
import com.github.manevolent.ts3j.protocol.packet.transformation.InitPacketTransformation;
|
||||
import com.github.manevolent.ts3j.util.HighPrecisionRecurrentTask;
|
||||
import com.github.manevolent.ts3j.util.HighPrecisionTimer;
|
||||
import com.github.manevolent.ts3j.util.Ts3Debugging;
|
||||
import com.github.manevolent.ts3j.util.Pair;
|
||||
|
||||
@@ -387,9 +387,9 @@ public class LocalTeamspeakClientSocket
|
||||
|
||||
waitForState(ClientConnectionState.CONNECTED, timeout);
|
||||
|
||||
microphoneThread = new HighPrecisionRecurrentTask(
|
||||
microphoneThread = new HighPrecisionTimer(
|
||||
20,
|
||||
0.01F,
|
||||
5F, // up to 100ms of drift/catchup
|
||||
new MicrophoneTask()
|
||||
);
|
||||
|
||||
|
||||
+34
-22
@@ -23,52 +23,60 @@ import java.util.concurrent.locks.LockSupport;
|
||||
*
|
||||
* Time of execution is held in account when calculating the time to sleep until the next execution.
|
||||
*/
|
||||
public class HighPrecisionRecurrentTask extends Thread {
|
||||
|
||||
public class HighPrecisionTimer extends Thread {
|
||||
private final int periodInNanos;
|
||||
private final int spinningTimeNanos;
|
||||
private final int maximumDriftInNanos;
|
||||
private final Runnable target;
|
||||
private volatile boolean stop;
|
||||
|
||||
/**
|
||||
* @param periodInMilis The period in milliseconds of the task execution.
|
||||
* @param percentageOfSleepSpinning The percentage of total sleeping that should be done spinning to increase accuracy.
|
||||
* @param catchupTicks The number of ticks allowed to consecutively catch up to
|
||||
* @param target The task to run.
|
||||
*/
|
||||
public HighPrecisionRecurrentTask(int periodInMilis, float percentageOfSleepSpinning, Runnable target) {
|
||||
public HighPrecisionTimer(int periodInMilis,
|
||||
float catchupTicks,
|
||||
Runnable target) {
|
||||
super("TS3J AudioThread");
|
||||
if (percentageOfSleepSpinning < 0 || percentageOfSleepSpinning > 1)
|
||||
throw new IllegalArgumentException("percentageOfSleepSpinning < 0 | percentageOfSleepSpinning > 1");
|
||||
|
||||
this.periodInNanos = periodInMilis * 1_000_000;
|
||||
this.spinningTimeNanos = (int) (periodInNanos * percentageOfSleepSpinning);
|
||||
this.maximumDriftInNanos = (int) Math.floor((double)periodInNanos * (double)catchupTicks);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public boolean isStop() {
|
||||
return stop;
|
||||
}
|
||||
|
||||
public void setStop(boolean stop) {
|
||||
this.stop = stop;
|
||||
public void gracefulStop() {
|
||||
if (!this.stop) {
|
||||
this.stop = true;
|
||||
//if (isAlive()) interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings(value = "empty-statement")
|
||||
public void run() {
|
||||
long nextTarget = 0;
|
||||
long now = System.nanoTime();
|
||||
long nextTarget = now;
|
||||
|
||||
while (!stop) {
|
||||
long now = System.nanoTime();
|
||||
target.run();
|
||||
long total = System.nanoTime() - now;
|
||||
nextTarget = now + periodInNanos - total;
|
||||
sleepFor(periodInNanos - total - spinningTimeNanos);
|
||||
while (nextTarget > System.nanoTime()) {
|
||||
; //consume cycles
|
||||
|
||||
nextTarget += periodInNanos;
|
||||
|
||||
now = System.nanoTime();
|
||||
|
||||
// Clamp the next target to the maximum "drift" allowed
|
||||
if (nextTarget - now > maximumDriftInNanos)
|
||||
nextTarget = now - maximumDriftInNanos;
|
||||
|
||||
if (sleepFor(nextTarget - now)) {
|
||||
while (nextTarget > System.nanoTime()) {
|
||||
; //consume cycles
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sleepFor(long nanos) {
|
||||
private boolean sleepFor(long nanos) {
|
||||
if (nanos > 0) {
|
||||
long elapsed = 0;
|
||||
while (elapsed < nanos) {
|
||||
@@ -76,7 +84,11 @@ public class HighPrecisionRecurrentTask extends Thread {
|
||||
LockSupport.parkNanos(nanos - elapsed);
|
||||
elapsed += System.nanoTime() - t0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user