Example #1
0
        public void OnFrame(object sender, FrameEventArgs args)
        {
            // Get the most recent frame and report some basic information
            Frame frame = args.frame;
            Hand  h;

            if (frame.Hands.Count == 0)
            {
                return;
            }

            h = frame.Hands[0];
            Console.WriteLine(string.Format("Velocity is {0}", h.PalmVelocity));
            palm.Move(h.PalmPosition, h.PalmVelocity);
            if (palm.Stopped)
            {
                // check if this is the first time we're reading that the hand is stopped
                if (!handStopped)
                {
                    Console.WriteLine("Beat!");
                    handStopped = true;
                    // possible beat. get volume data, centroid of movement, and append the tempo to the queue
                    TimeSpan dur      = palm.PreviousDuration;
                    Vector   centroid = palm.Centroid;
                    Vector   startPos = palm.StartPosition;
                    Vector   stopPos  = palm.StopPosition;
                    oscHandler = new OSCHandler();
                    float estTempo = 60 * 1000 / dur.Milliseconds;
                    oscHandler.SendTempo((int)Math.Round(estTempo));

                    // X centroid of hand during movement = pan
                    Vector normCentroid = bounder.NormalizePoint(centroid);
                    oscHandler.SendPan((double)normCentroid.x);

                    // get normalized distance by normalizing the points
                    Vector startNorm = bounder.NormalizePoint(startPos);
                    Vector stopNorm  = bounder.NormalizePoint(stopPos);
                    oscHandler.SendVolume(stopNorm.DistanceTo(startNorm));
                }

                // otherwise, check if the hand meets fermata threshold
                else if (palm.DurationStopped > Listener.fermataThreshold)
                {
                    Console.WriteLine(string.Format("Duration stopped is {0}, threshold is {1}", palm.DurationStopped, Listener.fermataThreshold));
                    oscHandler = new OSCHandler();
                    oscHandler.SendFermata();
                }
            }
            else
            {
                // check if it was stopped previously
                if (handStopped)
                {
                    oscHandler = new OSCHandler();
                    oscHandler.SendTempo();
                }

                handStopped = false;
            }
        }
        /// <summary>
        /// Event responder to receiving a new frame
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        public void OnFrame(object sender, FrameEventArgs args)
        {
            // Get the most recent frame and report some basic information
            Frame          frame   = args.frame;
            InteractionBox box     = frame.InteractionBox;
            double         xBounds = frame.InteractionBox.Width;
            Hand           h;

            // search through detected hands
            int matchIndex = -1;

            for (int i = 0; i < frame.Hands.Count; i++)
            {
                if (frame.Hands[i].IsRight && UseRightHand)
                {
                    matchIndex = i;
                    break;
                }
                else if (frame.Hands[i].IsLeft && !UseRightHand)
                {
                    matchIndex = i;
                    break;
                }
            }

            if (matchIndex < 0)
            {
                // no matching hands were detected. just send the last played tempo
                oscHandler.SendTempo();
                return;
            }

            h = frame.Hands[matchIndex];

            // further stabilize this position by adding the average of the last three points
            xPositions.EnqueueMovingAverage(h.StabilizedPalmPosition.x, 3);
            lastTwoBeatsPositions.Add(h.StabilizedPalmPosition.x);
            //allPositions.Add(h.StabilizedPalmPosition);
            double xBackAvg    = xPositions.BackAverage(.8);
            double xFrontAvg   = xPositions.FrontAverage(.2);
            double averageXpos = 0;

            if ((xBackAvg * xFrontAvg < 0 && xPositions.Length() > 20))
            {
                BeatAmt++;
                Console.WriteLine("Beat!");
                if (BeatAmt % 2 == 0)
                {
                    averageXpos = lastTwoBeatsPositions.Average();
                    lastTwoBeatsPositions.Clear();
                }

                xPositions.Clear();
                if (firstBeat)
                {
                    // not enough data to create a tempo. we will use this as a starting point
                    startTime       = DateTime.Now;
                    initialPosition = h.PalmPosition;
                    firstBeat       = false;
                    return;
                }
                else
                {
                    TimeSpan span = DateTime.Now - startTime;
                    startTime = DateTime.Now;

                    double durSeconds = span.Seconds + (span.Milliseconds / 1000.0);
                    int    estTempo   = (int)Math.Round(60 / durSeconds);
                    estimatedTempos.Enqueue(estTempo);



                    var   initialNorm = box.NormalizePoint(initialPosition);
                    var   currentNorm = box.NormalizePoint(h.StabilizedPalmPosition);
                    float dist        = initialNorm.DistanceTo(currentNorm);
                    Console.WriteLine(string.Format("Actual 3D normalized dist {0}", dist));
                    double xDist = Math.Abs(currentNorm.x - initialNorm.x);

                    var nonNormDist = initialPosition.DistanceTo(h.StabilizedPalmPosition);
                    Console.WriteLine(string.Format("Non normalized dist {0}", nonNormDist));
                    dist = nonNormDist / 100;
                    // reset initial position
                    initialPosition = h.StabilizedPalmPosition;
                    // send volume based on scale of distance
                    if (BeatAmt % 2 == 0)
                    {
                        Vector avgXPosition = new Vector((float)averageXpos, 0, 0);
                        Vector normX        = box.NormalizePoint(avgXPosition);
                        oscHandler.SendPan(normX.x);
                        oscHandler.SendVolume(dist * 2 > 1 ? 1 : dist * 2);
                        // round the average to the nearest 5 to prevent too many changes
                        oscHandler.SendTempo((int)Math.Round(estimatedTempos.Average() / 5) * 5);
                    }

                    Console.WriteLine("-----");
                }
            }
            else
            {
                // check if the time between the last beat time and the current time is greater than the threshold for a fermata
            }
        }