andrewm@0
|
1 /*
|
andrewm@0
|
2 TouchKeys: multi-touch musical keyboard control software
|
andrewm@0
|
3 Copyright (c) 2013 Andrew McPherson
|
andrewm@0
|
4
|
andrewm@0
|
5 This program is free software: you can redistribute it and/or modify
|
andrewm@0
|
6 it under the terms of the GNU General Public License as published by
|
andrewm@0
|
7 the Free Software Foundation, either version 3 of the License, or
|
andrewm@0
|
8 (at your option) any later version.
|
andrewm@0
|
9
|
andrewm@0
|
10 This program is distributed in the hope that it will be useful,
|
andrewm@0
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
andrewm@0
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
andrewm@0
|
13 GNU General Public License for more details.
|
andrewm@0
|
14
|
andrewm@0
|
15 You should have received a copy of the GNU General Public License
|
andrewm@0
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
andrewm@0
|
17
|
andrewm@0
|
18 =====================================================================
|
andrewm@0
|
19
|
andrewm@0
|
20 KeyIdleDetector.h: uses continuous key position to detect whether a key
|
andrewm@0
|
21 is idle or active; active keys will have more detailed tracking applied
|
andrewm@0
|
22 to their position, so detecting idle keys saves processing.
|
andrewm@0
|
23 */
|
andrewm@0
|
24
|
andrewm@0
|
25
|
andrewm@0
|
26 #ifndef KEYCONTROL_KEYIDLEDETECTOR_H
|
andrewm@0
|
27 #define KEYCONTROL_KEYIDLEDETECTOR_H
|
andrewm@0
|
28
|
andrewm@0
|
29 #include "../Utility/Node.h"
|
andrewm@0
|
30 #include "../Utility/Accumulator.h"
|
andrewm@0
|
31 //#include "Trigger.h"
|
andrewm@0
|
32 //#include "PianoKeyboard.h"
|
andrewm@0
|
33 #include "PianoTypes.h"
|
andrewm@0
|
34
|
andrewm@0
|
35 #define kKeyIdleNumSamples 10
|
andrewm@0
|
36 #define kDefaultKeyIdleThreshold (scale_key_position(0.05))
|
andrewm@0
|
37
|
andrewm@0
|
38 // Three states of idle detector
|
andrewm@0
|
39 enum {
|
andrewm@0
|
40 kIdleDetectorIdle = 0,
|
andrewm@0
|
41 kIdleDetectorActive = 1,
|
andrewm@0
|
42 kIdleDetectorUnknown = 2
|
andrewm@0
|
43 };
|
andrewm@0
|
44
|
andrewm@0
|
45 /*
|
andrewm@0
|
46 * KeyIdleDetector
|
andrewm@0
|
47 *
|
andrewm@0
|
48 * A Filter that looks for whether the key position has been flat over time, or is changing.
|
andrewm@0
|
49 * Uses this information to detect when a key has begun to move.
|
andrewm@0
|
50 *
|
andrewm@0
|
51 * This class contains a second Filter object, operating on the same data source, which is used
|
andrewm@0
|
52 * to maintain a running sum of the last N values. The running sum is converted to an average
|
andrewm@0
|
53 * value, and the maximum deviation from the average is calculated.
|
andrewm@0
|
54 *
|
andrewm@0
|
55 */
|
andrewm@0
|
56
|
andrewm@0
|
57 class KeyIdleDetector : public Node<int> {
|
andrewm@0
|
58 public:
|
andrewm@0
|
59 // ***** Constructors *****
|
andrewm@0
|
60
|
andrewm@0
|
61 // Default constructor, taking an input and thresholds (position and timing) at which to detect "not idle"
|
andrewm@0
|
62 KeyIdleDetector(capacity_type capacity, Node<key_position>& keyBuffer, key_position positionThreshold,
|
andrewm@0
|
63 key_position activityThreshold, int counterThreshold);
|
andrewm@0
|
64
|
andrewm@0
|
65 // Copy constructor
|
andrewm@0
|
66 // KeyIdleDetector(KeyIdleDetector const& obj);
|
andrewm@0
|
67
|
andrewm@0
|
68 // ***** State Access *****
|
andrewm@0
|
69
|
andrewm@0
|
70 // Determine whether the key is currently idle or not.
|
andrewm@0
|
71 int idleState() { return idleState_; }
|
andrewm@0
|
72
|
andrewm@0
|
73 // Set the threshold at which a key is determined to be idle or not.
|
andrewm@0
|
74 key_position activityThreshold() { return activityThreshold_; }
|
andrewm@0
|
75 key_position positionThreshold() { return positionThreshold_; }
|
andrewm@0
|
76 void setActivityThreshold(key_position thresh) { activityThreshold_ = thresh; }
|
andrewm@0
|
77 void setPositionThreshold(key_position thresh) { positionThreshold_ = thresh; }
|
andrewm@0
|
78
|
andrewm@0
|
79 // ***** Modifiers *****
|
andrewm@0
|
80
|
andrewm@0
|
81 void clear();
|
andrewm@0
|
82
|
andrewm@0
|
83 // ***** Evaluator *****
|
andrewm@0
|
84
|
andrewm@0
|
85 // This method actually handles the quantification of key activity. When it
|
andrewm@0
|
86 // exceeds a preset threshold, it sends a trigger
|
andrewm@0
|
87
|
andrewm@0
|
88 void triggerReceived(TriggerSource* who, timestamp_type timestamp);
|
andrewm@0
|
89
|
andrewm@0
|
90 // ***** Member Variables *****
|
andrewm@0
|
91
|
andrewm@0
|
92 Node<key_position>& keyBuffer_; // Raw key position data
|
andrewm@0
|
93 Accumulator<key_position, kKeyIdleNumSamples> accumulator_; // This class accumulates the last N key samples (to find an average)
|
andrewm@0
|
94
|
andrewm@0
|
95 key_position keyIdleThreshold_; // Position below which we assume key is staying idle
|
andrewm@0
|
96
|
andrewm@0
|
97 key_position activityThreshold_; // How much key motion should take place to make key active
|
andrewm@0
|
98 key_position positionThreshold_; // Position below which key can return to idle
|
andrewm@0
|
99 int numberOfFramesWithoutActivity_; // For how many samples have we been below the idle threshold?
|
andrewm@0
|
100 int noActivityCounterThreshold_;
|
andrewm@0
|
101 int idleState_; // Currently idle?
|
andrewm@0
|
102
|
andrewm@0
|
103 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KeyIdleDetector)
|
andrewm@0
|
104 };
|
andrewm@0
|
105
|
andrewm@0
|
106
|
andrewm@0
|
107 #endif /* KEYCONTROL_KEYIDLEDETECTOR_H */ |