public void OnHand(HandStats hand, long timestamp)
        {
            if (hand.TimeVisible <= MIN_TIME_VISIBLE)
            {
                return;
            }

            float currentX = hand.PalmPosition.x;

            if (float.IsNaN(lastXTriggered))
            {
                lastXTriggered = currentX;
                return;
            }

            float diff = lastXTriggered - currentX;

            if (Math.Abs(diff) < MIN_TRIGGER_DISTANCE)
            {
                return;
            }

            lastXTriggered = currentX;

            if (diff < 0)
            {
                VolumeController.VolumeDown();
            }
            else
            {
                VolumeController.VolumeUp();
            }
        }
        /// <summary>
        ///     Call this function whenever a valid hand is found in a frame that you want to detect gestures on
        /// </summary>
        /// <param name="hand">Hand to detect gestures on</param>
        /// <param name="timestamp">Timestamp of the frame, in microseconds</param>
        public void OnHand(HandStats hand, long timestamp)
        {
            bool wasMakingGesture = isMakingGesture && lastHandId == hand.Id;

            isMakingGesture = isGesture(hand);

            lastHandId = hand.Id;

            if (!wasMakingGesture && isMakingGesture)
            {
                lastGestureTime = timestamp;
            }
            else if (!isMakingGesture)
            {
                if (wasMakingGesture && timestamp >= lastGestureTime + MIN_COOLDOWN_TIME)
                {
                    lastTriggerHandId = -1;
                }
                return;
            }

            // Make sure the trigger is detected for a bit, not just random noise
            if (timestamp <= lastGestureTime + MIN_DETECTION_TIME)
            {
                return;
            }

            // Don't let the same hand trigger gesture again
            if (lastTriggerHandId == hand.Id)
            {
                return;
            }

            // Only trigger action at most once every second
            if (timestamp <= lastActionTime + MIN_TRIGGER_DEBOUNCE)
            {
                return;
            }

            // Trigger a gesture!
            lastActionTime    = timestamp;
            lastTriggerHandId = hand.Id;
            onGesture();
        }
        private void frameHandler(object sender, FrameEventArgs eventArgs)
        {
            Frame frame = eventArgs.frame;

            // Only watch for one-handed gestures
            if (frame.Hands.Count != 1)
            {
                return;
            }

            var hand = new HandStats(frame.Hands[0]);

            if (WindowState != WindowState.Minimized)
            {
                HandInfo.Text      = hand.ToString();
                Confidence.Text    = "Confidence: " + hand.Confidence;
                TimeVisible.Text   = "Time visible: " + hand.TimeVisible;
                PinchStrength.Text = "Pinch strength: " + hand.PinchStrength;
                PinchDistance.Text = "Pinch distance: " + hand.PinchDistance;
                GrabStrength.Text  = "Grab strength: " + hand.GrabStrength;
                PalmPosition.Text  = $"Palm position: {hand.PalmPosition}";
                HandYaw.Text       = $"Hand yaw: {hand.Direction.Yaw}";
                HandPitch.Text     = $"Hand pitch: {hand.Direction.Pitch}";
                HandRoll.Text      = $"Hand roll: {hand.PalmNormal.Roll}";

                FingerSpread.Text  = "Finger spread: " + hand.AngleSum;
                HandOpen.Text      = $"Hand open: {hand.IsOpen}";
                HandDirection.Text = $"Hand direction: {hand.Pointing}";
                CurrentTime.Text   = $"Current time: {frame.Timestamp}";
                SameHand.Text      = $"Same hand: {hand.Id == currentHand}";
                HandInBounds.Text  = $"In bounds: {hand.IsInBounds}";
                UsingMouse.Text    = $"Using mouse: {hand.IsUsingMouse}";
            }

            // Only use right hand
            if (hand.IsLeft)
            {
                return;
            }
            if (!hand.IsInBounds || hand.IsUsingMouse)
            {
                currentHand = 0;
                return;
            }

            if (hand.Id != currentHand)
            {
                // Play a sound to indicate a new hand was detected
                waveFileReader.Position = 0;
                beepUp.Play();
            }

            foreach (var detector in gestureDetectors)
            {
                detector.OnHand(hand, frame.Timestamp);
            }

            scrubDetector.OnHand(hand, frame.Timestamp);

            currentHand = hand.Id;
        }