This repository has been archived by the owner on Jun 5, 2023. It is now read-only.
/
DemoInstrument.cs
116 lines (94 loc) · 4.13 KB
/
DemoInstrument.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using Microsoft.Kinect;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ventuz.OSC;
namespace GesturalMusic
{
class DemoInstrument : Instrument
{
// for different types
public readonly static String PAD = "Pad";
public readonly static String INSTRUMENT = "Instrument";
public new string name;
private Filter filter;
// For rate limiting
private DateTime lastNotePlayed;
private static TimeSpan rateLimit = new TimeSpan(0, 0, 0, 0, 30);
// For hand closed state (playing state)
HandState handStateLast;
int lastSemitone;
public DemoInstrument(string name) : base(name)
{
this.name = name;
filter = new Filter(this.name);
lastNotePlayed = DateTime.Now;
handStateLast = HandState.Unknown;
lastSemitone = -1;
}
public void PlayNote(float pitch, int octave)
{
if (lastNotePlayed + rateLimit <= DateTime.Now)
{
Console.WriteLine("Playing: " + this.name + " " + pitch + " " + octave + " (demo mode)");
OscElement pitchElem = new OscElement("/" + this.name + "/pitch", pitch);
OscElement octaveElem = new OscElement("/" + this.name + "/octave", octave);
MainWindow.osc.Send(pitchElem);
MainWindow.osc.Send(octaveElem);
lastNotePlayed = DateTime.Now;
}
}
public bool CheckAndPlayNoteD(Body body)
{
// first thing, send filters
filter.SendFilterData(body);
double rightThreshold = 0.2;
double leftThreshold = 0.1;
// We're trying to play a MIDI instrument
if (body.HandLeftState == HandState.Open)
{
//////////////////////////////////////////////////////////////
// Semitone
//////////////////////////////////////////////////////////////
double leftMax = body.Joints[JointType.ShoulderLeft].Position.X - MainWindow.armLength + MainWindow.armLength * rightThreshold;
double rightMax = body.Joints[JointType.ShoulderLeft].Position.X - MainWindow.armLength * leftThreshold;
// Base our measurements off the wrist location
double pos = body.Joints[JointType.WristLeft].Position.X;
float percentage = (float)Utils.Clamp(0, 1, (float)((pos - leftMax) / (rightMax - leftMax)));
//////////////////////////////////////////////////////////////
// Octave
//////////////////////////////////////////////////////////////
// baseOctave is the lowest octave - so, if in C, we want our lowest note to be C3 (0-based)
// userOctave can add to baseOctave, so our octaves available start at C3 (lower), C4 (slightly down), and C5 (above shoulder)
int baseOctave = 4;
int userOctave = 0;
if (body.Joints[JointType.WristLeft].Position.Y > body.Joints[JointType.SpineShoulder].Position.Y)
{
userOctave = 2;
}
else if (body.Joints[JointType.WristLeft].Position.Y > body.Joints[JointType.SpineMid].Position.Y)
{
userOctave = 1;
}
else if (body.Joints[JointType.WristLeft].Position.Y > body.Joints[JointType.SpineBase].Position.Y)
{
userOctave = 0;
}
else
{
return false;
}
// Scale octave to 12 semitones per octave
int octave = (userOctave + baseOctave) * 12;
//////////////////////////////////////////////////////////////
// Send
//////////////////////////////////////////////////////////////
this.PlayNote(percentage, octave);
return true;
}
return false;
}
}
}