Esempio n. 1
0
        private DmxFrame ReadFrame(BinaryReader binRead)
        {
            var target = new DmxFrame();
            target.Start = binRead.ReadByte();
            target.TimestampMS = (uint)binRead.ReadInt32();
            target.Universe = (ushort)binRead.ReadInt16();
            switch (target.Start)
            {
                case 1:
                    target.Len = (ushort)binRead.ReadInt16();
                    target.Data = binRead.ReadBytes(target.Len);
                    break;

                case 2:
                    break;

                default:
                    throw new ArgumentException("Invalid data");
            }
            target.End = binRead.ReadByte();

            if (target.End != 4)
                throw new ArgumentException("Invalid data");

            return target;
        }
Esempio n. 2
0
        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();
            });
        }
Esempio n. 3
0
        private void OutputData(DmxFrame dmxFrame, Bitmap bitmap, Rectangle bitmapRect, int stride)
        {
            int[] mapping;
            if (dmxFrame.Data != null && this.pixelMapping.TryGetValue(dmxFrame.Universe, out mapping))
            {
                BitmapData bitmapData = bitmap.LockBits(bitmapRect, ImageLockMode.WriteOnly, bitmap.PixelFormat);

                int maxLen = Math.Min(dmxFrame.Data.Length, mapping.Length * 3);
                for (int pos = 0; pos < maxLen; pos++)
                {
                    int bytePos = mapping[pos];
                    if (bytePos >= 0 && bytePos < this.rgbValues.Length)
                        this.rgbValues[bytePos] = dmxFrame.Data[pos];
                }

                System.Runtime.InteropServices.Marshal.Copy(this.rgbValues, 0, bitmapData.Scan0, this.rgbValues.Length);
                bitmap.UnlockBits(bitmapData);
            }

            if (dmxFrame.Universe == this.triggerSyncOnUniverse)
                this.device.PushOutput(this.sub.Token);
        }