andrewm@0: /*
andrewm@0: TouchKeys: multi-touch musical keyboard control software
andrewm@0: Copyright (c) 2013 Andrew McPherson
andrewm@0:
andrewm@0: This program is free software: you can redistribute it and/or modify
andrewm@0: it under the terms of the GNU General Public License as published by
andrewm@0: the Free Software Foundation, either version 3 of the License, or
andrewm@0: (at your option) any later version.
andrewm@0:
andrewm@0: This program is distributed in the hope that it will be useful,
andrewm@0: but WITHOUT ANY WARRANTY; without even the implied warranty of
andrewm@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
andrewm@0: GNU General Public License for more details.
andrewm@0:
andrewm@0: You should have received a copy of the GNU General Public License
andrewm@0: along with this program. If not, see .
andrewm@0:
andrewm@0: =====================================================================
andrewm@0:
andrewm@0: KeyIdleDetector.h: uses continuous key position to detect whether a key
andrewm@0: is idle or active; active keys will have more detailed tracking applied
andrewm@0: to their position, so detecting idle keys saves processing.
andrewm@0: */
andrewm@0:
andrewm@0:
andrewm@0: #ifndef KEYCONTROL_KEYIDLEDETECTOR_H
andrewm@0: #define KEYCONTROL_KEYIDLEDETECTOR_H
andrewm@0:
andrewm@0: #include "../Utility/Node.h"
andrewm@0: #include "../Utility/Accumulator.h"
andrewm@0: //#include "Trigger.h"
andrewm@0: //#include "PianoKeyboard.h"
andrewm@0: #include "PianoTypes.h"
andrewm@0:
andrewm@0: #define kKeyIdleNumSamples 10
andrewm@0: #define kDefaultKeyIdleThreshold (scale_key_position(0.05))
andrewm@0:
andrewm@0: // Three states of idle detector
andrewm@0: enum {
andrewm@0: kIdleDetectorIdle = 0,
andrewm@0: kIdleDetectorActive = 1,
andrewm@0: kIdleDetectorUnknown = 2
andrewm@0: };
andrewm@0:
andrewm@0: /*
andrewm@0: * KeyIdleDetector
andrewm@0: *
andrewm@0: * A Filter that looks for whether the key position has been flat over time, or is changing.
andrewm@0: * Uses this information to detect when a key has begun to move.
andrewm@0: *
andrewm@0: * This class contains a second Filter object, operating on the same data source, which is used
andrewm@0: * to maintain a running sum of the last N values. The running sum is converted to an average
andrewm@0: * value, and the maximum deviation from the average is calculated.
andrewm@0: *
andrewm@0: */
andrewm@0:
andrewm@0: class KeyIdleDetector : public Node {
andrewm@0: public:
andrewm@0: // ***** Constructors *****
andrewm@0:
andrewm@0: // Default constructor, taking an input and thresholds (position and timing) at which to detect "not idle"
andrewm@0: KeyIdleDetector(capacity_type capacity, Node& keyBuffer, key_position positionThreshold,
andrewm@0: key_position activityThreshold, int counterThreshold);
andrewm@0:
andrewm@0: // Copy constructor
andrewm@0: // KeyIdleDetector(KeyIdleDetector const& obj);
andrewm@0:
andrewm@0: // ***** State Access *****
andrewm@0:
andrewm@0: // Determine whether the key is currently idle or not.
andrewm@0: int idleState() { return idleState_; }
andrewm@0:
andrewm@0: // Set the threshold at which a key is determined to be idle or not.
andrewm@0: key_position activityThreshold() { return activityThreshold_; }
andrewm@0: key_position positionThreshold() { return positionThreshold_; }
andrewm@0: void setActivityThreshold(key_position thresh) { activityThreshold_ = thresh; }
andrewm@0: void setPositionThreshold(key_position thresh) { positionThreshold_ = thresh; }
andrewm@0:
andrewm@0: // ***** Modifiers *****
andrewm@0:
andrewm@0: void clear();
andrewm@0:
andrewm@0: // ***** Evaluator *****
andrewm@0:
andrewm@0: // This method actually handles the quantification of key activity. When it
andrewm@0: // exceeds a preset threshold, it sends a trigger
andrewm@0:
andrewm@0: void triggerReceived(TriggerSource* who, timestamp_type timestamp);
andrewm@0:
andrewm@0: // ***** Member Variables *****
andrewm@0:
andrewm@0: Node& keyBuffer_; // Raw key position data
andrewm@0: Accumulator accumulator_; // This class accumulates the last N key samples (to find an average)
andrewm@0:
andrewm@0: key_position keyIdleThreshold_; // Position below which we assume key is staying idle
andrewm@0:
andrewm@0: key_position activityThreshold_; // How much key motion should take place to make key active
andrewm@0: key_position positionThreshold_; // Position below which key can return to idle
andrewm@0: int numberOfFramesWithoutActivity_; // For how many samples have we been below the idle threshold?
andrewm@0: int noActivityCounterThreshold_;
andrewm@0: int idleState_; // Currently idle?
andrewm@0:
andrewm@0: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KeyIdleDetector)
andrewm@0: };
andrewm@0:
andrewm@0:
andrewm@0: #endif /* KEYCONTROL_KEYIDLEDETECTOR_H */