diff --git a/MumbleSharp/Audio/AudioDecodingBuffer.cs b/MumbleSharp/Audio/AudioDecodingBuffer.cs index 2c47794..279e23d 100644 --- a/MumbleSharp/Audio/AudioDecodingBuffer.cs +++ b/MumbleSharp/Audio/AudioDecodingBuffer.cs @@ -35,30 +35,55 @@ public AudioDecodingBuffer(int sampleRate = Constants.DEFAULT_AUDIO_SAMPLE_RATE, } private long _nextSequenceToDecode; - private readonly List _encodedBuffer = new List(); - + private readonly List _encodedBuffer = new List(); + private IVoiceCodec _codec; - public int Read(byte[] buffer, int offset, int count) - { - int readCount = 0; - while (readCount < count) - { - readCount += ReadFromBuffer(buffer, offset + readCount, count - readCount); - - //Try to decode some more data into the buffer - if (!FillBuffer()) - break; - } + /// + /// The time, in milliseconds, for the jitter buffer to delay when network data is exhausted. Only updates internally when jitter is detected. + /// + public TimeSpan JitterDelay { get; set; } = TimeSpan.FromMilliseconds(350f); - if (readCount == 0) - { - //Return silence - Array.Clear(buffer, 0, buffer.Length); - return count; - } + private bool isJitterDetected; + private bool isJitterTimerRunning; + private DateTime jitterTimer = DateTime.UtcNow; + private double jitterMillis = 350f; - return readCount; + public int Read(byte[] buffer, int offset, int count) + { + int readCount = 0; + + if (isJitterTimerRunning && ((DateTime.UtcNow - jitterTimer).TotalMilliseconds > jitterMillis)) + { + isJitterDetected = false; + isJitterTimerRunning = false; + } + + if (!isJitterDetected) + { + while (readCount < count) + { + readCount += ReadFromBuffer(buffer, offset + readCount, count - readCount); + + if (readCount == 0) + { + isJitterDetected = true; + } + + //Try to decode some more data into the buffer + if (!FillBuffer()) + break; + } + } + + if (readCount == 0) + { + //Return silence + Array.Clear(buffer, 0, count); + return count; + } + + return readCount; } /// @@ -68,8 +93,15 @@ public int Read(byte[] buffer, int offset, int count) /// The encoded audio packet /// The codec to use to decode this packet public void AddEncodedPacket(long sequence, byte[] data, IVoiceCodec codec) - { - if(sequence == 0) + { + if (isJitterDetected && !isJitterTimerRunning) + { + jitterTimer = DateTime.UtcNow; + jitterMillis = JitterDelay.TotalMilliseconds; + isJitterTimerRunning = true; + } + + if (sequence == 0) _nextSequenceToDecode = 0; if (_codec == null) @@ -81,7 +113,8 @@ public void AddEncodedPacket(long sequence, byte[] data, IVoiceCodec codec) if (_nextSequenceToDecode > sequence) return; - _encodedBuffer.Add(new BufferPacket { + _encodedBuffer.Add(new BufferPacket + { Data = data, Sequence = sequence });