annotate Source/Mappings/MRPMapping.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 MRPMapping.h: mapping class for magnetic resonator piano using continuous
andrewm@0 21 key position.
andrewm@0 22 */
andrewm@0 23
andrewm@0 24 #ifndef __touchkeys__MRPMapping__
andrewm@0 25 #define __touchkeys__MRPMapping__
andrewm@0 26
andrewm@0 27 #include <map>
andrewm@0 28 #include <boost/bind.hpp>
andrewm@0 29 #include "../TouchKeys/KeyTouchFrame.h"
andrewm@0 30 #include "../TouchKeys/KeyPositionTracker.h"
andrewm@0 31 #include "../TouchKeys/PianoKeyboard.h"
andrewm@0 32 #include "Mapping.h"
andrewm@0 33 #include "../Utility/IIRFilter.h"
andrewm@0 34
andrewm@0 35 // How many velocity samples to save in the buffer. Make sure this is
andrewm@0 36 // enough to cover the frequency of updates.
andrewm@0 37 const int kMRPMappingVelocityBufferLength = 30;
andrewm@0 38
andrewm@0 39 // This class handles the mapping from key position and, optionally,
andrewm@0 40 // touch information to OSC messages which control the magnetic resonator
andrewm@0 41 // piano. One copy of the object is created for each active note, and
andrewm@0 42 // all objects use the PianoKeyboard Scheduler facility to request timed
andrewm@0 43 // updates.
andrewm@0 44
andrewm@0 45 class MRPMapping : public Mapping {
andrewm@0 46 private:
andrewm@0 47 /*// Useful constants for mapping MRP messages
andrewm@0 48 const int kMIDINoteOnMessage = 0x90;
andrewm@0 49 const int kDefaultMIDIChannel = 15;
andrewm@0 50 const float kDefaultAftertouchScaler = 100.0;
andrewm@0 51
andrewm@0 52 // Parameters for vibrato detection and mapping
andrewm@0 53 const key_velocity kVibratoVelocityThreshold = scale_key_velocity(2.0);
andrewm@0 54 const timestamp_diff_type kVibratoMinimumPeakSpacing = microseconds_to_timestamp(60000);
andrewm@0 55 const timestamp_diff_type kVibratoTimeout = microseconds_to_timestamp(500000);
andrewm@0 56 const int kVibratoMinimumOscillations = 4;
andrewm@0 57 const float kVibratoRateScaler = 0.005;*/
andrewm@0 58 // Useful constants for mapping MRP messages
andrewm@0 59 static const int kMIDINoteOnMessage;
andrewm@0 60 static const int kDefaultMIDIChannel;
andrewm@0 61 static const float kDefaultAftertouchScaler;
andrewm@0 62
andrewm@0 63 // Parameters for vibrato detection and mapping
andrewm@0 64 static const key_velocity kVibratoVelocityThreshold;
andrewm@0 65 static const timestamp_diff_type kVibratoMinimumPeakSpacing;
andrewm@0 66 static const timestamp_diff_type kVibratoTimeout;
andrewm@0 67 static const int kVibratoMinimumOscillations;
andrewm@0 68 static const float kVibratoRateScaler;
andrewm@0 69
andrewm@0 70 struct PitchBend {
andrewm@0 71 int note; // Note number of the bending key
andrewm@0 72 bool isControllingBend; // True if the note in this structure
andrewm@0 73 // is the one controlling bend (false if it's us)
andrewm@0 74 bool isFinished; // True if the bend should finish after this cycle
andrewm@0 75 Node<key_position>* positionBuffer; // Key position for bending key
andrewm@0 76 KeyPositionTracker* positionTracker; // Key states for bending key
andrewm@0 77 };
andrewm@0 78
andrewm@0 79 public:
andrewm@0 80 // ***** Constructors *****
andrewm@0 81
andrewm@0 82 // Default constructor, passing the buffer on which to trigger
andrewm@0 83 MRPMapping(PianoKeyboard &keyboard, MappingFactory *factory, int noteNumber, Node<KeyTouchFrame>* touchBuffer,
andrewm@0 84 Node<key_position>* positionBuffer, KeyPositionTracker* positionTracker);
andrewm@0 85
andrewm@0 86 // Copy constructor
andrewm@0 87 //MRPMapping(MRPMapping const& obj);
andrewm@0 88
andrewm@0 89 // ***** Destructor *****
andrewm@0 90
andrewm@0 91 ~MRPMapping();
andrewm@0 92
andrewm@0 93 // ***** Modifiers *****
andrewm@0 94
andrewm@0 95 // Disable mappings from being sent
andrewm@0 96 void disengage();
andrewm@0 97
andrewm@0 98 // Reset the state back initial values
andrewm@0 99 void reset();
andrewm@0 100
andrewm@0 101 // Set the aftertouch sensitivity on continuous key position
andrewm@0 102 // 0 means no aftertouch, 1 means default sensitivity, upward
andrewm@0 103 // from there
andrewm@0 104 void setAftertouchSensitivity(float sensitivity);
andrewm@0 105
andrewm@0 106 // Engage a pitch bend from a different key, based on its position and state
andrewm@0 107 void enablePitchBend(int toNote, Node<key_position>* toPositionBuffer,
andrewm@0 108 KeyPositionTracker *toPositionTracker);
andrewm@0 109
andrewm@0 110 // ***** Evaluators *****
andrewm@0 111
andrewm@0 112 // This method receives triggers whenever events occur in the touch data or the
andrewm@0 113 // continuous key position (state changes only). It alters the behavior and scheduling
andrewm@0 114 // of the mapping but does not itself send OSC messages
andrewm@0 115 void triggerReceived(TriggerSource* who, timestamp_type timestamp);
andrewm@0 116
andrewm@0 117 // This method handles the OSC message transmission. It should be run in the Scheduler
andrewm@0 118 // thread provided by PianoKeyboard.
andrewm@0 119 timestamp_type performMapping();
andrewm@0 120
andrewm@0 121 private:
andrewm@0 122 // ***** Private Methods *****
andrewm@0 123
andrewm@0 124 // Bring velocity calculations up to date
andrewm@0 125 key_velocity updateVelocityMeasurements();
andrewm@0 126
andrewm@0 127 // Find the timestamp of the first transition into a PartialPress state
andrewm@0 128 timestamp_type findTimestampOfPartialPress();
andrewm@0 129
andrewm@0 130 // ***** Member Variables *****
andrewm@0 131
andrewm@0 132 bool noteIsOn_; // Whether the MIDI note is active or not
andrewm@0 133 float aftertouchScaler_; // Scaler which affects aftertouch sensitivity
andrewm@0 134 float lastIntensity_, lastBrightness_; // Cached values for mapping qualities
andrewm@0 135 float lastPitch_, lastHarmonic_;
andrewm@0 136
andrewm@0 137 bool shouldLookForPitchBends_; // Whether to search for adjacent keys to start a pitch bend
andrewm@0 138 std::vector<PitchBend> activePitchBends_; // Which keys are involved in a pitch bend
andrewm@0 139
andrewm@0 140 Node<key_velocity> rawVelocity_; // History of key velocity measurements
andrewm@0 141 IIRFilterNode<key_velocity> filteredVelocity_; // Filtered key velocity information
andrewm@0 142 Node<key_position>::size_type lastCalculatedVelocityIndex_; // Keep track of how many velocity samples we've calculated
andrewm@0 143
andrewm@0 144 bool vibratoActive_; // Whether a vibrato gesture is currently detected
andrewm@0 145 int vibratoVelocityPeakCount_; // Counter for tracking velocity oscillations
andrewm@0 146 timestamp_type vibratoLastPeakTimestamp_; // When the last velocity peak took place
andrewm@0 147
andrewm@0 148 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MRPMapping)
andrewm@0 149 };
andrewm@0 150
andrewm@0 151 #endif /* defined(__touchkeys__MRPMapping__) */