コード例 #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);
        }
コード例 #2
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);
            }
        }
コード例 #3
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();
            });
        }