149 lines
4.1 KiB
C#
149 lines
4.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace SipComponent
|
|
{
|
|
class VoiceBuffer2
|
|
{
|
|
ByteQueue _byteQueue;
|
|
int _maxSize;
|
|
object _lockerOnTake = new object();
|
|
object _lockerOnAdd = new object();
|
|
bool _addingWasStopped;
|
|
volatile bool _fireEventHalfFull = true;
|
|
|
|
public VoiceBuffer2(int maxSize)
|
|
{
|
|
_maxSize = maxSize;
|
|
_byteQueue = new ByteQueue();
|
|
}
|
|
|
|
/*
|
|
public int TakeBytes(byte[] b)
|
|
{
|
|
int nbObBytesTaken = 0;
|
|
int length = b.Length;
|
|
lock (_lockerOnTake)
|
|
{
|
|
while (_byteQueue.Length < length && !_addingWasStopped)
|
|
{
|
|
OnEmpty(new EventArgs());
|
|
Monitor.Wait(_lockerOnTake);
|
|
}
|
|
if (_addingWasStopped)
|
|
return nbObBytesTaken;
|
|
}
|
|
nbObBytesTaken = _byteQueue.Dequeue(b, 0, length);
|
|
// Notify that adding can unblock
|
|
lock (_lockerOnAdd)
|
|
Monitor.Pulse(_lockerOnAdd);
|
|
#if DEBUG
|
|
//Console.WriteLine(_byteQueue.Length);
|
|
#endif
|
|
return nbObBytesTaken;
|
|
}
|
|
*/
|
|
|
|
public int TakeBytes(byte[] b)
|
|
{
|
|
int nbObBytesTaken = 0;
|
|
int length = b.Length;
|
|
lock (_lockerOnTake)
|
|
{
|
|
while (_byteQueue.Length < length && !_addingWasStopped)
|
|
{
|
|
OnEmpty(new EventArgs());
|
|
Monitor.Wait(_lockerOnTake);
|
|
}
|
|
//if (_addingWasStopped)
|
|
// return nbObBytesTaken;
|
|
}
|
|
nbObBytesTaken = _byteQueue.Dequeue(b, 0, length);
|
|
// Notify that adding can unblock
|
|
lock (_lockerOnAdd)
|
|
Monitor.Pulse(_lockerOnAdd);
|
|
//#if DEBUG
|
|
// Console.WriteLine(_byteQueue.Length);
|
|
//#endif
|
|
return nbObBytesTaken;
|
|
}
|
|
|
|
public void AddBytes(byte[] b)
|
|
{
|
|
int length = b.Length;
|
|
lock (_lockerOnAdd)
|
|
{
|
|
if (_addingWasStopped)
|
|
throw new SipClassException("Cannot add bytes to VoiceBuffer after calling StopAdding() method!");
|
|
while (_byteQueue.Length + length > _maxSize)
|
|
{
|
|
OnFull(new EventArgs());
|
|
Monitor.Wait(_lockerOnAdd);
|
|
}
|
|
}
|
|
_byteQueue.Enqueue(b, 0, b.Length);
|
|
// Notify that taking thread can unblock
|
|
lock (_lockerOnTake)
|
|
{
|
|
Monitor.Pulse(_lockerOnTake);
|
|
}
|
|
if (_fireEventHalfFull)
|
|
{
|
|
if (_byteQueue.Length >= _maxSize / 2)
|
|
{
|
|
OnHalfFull(new EventArgs());
|
|
_fireEventHalfFull = false;
|
|
|
|
}
|
|
}
|
|
//#if DEBUG
|
|
// Console.WriteLine(_byteQueue.Length);
|
|
//#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// Notifies the taking thread that adding was stopped and must continue
|
|
/// </summary>
|
|
public void StopAdding()
|
|
{
|
|
lock (_lockerOnTake)
|
|
{
|
|
_addingWasStopped = true;
|
|
Monitor.PulseAll(_lockerOnTake);
|
|
}
|
|
}
|
|
|
|
#region Events
|
|
|
|
public event EventHandler HalfFull;
|
|
public event EventHandler Full;
|
|
public event EventHandler Empty;
|
|
|
|
|
|
public void OnHalfFull(EventArgs e)
|
|
{
|
|
EventHandler handler = HalfFull;
|
|
if (handler != null)
|
|
handler(this, e);
|
|
}
|
|
public void OnFull(EventArgs e)
|
|
{
|
|
EventHandler handler = Full;
|
|
if (handler != null)
|
|
handler(this, e);
|
|
}
|
|
public void OnEmpty(EventArgs e)
|
|
{
|
|
EventHandler handler = Empty;
|
|
if (handler != null)
|
|
handler(this, e);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|