Skip to content

Instantly share code, notes, and snippets.

@orange-in-space
Last active March 11, 2018 08:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save orange-in-space/ccdbd35835fc51b7c9d9ba6bce6ee9f9 to your computer and use it in GitHub Desktop.
Save orange-in-space/ccdbd35835fc51b7c9d9ba6bce6ee9f9 to your computer and use it in GitHub Desktop.
RingBuffer?><;
using System;
namespace Orange.Utils
{
//
//(c) orange_in_space 2018
//CC BY 4.0
//
// I didn't any run test !><;
// Thread safe.(probably)
//
// 古いデータをがんがん捨てるリングバッファ(?><) オーディオ信号解析用(表示用)に作りました><
//
// 書いただけで、一部の機能以外は動くかどうか試してない><;
// スレッドセーフ
//(のつもりで書いたし、実際に一部の機能だけマルチスレッドで使ってて問題起きてないからたぶん><;)
//
// 使い方:Writeで書いてExportBuffer(out byte[] data)で最新のコピーを得て使う><
//
// Resizeでバッファ長を変更できる・・・と思うんだけど、書いただけで一度も実行したこと無い・・・><;
//
//
class OrangeBytesRingBuffer
{
private int _bufferlength = 65536;
private static readonly object SyncObject = new object();
private int _position = 0;
private byte[] _internaldata;
//constructor
public OrangeBytesRingBuffer()
{
_internaldata = new byte[BufferLength];
}
public OrangeBytesRingBuffer(int bufferLength)
{
BufferLength = bufferLength;
_internaldata = new byte[BufferLength];
}
public void ExportBuffer(out byte[] data)
{
lock (SyncObject)
{
data = CreateInOrderData();
}
}
public int Write(byte[] source, int? length = null)
{
int writelength;
if (length == null)
{
writelength = source.Length;
}
else if (length < 1)
{
writelength = 0;
}
else
{
writelength = Math.Min(source.Length, (int)length);
}
if (writelength == 0)
{
return 0;
}
lock (SyncObject)
{
int data_left = BufferLength - _position;
if (writelength > BufferLength)
{
Array.Copy(source, source.Length - BufferLength, _internaldata, 0, writelength);
_position = 0;
}
else if (writelength < data_left)
{
Array.Copy(source, 0, _internaldata, _position, writelength);
int m_pos = _position;
_position = (_position + writelength) % BufferLength;
}
else
{
Array.Copy(source, 0, _internaldata, _position, data_left);
Array.Copy(source, data_left, _internaldata, 0, writelength - data_left);
int m_pos = _position;
_position = (_position + writelength) % BufferLength;
}
}
return writelength;
}
public void WriteByte(byte source)
{
byte[] tmp = new byte[1] { source }; //....><;
Write(tmp);
}
public void Write(Int32 source)
{
byte[] tmp = BitConverter.GetBytes(source);
Write(tmp);
}
public void Write(Int16 source)
{
byte[] tmp = BitConverter.GetBytes(source);
Write(tmp);
}
public void Write(UInt16 source)
{
byte[] tmp = BitConverter.GetBytes(source);
Write(tmp);
}
public void Write(float source)
{
byte[] tmp = BitConverter.GetBytes(source);
Write(tmp);
}
private byte[] CreateInOrderData()
{
byte[] result = new byte[BufferLength];
if (_position == 0)
{
Array.Copy(_internaldata, result, BufferLength);
}
else
{
Array.Copy(_internaldata, _position, result, 0, BufferLength - _position);
Array.Copy(_internaldata, 0, result, BufferLength - _position, _position);
}
return result;
}
private void Resize(int newSize, bool forceGC = false)
{
lock (SyncObject)
{
if (newSize > BufferLength)
{
byte[] inorderdata = CreateInOrderData();
BufferLength = newSize;
byte[] _data = new byte[BufferLength];
Array.Copy(inorderdata, 0, _data, BufferLength - inorderdata.Length, inorderdata.Length);
}
else
{
byte[] inorderdata = CreateInOrderData();
BufferLength = newSize;
byte[] _data = new byte[BufferLength];
Array.Copy(inorderdata, inorderdata.Length - BufferLength, _data, 0, _data.Length);
}
}
if (forceGC)
{
GC.Collect();
}
}
public int Length
{
get
{
return _bufferlength;
}
}
private int BufferLength
{
get
{
return _bufferlength;
}
set
{
_bufferlength = value;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment