Luski.Net/Luski.net/Sound/JitterBuffer.cs

125 lines
3.7 KiB
C#
Raw Normal View History

2023-01-01 22:50:39 -05:00
using System;
using System.Collections.Generic;
namespace Luski.net.Sound
{
internal class JitterBuffer
{
internal JitterBuffer(object? sender, uint maxRTPPackets, uint timerIntervalInMilliseconds)
{
if (maxRTPPackets < 2)
{
throw new Exception("Wrong Arguments. Minimum maxRTPPackets is 2");
}
m_Sender = sender;
Maximum = maxRTPPackets;
IntervalInMilliseconds = timerIntervalInMilliseconds;
Init();
}
private readonly object? m_Sender = null;
private readonly EventTimer m_Timer = new();
private readonly Queue<RTPPacket> m_Buffer = new();
private RTPPacket m_LastRTPPacket = new();
private bool m_Underflow = true;
private bool m_Overflow = false;
internal delegate void DelegateDataAvailable(object sender, RTPPacket packet);
internal event DelegateDataAvailable? DataAvailable;
internal uint Maximum { get; } = 10;
internal uint IntervalInMilliseconds { get; } = 20;
private void Init()
{
InitTimer();
}
private void InitTimer()
{
m_Timer.TimerTick += new EventTimer.DelegateTimerTick(OnTimerTick);
}
internal void Start()
{
m_Timer.Start(IntervalInMilliseconds);
m_Underflow = true;
}
internal void Stop()
{
m_Timer.Stop();
m_Buffer.Clear();
}
private void OnTimerTick()
{
try
{
if (DataAvailable != null)
{
if (m_Buffer.Count > 0)
{
if (m_Overflow)
{
if (m_Buffer.Count <= Maximum / 2)
{
m_Overflow = false;
}
}
if (m_Underflow)
{
if (m_Buffer.Count < Maximum / 2)
{
return;
}
else
{
m_Underflow = false;
}
}
m_LastRTPPacket = m_Buffer.Dequeue();
DataAvailable(m_Sender, m_LastRTPPacket);
}
else
{
m_Overflow = false;
if (m_LastRTPPacket != null && m_Underflow == false)
{
if (m_LastRTPPacket.Data != null)
{
m_Underflow = true;
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(string.Format("JitterBuffer.cs | OnTimerTick() | {0}", ex.Message));
}
}
internal void AddData(RTPPacket packet)
{
try
{
if (m_Overflow == false)
{
if (m_Buffer.Count <= Maximum)
{
m_Buffer.Enqueue(packet);
}
else
{
m_Overflow = true;
}
}
}
catch (Exception ex)
{
Console.WriteLine(string.Format("JitterBuffer.cs | AddData() | {0}", ex.Message));
}
}
}
}