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: Mapping.h: base class for a single-note mapping. The mapping will take in andrewm@0: MIDI, touch and (optionally) continuous key position data, and generate andrewm@0: specific OSC or MIDI messages. TouchKeys-specific mappings generally andrewm@0: inherit from the TouchkeyBaseMapping subclass, which provides other andrewm@0: useful generic methods. andrewm@0: */ andrewm@0: andrewm@0: #ifndef touchkeys_Mapping_h andrewm@0: #define touchkeys_Mapping_h andrewm@0: andrewm@0: andrewm@0: #include andrewm@0: #include andrewm@0: #include "../TouchKeys/KeyTouchFrame.h" andrewm@0: #include "../TouchKeys/KeyPositionTracker.h" andrewm@0: #include "../TouchKeys/PianoKeyboard.h" andrewm@0: andrewm@0: #define NEW_MAPPING_SCHEDULER andrewm@0: andrewm@0: class MappingFactory; andrewm@0: andrewm@0: // This virtual base class defines a mapping from keyboard data to OSC or andrewm@0: // other output information. Specific behavior is implemented by subclasses. andrewm@0: andrewm@0: class Mapping : public TriggerDestination { andrewm@0: protected: andrewm@0: // Default frequency of mapping data, in the absence of other triggers andrewm@0: //const timestamp_diff_type kDefaultUpdateInterval = microseconds_to_timestamp(5500); andrewm@0: static const timestamp_diff_type kDefaultUpdateInterval; andrewm@0: andrewm@0: public: andrewm@0: // ***** Constructors ***** andrewm@0: andrewm@0: // Default constructor, passing the buffer on which to trigger andrewm@0: Mapping(PianoKeyboard &keyboard, MappingFactory *factory, int noteNumber, Node* touchBuffer, andrewm@0: Node* positionBuffer, KeyPositionTracker* positionTracker); andrewm@0: andrewm@0: // Copy constructor andrewm@0: Mapping(Mapping const& obj); andrewm@0: andrewm@0: // ***** Destructor ***** andrewm@0: andrewm@0: virtual ~Mapping(); andrewm@0: andrewm@0: // ***** Modifiers ***** andrewm@0: andrewm@0: // Enable mappings to be sent andrewm@0: virtual void engage(); andrewm@0: andrewm@0: // Disable mappings from being sent andrewm@0: virtual void disengage(bool shouldDelete = false); andrewm@0: andrewm@0: // Reset the state back initial values andrewm@0: virtual void reset(); andrewm@0: andrewm@0: // Set the interval between mapping actions andrewm@0: virtual void setUpdateInterval(timestamp_diff_type interval) { andrewm@0: if(interval <= 0) andrewm@0: return; andrewm@0: updateInterval_ = interval; andrewm@0: } andrewm@0: andrewm@0: // Suspend any further messages from this mapping andrewm@0: virtual void suspend() { suspended_ = true; } andrewm@0: andrewm@0: // Resume sending messages, optionally re-sending the current state andrewm@0: virtual void resume(bool resendCurrentState) { andrewm@0: if(resendCurrentState) andrewm@0: resend(); andrewm@0: suspended_ = false; andrewm@0: } andrewm@0: andrewm@0: // Resend the current state of all the managed parameters andrewm@0: virtual void resend() {} andrewm@0: andrewm@0: // ***** Evaluators ***** andrewm@0: // These are the main mapping functions, and they need to be implemented andrewm@0: // specifically in any subclass. andrewm@0: andrewm@0: // This method receives triggers whenever events occur in the touch data or the andrewm@0: // continuous key position (state changes only). andrewm@0: virtual void triggerReceived(TriggerSource* who, timestamp_type timestamp) = 0; andrewm@0: andrewm@0: // This method is run periodically the Scheduler provided by PianoKeyboard and andrewm@0: // handles the actual work of performing the mapping. andrewm@0: virtual timestamp_type performMapping() = 0; andrewm@0: andrewm@0: // Indicate whether the mapping has finished all of its processing and can be deleted. andrewm@0: // By default a mapping can be deleted whenever the factory wants to, but some andrewm@0: // may persist beyond note release for a limited period of time. andrewm@0: virtual bool requestFinish() { return true; } andrewm@0: andrewm@0: protected: andrewm@0: andrewm@0: // ***** Member Variables ***** andrewm@0: andrewm@0: PianoKeyboard& keyboard_; // Reference to the main keyboard controller andrewm@0: MappingFactory *factory_; // Factory that created this mapping andrewm@0: int noteNumber_; // MIDI note number for this key andrewm@0: Node* touchBuffer_; // Key touch location history andrewm@0: Node* positionBuffer_; // Raw key position data andrewm@0: KeyPositionTracker* positionTracker_; // Object which manages states of key andrewm@0: andrewm@0: bool engaged_; // Whether we're actively mapping andrewm@0: bool suspended_; // Whether we're suppressing messages andrewm@0: timestamp_diff_type updateInterval_; // How long between mapping calls andrewm@0: timestamp_type nextScheduledTimestamp_; // When we've asked for the next callback andrewm@0: Scheduler::action mappingAction_; // Action function which calls performMapping() andrewm@0: }; andrewm@0: andrewm@0: andrewm@0: #endif