annotate Source/TouchKeys/TouchkeyEntropyGenerator.cpp @ 56:b4a2d2ae43cf tip

merge
author Andrew McPherson <andrewm@eecs.qmul.ac.uk>
date Fri, 23 Nov 2018 15:48:14 +0000
parents c0c62ccf4bfd
children
rev   line source
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 }