public DmxPlayback([System.Runtime.CompilerServices.CallerMemberName] string name = "")
{
this.name = name;
this.sub = new Subroutine("SUB_" + this.name);
this.watch = new Stopwatch();
this.pixelMapping = new Dictionary<int, int[]>();
long timestampOffset = 0;
this.sub.RunAction(ins =>
{
var bitmap = (Bitmap)this.device.GetFrameBuffer(this.sub.Token, this.device)[DataElements.PixelBitmap];
if (bitmap.Width != this.pixelWidth || bitmap.Height != this.pixelHeight)
throw new ArgumentException("Invalid bitmap size");
var bitmapRect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
int bytesPerPixel = Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
int stride = 4 * ((bitmap.Width * bytesPerPixel + 3) / 4);
int byteCount = stride * bitmap.Height;
this.rgbValues = new byte[byteCount];
do
{
// See if we should restart
if (this.file.Position >= this.file.Length)
{
// Restart
this.file.Position = 0;
this.dmxFrame = null;
this.watch.Reset();
}
if (this.dmxFrame == null)
{
this.dmxFrame = ReadFrame(this.binRead);
timestampOffset = this.dmxFrame.TimestampMS;
}
this.watch.Start();
while (!ins.IsCancellationRequested && this.file.Position < this.file.Length)
{
// Calculate when the next stop is
this.nextStop = this.dmxFrame.TimestampMS - timestampOffset;
long msLeft = this.nextStop - this.watch.ElapsedMilliseconds;
if (msLeft <= 0)
{
// Output
OutputData(this.dmxFrame, bitmap, bitmapRect, stride);
// Read next frame
this.dmxFrame = ReadFrame(this.binRead);
continue;
}
else if (msLeft < 16)
{
SpinWait.SpinUntil(() => this.watch.ElapsedMilliseconds >= this.nextStop);
continue;
}
Thread.Sleep(1);
}
} while (!ins.IsCancellationRequested && this.loop);
this.watch.Stop();
});
}