andrewm@11
|
1 /*
|
andrewm@11
|
2 TouchKeys: multi-touch musical keyboard control software
|
andrewm@11
|
3 Copyright (c) 2013 Andrew McPherson
|
andrewm@11
|
4
|
andrewm@11
|
5 This program is free software: you can redistribute it and/or modify
|
andrewm@11
|
6 it under the terms of the GNU General Public License as published by
|
andrewm@11
|
7 the Free Software Foundation, either version 3 of the License, or
|
andrewm@11
|
8 (at your option) any later version.
|
andrewm@11
|
9
|
andrewm@11
|
10 This program is distributed in the hope that it will be useful,
|
andrewm@11
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
andrewm@11
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
andrewm@11
|
13 GNU General Public License for more details.
|
andrewm@11
|
14
|
andrewm@11
|
15 You should have received a copy of the GNU General Public License
|
andrewm@11
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
andrewm@11
|
17
|
andrewm@11
|
18 =====================================================================
|
andrewm@11
|
19
|
andrewm@11
|
20 TouchkeyEntropyGenerator.cpp: generate random TouchKeys data for testing
|
andrewm@11
|
21 */
|
andrewm@11
|
22
|
andrewm@11
|
23 #include "TouchkeyEntropyGenerator.h"
|
andrewm@13
|
24 #include <cstdlib>
|
andrewm@11
|
25
|
andrewm@11
|
26 TouchkeyEntropyGenerator::TouchkeyEntropyGenerator(PianoKeyboard& keyboard)
|
andrewm@11
|
27 : Thread("TouchkeyEntropyGenerator"), keyboard_(keyboard),
|
andrewm@11
|
28 waitableEvent_(true), isRunning_(false),
|
andrewm@11
|
29 keyboardRangeLow_(36), keyboardRangeHigh_(60),
|
andrewm@11
|
30 dataInterval_(milliseconds_to_timestamp(5.0))
|
andrewm@11
|
31 {
|
andrewm@13
|
32 srand(time(NULL));
|
andrewm@11
|
33 }
|
andrewm@11
|
34
|
andrewm@11
|
35 // Start the thread handling the scheduling.
|
andrewm@11
|
36 void TouchkeyEntropyGenerator::start() {
|
andrewm@11
|
37 if(isRunning_)
|
andrewm@11
|
38 return;
|
andrewm@11
|
39 // Initialize the touch data before starting
|
andrewm@11
|
40 for(int i = 0; i <= 127; i++) {
|
andrewm@11
|
41 clearTouchData(i);
|
andrewm@11
|
42 nextOnOffFrameCount_[i] = abs(rand()) % 8192;
|
andrewm@11
|
43 }
|
andrewm@11
|
44 isRunning_ = true;
|
andrewm@11
|
45 startThread();
|
andrewm@11
|
46 }
|
andrewm@11
|
47
|
andrewm@11
|
48 // Stop the scheduler thread if it is currently running.
|
andrewm@11
|
49 void TouchkeyEntropyGenerator::stop() {
|
andrewm@11
|
50 if(!isRunning_)
|
andrewm@11
|
51 return;
|
andrewm@11
|
52
|
andrewm@11
|
53 // Tell the thread to quit and signal the event it waits on
|
andrewm@11
|
54 signalThreadShouldExit();
|
andrewm@11
|
55 stopThread(-1);
|
andrewm@11
|
56
|
andrewm@11
|
57 isRunning_ = false;
|
andrewm@11
|
58 }
|
andrewm@11
|
59
|
andrewm@11
|
60 // Run the entropy generator in its own thread
|
andrewm@11
|
61 void TouchkeyEntropyGenerator::run() {
|
andrewm@11
|
62 timestamp_type lastDataTime = keyboard_.schedulerCurrentTimestamp();
|
andrewm@11
|
63 timestamp_type currentTime;
|
andrewm@11
|
64
|
andrewm@11
|
65 while(!threadShouldExit()) {
|
andrewm@11
|
66 // Generate random data at regular intervals
|
andrewm@11
|
67 currentTime = keyboard_.schedulerCurrentTimestamp();
|
andrewm@11
|
68 while(currentTime - lastDataTime < dataInterval_ && !threadShouldExit()) {
|
andrewm@11
|
69 waitableEvent_.wait(1);
|
andrewm@11
|
70 currentTime = keyboard_.schedulerCurrentTimestamp();
|
andrewm@11
|
71 }
|
andrewm@11
|
72
|
andrewm@11
|
73 for(int i = keyboardRangeLow_; i <= keyboardRangeHigh_; i++) {
|
andrewm@11
|
74 if(touchFrames_[i].count != 0) {
|
andrewm@11
|
75 // This key is on. Check if it should go off; otherwise generate new data
|
andrewm@11
|
76 if(--nextOnOffFrameCount_[i] <= 0) {
|
andrewm@11
|
77 clearTouchData(i);
|
andrewm@11
|
78 if(keyboard_.key(i) != 0)
|
andrewm@11
|
79 keyboard_.key(i)->touchOff(currentTime);
|
andrewm@11
|
80 nextOnOffFrameCount_[i] = abs(rand()) % 8192;
|
andrewm@11
|
81 }
|
andrewm@11
|
82 else {
|
andrewm@11
|
83 generateRandomFrame(i);
|
andrewm@11
|
84 if(keyboard_.key(i) != 0) {
|
andrewm@11
|
85 KeyTouchFrame copyFrame(touchFrames_[i]);
|
andrewm@11
|
86 keyboard_.key(i)->touchInsertFrame(copyFrame, currentTime);
|
andrewm@11
|
87 }
|
andrewm@11
|
88 }
|
andrewm@11
|
89 }
|
andrewm@11
|
90 else {
|
andrewm@11
|
91 // This key is off. Check if it should go on
|
andrewm@11
|
92 if(--nextOnOffFrameCount_[i] <= 0) {
|
andrewm@11
|
93 generateRandomFrame(i);
|
andrewm@11
|
94 if(keyboard_.key(i) != 0) {
|
andrewm@11
|
95 KeyTouchFrame copyFrame(touchFrames_[i]);
|
andrewm@11
|
96 keyboard_.key(i)->touchInsertFrame(copyFrame, currentTime);
|
andrewm@11
|
97 }
|
andrewm@11
|
98 nextOnOffFrameCount_[i] = abs(rand()) % 8192;
|
andrewm@11
|
99 }
|
andrewm@11
|
100 }
|
andrewm@11
|
101 }
|
andrewm@11
|
102 }
|
andrewm@11
|
103
|
andrewm@11
|
104 // Tell all currently enabled notes to turn off
|
andrewm@11
|
105 for(int i = 0; i < 128; i++) {
|
andrewm@11
|
106 if(touchFrames_[i].count > 0 && keyboard_.key(i) != 0)
|
andrewm@11
|
107 keyboard_.key(i)->touchOff(currentTime);
|
andrewm@11
|
108 }
|
andrewm@11
|
109 }
|
andrewm@11
|
110
|
andrewm@11
|
111 // Clear touch data for a particular key
|
andrewm@11
|
112 void TouchkeyEntropyGenerator::clearTouchData(int i) {
|
andrewm@11
|
113 touchFrames_[i].count = 0;
|
andrewm@11
|
114 touchFrames_[i].locH = -1.0;
|
andrewm@11
|
115 touchFrames_[i].nextId = 0;
|
andrewm@11
|
116 for(int j = 0; j < 3; j++) {
|
andrewm@11
|
117 touchFrames_[i].ids[j] = -1;
|
andrewm@11
|
118 touchFrames_[i].locs[j] = -1.0;
|
andrewm@11
|
119 touchFrames_[i].sizes[j] = 0;
|
andrewm@11
|
120 }
|
andrewm@11
|
121 int key = i % 12;
|
andrewm@11
|
122 if(key == 1 || key == 3 || key == 6 || key == 8 || key == 10)
|
andrewm@11
|
123 touchFrames_[i].white = false;
|
andrewm@11
|
124 else
|
andrewm@11
|
125 touchFrames_[i].white = true;
|
andrewm@11
|
126 }
|
andrewm@11
|
127
|
andrewm@11
|
128 // Generate a random frame of touch data on this key
|
andrewm@11
|
129 void TouchkeyEntropyGenerator::generateRandomFrame(int key) {
|
andrewm@11
|
130 touchFrames_[key].count = 1;
|
andrewm@11
|
131 touchFrames_[key].locH = (float)abs(rand()) / (float)RAND_MAX;
|
andrewm@11
|
132 touchFrames_[key].locs[0] = (float)abs(rand()) / (float)RAND_MAX;
|
andrewm@11
|
133 touchFrames_[key].sizes[0] = (float)abs(rand()) / (float)RAND_MAX;
|
andrewm@11
|
134 } |