annotate Source/Mappings/Control/TouchkeyControlMapping.h @ 56:b4a2d2ae43cf tip

merge
author Andrew McPherson <andrewm@eecs.qmul.ac.uk>
date Fri, 23 Nov 2018 15:48:14 +0000
parents 3580ffe87dc8
children
rev   line source
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 TouchkeyControlMapping.h: per-note mapping for the TouchKeys control
andrewm@0 21 mapping, which converts an arbitrary touch parameter into a MIDI or
andrewm@0 22 OSC control message.
andrewm@0 23 */
andrewm@0 24
andrewm@0 25 #ifndef __touchkeys__TouchkeyControlMapping__
andrewm@0 26 #define __touchkeys__TouchkeyControlMapping__
andrewm@0 27
andrewm@0 28 #include <iostream>
andrewm@0 29 #include <map>
andrewm@0 30 #include <boost/bind.hpp>
andrewm@0 31 #include "../TouchkeyBaseMapping.h"
andrewm@0 32 #include "../../Utility/IIRFilter.h"
andrewm@0 33
andrewm@0 34 // This class handles the implementation of a basic MIDI/OSC control message
andrewm@0 35 // based on touch data. It can use absolute or relative position in the X
andrewm@0 36 // or Y axis.
andrewm@0 37
andrewm@0 38 class TouchkeyControlMapping : public TouchkeyBaseMapping /*public Mapping, public OscHandler*/ {
andrewm@0 39 friend class TouchkeyControlMappingFactory;
andrewm@0 40
andrewm@0 41 public:
andrewm@0 42 enum {
andrewm@0 43 kInputParameterXPosition = 1,
andrewm@0 44 kInputParameterYPosition,
andrewm@0 45 kInputParameterTouchSize,
andrewm@0 46 kInputParameter2FingerMean,
andrewm@0 47 kInputParameter2FingerDistance,
andrewm@0 48 kInputParameterMaxValue
andrewm@0 49 };
andrewm@0 50
andrewm@0 51 enum {
andrewm@0 52 kTypeAbsolute = 1,
andrewm@0 53 kTypeFirstTouchRelative,
andrewm@0 54 kTypeNoteOnsetRelative,
andrewm@0 55 kTypeMaxValue
andrewm@0 56 };
andrewm@0 57
andrewm@0 58 enum {
andrewm@0 59 kDirectionPositive = 1,
andrewm@0 60 kDirectionNegative,
andrewm@0 61 kDirectionBoth,
andrewm@0 62 kDirectionMaxValue
andrewm@0 63 };
andrewm@0 64
andrewm@0 65 private:
andrewm@0 66 // Useful constants for mapping MRP messages
andrewm@0 67 static const int kDefaultMIDIChannel;
andrewm@0 68 static const int kDefaultFilterBufferLength;
andrewm@0 69
andrewm@0 70 static const bool kDefaultIgnoresTwoFingers;
andrewm@0 71 static const bool kDefaultIgnoresThreeFingers;
andrewm@0 72 static const int kDefaultDirection;
andrewm@0 73
andrewm@0 74 public:
andrewm@0 75 // ***** Constructors *****
andrewm@0 76
andrewm@0 77 // Default constructor, passing the buffer on which to trigger
andrewm@0 78 TouchkeyControlMapping(PianoKeyboard &keyboard, MappingFactory *factory, int noteNumber, Node<KeyTouchFrame>* touchBuffer,
andrewm@0 79 Node<key_position>* positionBuffer, KeyPositionTracker* positionTracker);
andrewm@0 80
andrewm@0 81 // ***** Destructor *****
andrewm@0 82
andrewm@0 83 ~TouchkeyControlMapping();
andrewm@0 84
andrewm@0 85 // ***** Modifiers *****
andrewm@0 86
andrewm@0 87 // Enable mappings to be sent
andrewm@0 88 //void engage();
andrewm@0 89
andrewm@0 90 // Disable mappings from being sent
andrewm@0 91 //void disengage(bool shouldDelete = false);
andrewm@0 92
andrewm@0 93 // Reset the state back initial values
andrewm@0 94 void reset();
andrewm@0 95
andrewm@0 96 // Resend the current state of all parameters
andrewm@0 97 void resend();
andrewm@0 98
andrewm@0 99 // Name for this control, used in the OSC path
andrewm@0 100 //void setName(const std::string& name);
andrewm@0 101
andrewm@0 102 // Parameters for the controller handling
andrewm@0 103 // Input parameter to use for this control mapping and whether it is absolute or relative
andrewm@0 104 void setInputParameter(int parameter, int type);
andrewm@0 105
andrewm@0 106 // Input/output range for this parameter
andrewm@0 107 void setRange(float inputMin, float inputMax, float outputMin, float outputMax, float outputDefault);
andrewm@0 108
andrewm@0 109 // Threshold which must be exceeded for the control to engage (for relative position), or 0 if not used
andrewm@0 110 void setThreshold(float threshold);
andrewm@0 111
andrewm@0 112 // Set whether the mapping should ignore multiple touches
andrewm@0 113 void setIgnoresMultipleFingers(bool ignoresTwo, bool ignoresThree);
andrewm@0 114
andrewm@0 115 // Set whether the mapping should use the absolute value of a relative position
andrewm@0 116 void setDirection(int direction);
andrewm@0 117
andrewm@0 118 // ***** Evaluators *****
andrewm@0 119
andrewm@0 120 // OSC Handler Method: called by PianoKeyboard (or other OSC source)
andrewm@0 121 //bool oscHandlerMethod(const char *path, const char *types, int numValues, lo_arg **values, void *data);
andrewm@0 122
andrewm@0 123 // This method receives triggers whenever events occur in the touch data or the
andrewm@0 124 // continuous key position (state changes only). It alters the behavior and scheduling
andrewm@0 125 // of the mapping but does not itself send OSC messages
andrewm@0 126 void triggerReceived(TriggerSource* who, timestamp_type timestamp);
andrewm@0 127
andrewm@0 128 // This method handles the OSC message transmission. It should be run in the Scheduler
andrewm@0 129 // thread provided by PianoKeyboard.
andrewm@0 130 timestamp_type performMapping();
andrewm@0 131
andrewm@0 132 private:
andrewm@0 133 // ***** Private Methods *****
andrewm@0 134 void midiNoteOnReceived(int channel, int velocity);
andrewm@0 135 void midiNoteOffReceived(int channel);
andrewm@0 136
andrewm@0 137 void resetDetectionState();
andrewm@0 138 void clearBuffers();
andrewm@0 139
andrewm@0 140 float getValue(const KeyTouchFrame& frame);
andrewm@0 141 int locateTouchId(KeyTouchFrame const& frame, int index);
andrewm@0 142 int lowestUnassignedTouch(KeyTouchFrame const& frame, int *indexWithinFrame);
andrewm@0 143 void sendControlMessage(float value, bool force = false);
andrewm@0 144
andrewm@0 145 // ***** Member Variables *****
andrewm@0 146
andrewm@0 147 bool controlIsEngaged_; // Whether the control has
andrewm@0 148
andrewm@0 149 float inputMin_, inputMax_; // Input ranges
andrewm@0 150 float outputMin_, outputMax_; // Output ranges
andrewm@0 151 float outputDefault_; // Default value to send in absence of any input
andrewm@0 152 int inputParameter_; // Parameter to be used for mapping
andrewm@0 153 int inputType_; // Type of mapping (absolute, relative, etc.)
andrewm@0 154 float threshold_; // Threshold that must be exceeded before mapping engages
andrewm@0 155 bool ignoresTwoFingers_; // Whether this mapping supresses all messages when two
andrewm@0 156 bool ignoresThreeFingers_; // or three fingers are present
andrewm@0 157 int direction_; // Whether the mapping goes up, down or both directions (for relative motion)
andrewm@0 158
andrewm@0 159 float touchOnsetValue_, midiOnsetValue_; // Where the touch began initially and at MIDI note on
andrewm@0 160 float lastValue_; // Where the touch was at the last frame we received
andrewm@0 161 int idsOfCurrentTouches_[3]; // Which touch ID(s) we're currently following
andrewm@0 162 timestamp_type lastTimestamp_; // When the last data point arrived
andrewm@0 163 Node<float>::size_type lastProcessedIndex_; // Index of the last filtered position sample we've handled
andrewm@0 164
andrewm@0 165 float controlEngageLocation_; // Where the controller was engaged (i.e. where the threshold was crossed, if relative)
andrewm@0 166 float controlScalerPositive_, controlScalerNegative_; // Translation between position and control values for upward and downward motions
andrewm@0 167
andrewm@0 168 float lastControlValue_; // The last value we sent out
andrewm@0 169
andrewm@0 170 Node<float> rawValues_; // Most recent values
andrewm@0 171 //CriticalSection rawValueAccessMutex_; // Mutex protecting access to raw values buffer
andrewm@0 172 };
andrewm@0 173
andrewm@0 174
andrewm@0 175
andrewm@0 176 #endif /* defined(__touchkeys__TouchkeyControlMapping__) */