using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.Kinect; using Newtonsoft.Json; using NAudio.Wave; using MicroLibrary; using System.IO; namespace FFDDR { public partial class FFDDR : Form { // Wavprocessor variables private string[] wavInfo; private long wavFrameIncrement = 0; private WaveFileReader reader; private WaveOut output; private int m = 0; private Graphics graphics; private MicroTimer timer; private int beatBoxChanger = 0; private long timeSinceLastBeat = 0; // SkeletonTracker variables private const float RenderWidth = 640.0f; private const float RenderHeight = 480.0f; private KinectSensor sensor; private Skeleton[] skeletonArray; private SkeletonManager skeletonManager; private PictureBox[] pboxShowCalibrated; private Vector4 centreScreen; private bool twoPlayer = false; private float deadspotSize = 50; public FFDDR() { InitializeComponent(); } private void FFDDR_Load(object sender, EventArgs e) { #region Beat detect // The song to convert + read reader = new WaveFileReader(@"C:\Users\Chris\Downloads\become.wav"); output = new WaveOut(); output.Init(reader); output.Play(); graphics = mainScreen.CreateGraphics(); this.DoubleBuffered = true; // The song to play wavInfo = WavProcessor.ReadWav(@"C:\Users\Chris\Downloads\", "become", 1024, 30); // Play one buffer every (songLength/temp.length(numbuffer)) milliseconds. Both values are contained in the Json string[] WavFrame temp = (WavFrame)JsonConvert.DeserializeObject(wavInfo[0]); timer = new MicroTimer(); timer.Interval = (int)((temp.songLength / wavInfo.Length) * 1000); // Have the ability to ignore late-firing timer events. Enable if drift issues exist, currently works with. // timer.IgnoreEventIfLateBy = (int)((temp.songLength / wavInfo.Length) )/ 4; timer.Enabled = true; timer.MicroTimerElapsed += new MicroTimer.MicroTimerElapsedEventHandler(timerTick); #endregion #region Initialize and start Kinect foreach (var potentialSensor in KinectSensor.KinectSensors) { if (potentialSensor.Status == KinectStatus.Connected) { this.sensor = potentialSensor; break; } } if (null != this.sensor) { // Turn on the skeleton stream to receive skeleton frames this.sensor.SkeletonStream.Enable(); // Add an event handler to be called whenever there is new color frame data this.sensor.SkeletonFrameReady += this.SensorSkeletonFrameReady; // Start the sensor! try { this.sensor.Start(); sensor.ElevationAngle = -5; } catch (IOException) { this.sensor = null; } } #endregion skeletonManager = new SkeletonManager(6); graphics = screen.CreateGraphics(); centreScreen.X = screen.Width / 2; centreScreen.Z = screen.Height / 2; #region Display pictureboxes showing calibration information pboxShowCalibrated = new PictureBox[6]; for (int i = 0; i < pboxShowCalibrated.Length; i++) { pboxShowCalibrated[i] = new PictureBox(); pboxShowCalibrated[i].Height = 40; pboxShowCalibrated[i].Width = 40; pboxShowCalibrated[i].Left = this.Width - (pboxShowCalibrated[i].Width + 17); pboxShowCalibrated[i].Top = (i * 50); pboxShowCalibrated[i].BackColor = Color.DarkGray; pboxShowCalibrated[i].Visible = true; this.Controls.Add(pboxShowCalibrated[i]); } #endregion } private void timerTick(object sender, MicroTimerEventArgs args) { timeSinceLastBeat++; wavFrameIncrement++; if (mainScreen.InvokeRequired) { //mainScreen.Invoke(new MethodInvoker(delegate { mainScreen.Refresh(); })); mainScreen.Invoke(new MethodInvoker(delegate { mainScreen.CreateGraphics().FillRectangle(new SolidBrush(Color.White), 0, 0, mainScreen.Width, mainScreen.Height); })); } // When song finished this is out of bounds. fix this. WavFrame currentFrame = (WavFrame)JsonConvert.DeserializeObject(wavInfo[wavFrameIncrement]); for (int j = 0; j < currentFrame.bandPowers.Length; j++) { // Calling control change drawing beat visualizer bands) from another thread. if (mainScreen.InvokeRequired) { mainScreen.Invoke(new MethodInvoker(delegate { mainScreen.CreateGraphics().DrawRectangle(new Pen(Color.DarkBlue), j * 15, 0, 10, 6 * currentFrame.bandPowers[j]); })); } } // If a beat exists on the current frame, display it via BeatBox if (currentFrame.beatExists == true) { if (beatBox.InvokeRequired) { beatBox.Invoke(new MethodInvoker(delegate { ChangeBeatBox(); })); } } } private void ChangeBeatBox() { // Alternate the box which chanhges to the beat. graphics = mainScreen.CreateGraphics(); if (timeSinceLastBeat >= 20) { beatBoxChanger++; timeSinceLastBeat = 0; PictureBox p; if ((beatBoxChanger %= 2) == 1) { p = beatBox; } else p = beatBox1; if (beatBox.BackColor == Color.DarkBlue) { p.BackColor = Color.Turquoise; } else p.BackColor = Color.DarkBlue; } } private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) { skeletonArray = new Skeleton[0]; using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame()) { if (skeletonFrame != null) { skeletonArray = new Skeleton[skeletonFrame.SkeletonArrayLength]; skeletonFrame.CopySkeletonDataTo(skeletonArray); skeletonManager.Update(skeletonArray); } if (skeletonArray.Length != 0) { //screen.Refresh(); //screen2.Refresh(); twoPlayer = false; for (int i = 0; i < skeletonArray.Length; i++) { if (skeletonManager.calibrated[i] == false) skeletonManager.Calibrate(i); if (skeletonManager.calibrated[i] == true) { if (skeletonManager.skeletons[i].TrackingState == SkeletonTrackingState.NotTracked) { skeletonManager.calibrated[i] = false; pboxShowCalibrated[i].BackColor = Color.DarkGray; } else { pboxShowCalibrated[i].BackColor = Color.Cyan; if (twoPlayer == false) graphics = screen.CreateGraphics(); else graphics = screen2.CreateGraphics(); twoPlayer = true; int quadrentLeft = skeletonManager.FindQuadrant(skeletonManager.leftFoot[i].Z, skeletonManager.leftFoot[i].X, skeletonManager.centre[i]); int quadrentRight = skeletonManager.FindQuadrant(skeletonManager.rightFoot[i].Z, skeletonManager.rightFoot[i].X, skeletonManager.centre[i]); graphics.FillRectangle(new SolidBrush(Color.White), 0, 0, screen.Width, screen.Height); DrawQuadrent(quadrentLeft, graphics); DrawQuadrent(quadrentRight, graphics); float xCoordLeft = centreScreen.X + (skeletonManager.leftFoot[i].X - skeletonManager.centre[i].X) * (screen.Width / 2) / 0.8f; float yCoordLeft = centreScreen.Z + (skeletonManager.leftFoot[i].Z - skeletonManager.centre[i].Z) * (screen.Height / 2) / 0.8f; float xCoordRight = centreScreen.X + (skeletonManager.rightFoot[i].X - skeletonManager.centre[i].X) * (screen.Width / 2) / 0.8f; float yCoordRight = centreScreen.Z + (skeletonManager.rightFoot[i].Z - skeletonManager.centre[i].Z) * (screen.Height / 2) / 0.8f; graphics.DrawRectangle(new Pen(Color.Black), (int)(xCoordLeft), (int)(yCoordLeft), 20, 20); graphics.DrawRectangle(new Pen(Color.Black), (int)(xCoordRight), (int)(yCoordRight), 20, 20); } } } } } } private void DrawQuadrent(int num, Graphics graphics) { if (num == 1) { graphics.FillRectangle(new SolidBrush(Color.Red), 0, 0, screen.Width / 2, screen.Height / 2); } else if (num == 2) { graphics.FillRectangle(new SolidBrush(Color.Blue), screen.Width / 2, 0, screen.Width / 2, screen.Height / 2); } else if (num == 3) { graphics.FillRectangle(new SolidBrush(Color.Green), screen.Height / 2, screen.Width / 2, screen.Width / 2, screen.Height / 2); } else if (num == 4) { graphics.FillRectangle(new SolidBrush(Color.Yellow), 0, screen.Height / 2, screen.Width / 2, screen.Height / 2); } graphics.FillEllipse(new SolidBrush(Color.Black), screen.Width / 2 - (deadspotSize / 2), screen.Height / 2 - (deadspotSize / 2), deadspotSize, deadspotSize); } } }