public void gestureCompleted() { // Minimum number of frames of no motion to be segmented as a gesture int motion_threshold = 3; //originally 5 // Minimum length of time after a gesture is completed before another gesture can be started. int ignore_threshold = 10; // If users are still reseting their hands, ignore all the movements and clear all buffers. if (ignoreFrames <= ignore_threshold) { motion_free = 0; readyforgesture = false; colorBox.Background = new SolidColorBrush(Colors.Red); gesture_started = false; //Clear the buffers foreach (List<int> sublist in history) sublist.Clear(); foreach (List<int> sublist in inverse_history) sublist.Clear(); pointHist.Clear(); } if (gesture_started && ignoreFrames > ignore_threshold && motion_free > motion_threshold && selectedChannels >= 2) { // Use LINQ to remove all the frames at the end that correspond to the motion free periods. pointHist = new PointCollection(pointHist.Reverse().Skip(motion_threshold).Reverse()); S = new StylusPointCollection(S.Reverse().Skip(motion_threshold).Reverse()); for (int i = 0; i < history.Count; i++) { history[i] = new List<int>(history[i].Reverse<int>().Skip(motion_threshold).Reverse<int>()); inverse_history[i] = new List<int>(inverse_history[i].Reverse<int>().Skip(motion_threshold).Reverse<int>()); } //If we are in detect mode, pass it to WEKA for classification. if (detectMode.IsChecked.Value && pointHist.Count > 9) { //Call function to find features and test with weka machine if (selectedChannels == 2) { float[] speakers = { (float)KF[0].speakerTheta, (float)KF[1].speakerTheta }; //temp stores the string identifier of the gesture string temp = WekaHelper.Classify(false, pointHist.Count() * waveIn.BufferMilliseconds, true, new List<float>(speakers), pointHist, S, history, inverse_history); //switch statement to rename up/down gestures to forward/back when displaying in the application switch (temp) { case "swipe_up": temp = "swipe_forward"; break; case "swipe_down": temp = "swipe_back"; break; case "tap_up": temp = "tap_forward"; break; case "tap_down": temp = "tap_back"; break; } gestureDetected.Text = temp; //TODO Put interaction with other applications in this switch statement // Allows for changing between workspaces in windows 10. if (shellIntegration.IsChecked.Value) { switch (temp) { case "swipe_forward": sim.Keyboard.KeyDown(VirtualKeyCode.LWIN); sim.Keyboard.KeyPress(VirtualKeyCode.TAB); sim.Keyboard.KeyUp(VirtualKeyCode.LWIN); break; case "swipe_back": break; case "swipe_left": if (!chrome) { sim.Keyboard.KeyDown(VirtualKeyCode.LWIN); sim.Keyboard.KeyDown(VirtualKeyCode.LCONTROL); sim.Keyboard.KeyPress(VirtualKeyCode.LEFT); sim.Keyboard.KeyUp(VirtualKeyCode.LWIN); sim.Keyboard.KeyUp(VirtualKeyCode.LCONTROL); } else { sim.Keyboard.KeyDown(VirtualKeyCode.LCONTROL); sim.Keyboard.KeyDown(VirtualKeyCode.LSHIFT); sim.Keyboard.KeyPress(VirtualKeyCode.TAB); sim.Keyboard.KeyUp(VirtualKeyCode.LSHIFT); sim.Keyboard.KeyUp(VirtualKeyCode.LCONTROL); } break; case "swipe_right": if (!chrome) { sim.Keyboard.KeyDown(VirtualKeyCode.LWIN); sim.Keyboard.KeyDown(VirtualKeyCode.LCONTROL); sim.Keyboard.KeyPress(VirtualKeyCode.RIGHT); sim.Keyboard.KeyUp(VirtualKeyCode.LWIN); sim.Keyboard.KeyUp(VirtualKeyCode.LCONTROL); } else { sim.Keyboard.KeyDown(VirtualKeyCode.LCONTROL); sim.Keyboard.KeyPress(VirtualKeyCode.TAB); sim.Keyboard.KeyUp(VirtualKeyCode.LCONTROL); } break; case "tap_forward": chrome = true; break; case "tap_back": chrome = false; break; case "tap_left": break; case "tap_right": break; } } } ignoreFrames = 0; } // Clear the buffers foreach (List<int> sublist in history) sublist.Clear(); foreach (List<int> sublist in inverse_history) sublist.Clear(); pointHist.Clear(); // Prepare for next gesture (might need a button press) readyforgesture = false; colorBox.Background = new SolidColorBrush(Colors.Red); gesture_started = false; motion_free = 0; } }